summaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/bearer/symbian/qnetworksession_impl.cpp261
-rw-r--r--src/plugins/bearer/symbian/qnetworksession_impl.h38
-rw-r--r--src/plugins/platforms/directfb/qdirectfbglcontext.cpp2
-rw-r--r--src/plugins/platforms/eglconvenience/eglconvenience.pri7
-rw-r--r--src/plugins/platforms/eglconvenience/qeglconvenience.cpp4
-rw-r--r--src/plugins/platforms/eglconvenience/qeglconvenience.h6
-rw-r--r--src/plugins/platforms/eglconvenience/qeglplatformcontext.cpp5
-rw-r--r--src/plugins/platforms/eglconvenience/qeglplatformcontext.h2
-rw-r--r--src/plugins/platforms/eglconvenience/qxlibeglintegration.cpp4
-rw-r--r--src/plugins/platforms/eglconvenience/qxlibeglintegration.h2
-rw-r--r--src/plugins/platforms/eglconvenience/xlibeglintegration.pri7
-rw-r--r--src/plugins/platforms/eglfs/qeglfsintegration.cpp4
-rw-r--r--src/plugins/platforms/eglfs/qeglfsscreen.cpp1
-rw-r--r--src/plugins/platforms/eglfs/qeglfsscreen.h1
-rw-r--r--src/plugins/platforms/eglfs/qeglfswindow.h3
-rw-r--r--src/plugins/platforms/fontdatabases/genericunix/genericunix.pri4
-rw-r--r--src/plugins/platforms/glxconvenience/glxconvenience.pri7
-rw-r--r--src/plugins/platforms/glxconvenience/qglxconvenience.cpp243
-rw-r--r--src/plugins/platforms/glxconvenience/qglxconvenience.h56
-rw-r--r--src/plugins/platforms/openkode/qopenkodeintegration.cpp10
-rw-r--r--src/plugins/platforms/openkode/qopenkodeintegration.h6
-rw-r--r--src/plugins/platforms/openkode/qopenkodewindow.cpp10
-rw-r--r--src/plugins/platforms/uikit/README4
-rw-r--r--src/plugins/platforms/uikit/examples/qmltest/main.mm32
-rwxr-xr-xsrc/plugins/platforms/uikit/examples/qmltest/qmltest.xcodeproj/project.pbxproj28
-rw-r--r--src/plugins/platforms/uikit/quikiteventloop.h4
-rw-r--r--src/plugins/platforms/uikit/quikiteventloop.mm27
-rw-r--r--src/plugins/platforms/uikit/quikitscreen.mm21
-rw-r--r--src/plugins/platforms/uikit/quikitsoftwareinputhandler.h61
-rw-r--r--src/plugins/platforms/uikit/quikitwindow.h54
-rw-r--r--src/plugins/platforms/uikit/quikitwindow.mm290
-rw-r--r--src/plugins/platforms/uikit/quikitwindowsurface.h23
-rw-r--r--src/plugins/platforms/uikit/quikitwindowsurface.mm196
-rw-r--r--src/plugins/platforms/uikit/uikit.pro4
-rw-r--r--src/plugins/platforms/wayland/gl_integration/gl_integration.pri57
-rw-r--r--src/plugins/platforms/wayland/gl_integration/qwaylandglintegration.cpp52
-rw-r--r--src/plugins/platforms/wayland/gl_integration/qwaylandglintegration.h62
-rw-r--r--src/plugins/platforms/wayland/gl_integration/qwaylandglwindowsurface.cpp (renamed from src/plugins/platforms/wayland/qwaylanddrmsurface.cpp)21
-rw-r--r--src/plugins/platforms/wayland/gl_integration/qwaylandglwindowsurface.h (renamed from src/plugins/platforms/wayland/qwaylanddrmsurface.h)9
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglcontext.cpp174
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglcontext.h80
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.cpp112
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.h82
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglwindow.cpp76
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglwindow.h66
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_egl/readback_egl.pri14
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.cpp163
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.h79
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.cpp97
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.h80
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.cpp73
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.h65
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_glx/readback_glx.pri12
-rw-r--r--src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglinclude.h (renamed from src/plugins/platforms/wayland/qwaylandinclude.h)18
-rw-r--r--src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.cpp95
-rw-r--r--src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.h73
-rw-r--r--src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.cpp (renamed from src/plugins/platforms/wayland/qwaylandeglwindow.cpp)15
-rw-r--r--src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.h (renamed from src/plugins/platforms/wayland/qwaylandeglwindow.h)5
-rw-r--r--src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandglcontext.cpp (renamed from src/plugins/platforms/wayland/qwaylandglcontext.cpp)55
-rw-r--r--src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandglcontext.h (renamed from src/plugins/platforms/wayland/qwaylandglcontext.h)11
-rw-r--r--src/plugins/platforms/wayland/gl_integration/wayland_egl/wayland_egl.pri12
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.cpp169
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.h82
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.cpp139
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.h98
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.cpp77
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.h65
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_egl/xcomposite_egl.pri15
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.cpp150
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.h85
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.cpp126
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.h93
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.cpp77
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.h65
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_glx/xcomposite_glx.pri13
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_share/qwaylandxcompositebuffer.cpp59
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_share/qwaylandxcompositebuffer.h62
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_share/wayland-xcomposite-client-protocol.h145
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_share/wayland-xcomposite-protocol.c59
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_share/xcomposite_share.pri9
-rw-r--r--src/plugins/platforms/wayland/qwaylandbuffer.h2
-rw-r--r--src/plugins/platforms/wayland/qwaylanddisplay.cpp241
-rw-r--r--src/plugins/platforms/wayland/qwaylanddisplay.h55
-rw-r--r--src/plugins/platforms/wayland/qwaylandinputdevice.cpp8
-rw-r--r--src/plugins/platforms/wayland/qwaylandinputdevice.h1
-rw-r--r--src/plugins/platforms/wayland/qwaylandintegration.cpp24
-rw-r--r--src/plugins/platforms/wayland/qwaylandintegration.h2
-rw-r--r--src/plugins/platforms/wayland/qwaylandscreen.cpp1
-rw-r--r--src/plugins/platforms/wayland/qwaylandshmsurface.cpp21
-rw-r--r--src/plugins/platforms/wayland/qwaylandshmsurface.h3
-rw-r--r--src/plugins/platforms/wayland/qwaylandshmwindow.cpp26
-rw-r--r--src/plugins/platforms/wayland/qwaylandshmwindow.h7
-rw-r--r--src/plugins/platforms/wayland/qwaylandwindow.cpp64
-rw-r--r--src/plugins/platforms/wayland/qwaylandwindow.h14
-rw-r--r--src/plugins/platforms/wayland/wayland.pro23
-rw-r--r--src/plugins/platforms/xcb/README3
-rw-r--r--src/plugins/platforms/xcb/qdri2context.cpp2
-rw-r--r--src/plugins/platforms/xcb/qglxintegration.cpp238
-rw-r--r--src/plugins/platforms/xcb/qglxintegration.h9
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.cpp251
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.h39
-rw-r--r--src/plugins/platforms/xcb/qxcbintegration.cpp9
-rw-r--r--src/plugins/platforms/xcb/qxcbintegration.h3
-rw-r--r--src/plugins/platforms/xcb/qxcbkeyboard.cpp6
-rw-r--r--src/plugins/platforms/xcb/qxcbscreen.cpp39
-rw-r--r--src/plugins/platforms/xcb/qxcbscreen.h6
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp257
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.h10
-rw-r--r--src/plugins/platforms/xcb/qxcbwindowsurface.cpp64
-rw-r--r--src/plugins/platforms/xcb/qxcbwindowsurface.h2
-rw-r--r--src/plugins/platforms/xcb/xcb.pro3
-rw-r--r--src/plugins/platforms/xlib/qglxintegration.cpp225
-rw-r--r--src/plugins/platforms/xlib/qglxintegration.h9
-rw-r--r--src/plugins/platforms/xlib/qxlibintegration.cpp20
-rw-r--r--src/plugins/platforms/xlib/qxlibintegration.h7
-rw-r--r--src/plugins/platforms/xlib/qxlibnativeinterface.cpp133
-rw-r--r--src/plugins/platforms/xlib/qxlibnativeinterface.h75
-rw-r--r--src/plugins/platforms/xlib/qxlibscreen.cpp5
-rw-r--r--src/plugins/platforms/xlib/qxlibscreen.h8
-rw-r--r--src/plugins/platforms/xlib/qxlibwindow.cpp15
-rw-r--r--src/plugins/platforms/xlib/xlib.pro7
-rw-r--r--src/plugins/qpluginbase.pri19
122 files changed, 5322 insertions, 1307 deletions
diff --git a/src/plugins/bearer/symbian/qnetworksession_impl.cpp b/src/plugins/bearer/symbian/qnetworksession_impl.cpp
index 741f8c5..a9bd414 100644
--- a/src/plugins/bearer/symbian/qnetworksession_impl.cpp
+++ b/src/plugins/bearer/symbian/qnetworksession_impl.cpp
@@ -45,8 +45,7 @@
#include <es_enum.h>
#include <es_sock.h>
#include <in_sock.h>
-#include <stdapis/sys/socket.h>
-#include <stdapis/net/if.h>
+#include <private/qcore_symbian_p.h>
#ifdef SNAP_FUNCTIONALITY_AVAILABLE
#include <cmmanager.h>
@@ -61,65 +60,60 @@
QT_BEGIN_NAMESPACE
QNetworkSessionPrivateImpl::QNetworkSessionPrivateImpl(SymbianEngine *engine)
-: CActive(CActive::EPriorityUserInput), engine(engine),
- iDynamicUnSetdefaultif(0), ipConnectionNotifier(0),
+: engine(engine), iSocketServ(qt_symbianGetSocketServer()),
+ ipConnectionNotifier(0), ipConnectionStarter(0),
iHandleStateNotificationsFromManager(false), iFirstSync(true), iStoppedByUser(false),
iClosedByUser(false), iError(QNetworkSession::UnknownSessionError), iALREnabled(0),
iConnectInBackground(false), isOpening(false)
{
- CActiveScheduler::Add(this);
#ifdef SNAP_FUNCTIONALITY_AVAILABLE
iMobility = NULL;
#endif
- // Try to load "Open C" dll dynamically and
- // try to attach to unsetdefaultif function dynamically.
- // This is to avoid build breaks with old OpenC versions.
- if (iOpenCLibrary.Load(_L("libc")) == KErrNone) {
- iDynamicUnSetdefaultif = (TOpenCUnSetdefaultifFunction)iOpenCLibrary.Lookup(597);
- }
-#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
- qDebug() << "QNS this : " << QString::number((uint)this) << " - ";
- if (iDynamicUnSetdefaultif)
- qDebug() << "dynamic unsetdefaultif() is present in PIPS library. ";
- else
- qDebug() << "dynamic unsetdefaultif() not present in PIPS library. ";
-#endif
TRAP_IGNORE(iConnectionMonitor.ConnectL());
}
-QNetworkSessionPrivateImpl::~QNetworkSessionPrivateImpl()
+void QNetworkSessionPrivateImpl::closeHandles()
{
- isOpen = false;
- isOpening = false;
-
+ QMutexLocker lock(&mutex);
// Cancel Connection Progress Notifications first.
- // Note: ConnectionNotifier must be destroyed before Canceling RConnection::Start()
+ // Note: ConnectionNotifier must be destroyed before RConnection::Close()
// => deleting ipConnectionNotifier results RConnection::CancelProgressNotification()
delete ipConnectionNotifier;
ipConnectionNotifier = NULL;
#ifdef SNAP_FUNCTIONALITY_AVAILABLE
- if (iMobility) {
- delete iMobility;
- iMobility = NULL;
- }
+ // mobility monitor must be deleted before RConnection is closed
+ delete iMobility;
+ iMobility = NULL;
#endif
- // Cancel possible RConnection::Start()
- Cancel();
- iSocketServ.Close();
+ // Cancel possible RConnection::Start() - may call RConnection::Close if Start was in progress
+ delete ipConnectionStarter;
+ ipConnectionStarter = 0;
+ //close any open connection (note Close twice is safe in case Cancel did it above)
+ iConnection.Close();
- // Close global 'Open C' RConnection
- // Clears also possible unsetdefaultif() flags.
- setdefaultif(0);
+ QSymbianSocketManager::instance().setDefaultConnection(0);
iConnectionMonitor.Close();
- iOpenCLibrary.Close();
#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
qDebug() << "QNS this : " << QString::number((uint)this)
- << " - destroyed (and setdefaultif(0))";
+ << " - handles closed";
+#endif
+
+}
+
+QNetworkSessionPrivateImpl::~QNetworkSessionPrivateImpl()
+{
+ isOpen = false;
+ isOpening = false;
+
+ closeHandles();
+#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
+ qDebug() << "QNS this : " << QString::number((uint)this)
+ << " - destroyed";
#endif
}
@@ -166,7 +160,7 @@ void QNetworkSessionPrivateImpl::configurationAdded(QNetworkConfigurationPrivate
#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
qDebug() << "QNS this : " << QString::number((uint)this) << " - "
<< "configurationAdded IAP: "
- << toSymbianConfig(privateConfiguration(config))->numericIdentifier();
+ << toSymbianConfig(config)->numericIdentifier();
#endif
syncStateWithInterface();
@@ -324,6 +318,7 @@ QNetworkSession::SessionError QNetworkSessionPrivateImpl::error() const
void QNetworkSessionPrivateImpl::open()
{
+ QMutexLocker lock(&mutex);
#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
qDebug() << "QNS this : " << QString::number((uint)this) << " - "
<< "open() called, session state is: " << state << " and isOpen is: "
@@ -363,20 +358,10 @@ void QNetworkSessionPrivateImpl::open()
iStoppedByUser = false;
iClosedByUser = false;
- TInt error = iSocketServ.Connect();
- if (error != KErrNone) {
- // Could not open RSocketServ
- newState(QNetworkSession::Invalid);
- iError = QNetworkSession::UnknownSessionError;
- emit QNetworkSessionPrivate::error(iError);
- syncStateWithInterface();
- return;
- }
-
- error = iConnection.Open(iSocketServ);
+ Q_ASSERT(!iConnection.SubSessionHandle());
+ TInt error = iConnection.Open(iSocketServ);
if (error != KErrNone) {
// Could not open RConnection
- iSocketServ.Close();
newState(QNetworkSession::Invalid);
iError = QNetworkSession::UnknownSessionError;
emit QNetworkSessionPrivate::error(iError);
@@ -414,9 +399,9 @@ void QNetworkSessionPrivateImpl::open()
pref.SetIapId(symbianConfig->numericIdentifier());
#endif
- iConnection.Start(pref, iStatus);
- if (!IsActive()) {
- SetActive();
+ if (!ipConnectionStarter) {
+ ipConnectionStarter = new ConnectionStarter(*this, iConnection);
+ ipConnectionStarter->Start(pref);
}
// Avoid flip flop of states if the configuration is already
// active. IsOpen/opened() will indicate when ready.
@@ -442,9 +427,9 @@ void QNetworkSessionPrivateImpl::open()
#else
TConnSnapPref snapPref(symbianConfig->numericIdentifier());
#endif
- iConnection.Start(snapPref, iStatus);
- if (!IsActive()) {
- SetActive();
+ if (!ipConnectionStarter) {
+ ipConnectionStarter = new ConnectionStarter(*this, iConnection);
+ ipConnectionStarter->Start(snapPref);
}
// Avoid flip flop of states if the configuration is already
// active. IsOpen/opened() will indicate when ready.
@@ -453,9 +438,9 @@ void QNetworkSessionPrivateImpl::open()
}
} else if (publicConfig.type() == QNetworkConfiguration::UserChoice) {
iKnownConfigsBeforeConnectionStart = engine->accessPointConfigurationIdentifiers();
- iConnection.Start(iStatus);
- if (!IsActive()) {
- SetActive();
+ if (!ipConnectionStarter) {
+ ipConnectionStarter = new ConnectionStarter(*this, iConnection);
+ ipConnectionStarter->Start();
}
newState(QNetworkSession::Connecting);
}
@@ -465,9 +450,7 @@ void QNetworkSessionPrivateImpl::open()
isOpening = false;
iError = QNetworkSession::UnknownSessionError;
emit QNetworkSessionPrivate::error(iError);
- if (ipConnectionNotifier) {
- ipConnectionNotifier->StopNotifications();
- }
+ closeHandles();
syncStateWithInterface();
}
}
@@ -519,31 +502,10 @@ void QNetworkSessionPrivateImpl::close(bool allowSignals)
serviceConfig = QNetworkConfiguration();
-#ifdef SNAP_FUNCTIONALITY_AVAILABLE
- if (iMobility) {
- delete iMobility;
- iMobility = NULL;
- }
-#endif
+ closeHandles();
- if (ipConnectionNotifier && !iHandleStateNotificationsFromManager) {
- ipConnectionNotifier->StopNotifications();
- // Start handling IAP state change signals from QNetworkConfigurationManagerPrivate
- iHandleStateNotificationsFromManager = true;
- }
-
- Cancel(); // closes iConnection
- iSocketServ.Close();
-
- // Close global 'Open C' RConnection. If OpenC supports,
- // close the defaultif for good to avoid difficult timing
- // and bouncing issues of network going immediately back up
- // because of e.g. select() thread etc.
- if (iDynamicUnSetdefaultif) {
- iDynamicUnSetdefaultif();
- } else {
- setdefaultif(0);
- }
+ // Start handling IAP state change signals from QNetworkConfigurationManagerPrivate
+ iHandleStateNotificationsFromManager = true;
// If UserChoice, go down immediately. If some other configuration,
// go down immediately if there is no reports expected from the platform;
@@ -566,6 +528,7 @@ void QNetworkSessionPrivateImpl::close(bool allowSignals)
void QNetworkSessionPrivateImpl::stop()
{
+ QMutexLocker lock(&mutex);
#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
qDebug() << "QNS this : " << QString::number((uint)this) << " - "
<< "stop() called, session state is: " << state << " and isOpen is : "
@@ -639,13 +602,7 @@ void QNetworkSessionPrivateImpl::migrate()
{
#ifdef SNAP_FUNCTIONALITY_AVAILABLE
if (iMobility) {
- // Close global 'Open C' RConnection. If openC supports, use the 'heavy'
- // version to block all subsequent requests.
- if (iDynamicUnSetdefaultif) {
- iDynamicUnSetdefaultif();
- } else {
- setdefaultif(0);
- }
+ QSymbianSocketManager::instance().setDefaultConnection(0);
// Start migrating to new IAP
iMobility->MigrateToPreferredCarrier();
}
@@ -675,12 +632,7 @@ void QNetworkSessionPrivateImpl::accept()
QNetworkConfiguration newActiveConfig = activeConfiguration(iNewRoamingIap);
- // Use name of the new IAP to open global 'Open C' RConnection
- QByteArray nameAsByteArray = newActiveConfig.name().toUtf8();
- ifreq ifr;
- memset(&ifr, 0, sizeof(struct ifreq));
- strcpy(ifr.ifr_name, nameAsByteArray.constData());
- setdefaultif(&ifr);
+ QSymbianSocketManager::instance().setDefaultConnection(&iConnection);
newState(QNetworkSession::Connected, iNewRoamingIap);
}
@@ -698,12 +650,7 @@ void QNetworkSessionPrivateImpl::reject()
} else {
QNetworkConfiguration newActiveConfig = activeConfiguration(iOldRoamingIap);
- // Use name of the old IAP to open global 'Open C' RConnection
- QByteArray nameAsByteArray = newActiveConfig.name().toUtf8();
- ifreq ifr;
- memset(&ifr, 0, sizeof(struct ifreq));
- strcpy(ifr.ifr_name, nameAsByteArray.constData());
- setdefaultif(&ifr);
+ QSymbianSocketManager::instance().setDefaultConnection(&iConnection);
newState(QNetworkSession::Connected, iOldRoamingIap);
}
@@ -756,12 +703,14 @@ void QNetworkSessionPrivateImpl::NewCarrierActive(TAccessPointInfo /*aNewAPInfo*
}
}
-void QNetworkSessionPrivateImpl::Error(TInt /*aError*/)
+void QNetworkSessionPrivateImpl::Error(TInt aError)
{
#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
qDebug() << "QNS this : " << QString::number((uint)this) << " - "
- << "roaming Error() occurred, isOpen is: " << isOpen;
+ << "roaming Error() occurred" << aError << ", isOpen is: " << isOpen;
#endif
+ if (aError == KErrCancel)
+ return; //avoid recursive deletion
if (isOpen) {
isOpen = false;
isOpening = false;
@@ -769,10 +718,7 @@ void QNetworkSessionPrivateImpl::Error(TInt /*aError*/)
serviceConfig = QNetworkConfiguration();
iError = QNetworkSession::RoamingError;
emit QNetworkSessionPrivate::error(iError);
- Cancel();
- if (ipConnectionNotifier) {
- ipConnectionNotifier->StopNotifications();
- }
+ closeHandles();
QT_TRY {
syncStateWithInterface();
// In some cases IAP is still in Connected state when
@@ -1064,13 +1010,14 @@ QNetworkConfiguration QNetworkSessionPrivateImpl::activeConfiguration(TUint32 ia
return publicConfig;
}
-void QNetworkSessionPrivateImpl::RunL()
+void QNetworkSessionPrivateImpl::ConnectionStartComplete(TInt statusCode)
{
#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
qDebug() << "QNS this : " << QString::number((uint)this) << " - "
- << "RConnection::RunL with status code: " << iStatus.Int();
+ << "RConnection::Start completed with status code: " << statusCode;
#endif
- TInt statusCode = iStatus.Int();
+ delete ipConnectionStarter;
+ ipConnectionStarter = 0;
switch (statusCode) {
case KErrNone: // Connection created successfully
@@ -1085,30 +1032,20 @@ void QNetworkSessionPrivateImpl::RunL()
// Connectivity Test, ICT, failed).
error = KErrGeneral;
} else {
- // Use name of the IAP to open global 'Open C' RConnection
- ifreq ifr;
- memset(&ifr, 0, sizeof(struct ifreq));
- QByteArray nameAsByteArray = newActiveConfig.name().toUtf8();
- strcpy(ifr.ifr_name, nameAsByteArray.constData());
- error = setdefaultif(&ifr);
+ QSymbianSocketManager::instance().setDefaultConnection(&iConnection);
}
if (error != KErrNone) {
isOpen = false;
isOpening = false;
iError = QNetworkSession::UnknownSessionError;
QT_TRYCATCH_LEAVING(emit QNetworkSessionPrivate::error(iError));
- if (ipConnectionNotifier) {
- ipConnectionNotifier->StopNotifications();
- }
+ closeHandles();
if (!newActiveConfig.isValid()) {
// No valid configuration, bail out.
// Status updates from QNCM won't be received correctly
// because there is no configuration to associate them with so transit here.
- iConnection.Close();
newState(QNetworkSession::Closing);
newState(QNetworkSession::Disconnected);
- } else {
- Cancel();
}
QT_TRYCATCH_LEAVING(syncStateWithInterface());
return;
@@ -1151,10 +1088,7 @@ void QNetworkSessionPrivateImpl::RunL()
serviceConfig = QNetworkConfiguration();
iError = QNetworkSession::InvalidConfigurationError;
QT_TRYCATCH_LEAVING(emit QNetworkSessionPrivate::error(iError));
- if (ipConnectionNotifier) {
- ipConnectionNotifier->StopNotifications();
- }
- Cancel();
+ closeHandles();
QT_TRYCATCH_LEAVING(syncStateWithInterface());
break;
case KErrCancel: // Connection attempt cancelled
@@ -1173,20 +1107,12 @@ void QNetworkSessionPrivateImpl::RunL()
iError = QNetworkSession::UnknownSessionError;
}
QT_TRYCATCH_LEAVING(emit QNetworkSessionPrivate::error(iError));
- if (ipConnectionNotifier) {
- ipConnectionNotifier->StopNotifications();
- }
- Cancel();
+ closeHandles();
QT_TRYCATCH_LEAVING(syncStateWithInterface());
break;
}
}
-void QNetworkSessionPrivateImpl::DoCancel()
-{
- iConnection.Close();
-}
-
// Enters newState if feasible according to current state.
// AccessPointId may be given as parameter. If it is zero, state-change is assumed to
// concern this session's configuration. If non-zero, the configuration is looked up
@@ -1211,12 +1137,7 @@ bool QNetworkSessionPrivateImpl::newState(QNetworkSession::State newState, TUint
#endif
#ifdef SNAP_FUNCTIONALITY_AVAILABLE
- // Use name of the IAP to set default IAP
- QByteArray nameAsByteArray = activeConfig.name().toUtf8();
- ifreq ifr;
- strcpy(ifr.ifr_name, nameAsByteArray.constData());
-
- setdefaultif(&ifr);
+ QSymbianSocketManager::instance().setDefaultConnection(&iConnection);
#endif
}
@@ -1268,10 +1189,7 @@ bool QNetworkSessionPrivateImpl::newState(QNetworkSession::State newState, TUint
serviceConfig = QNetworkConfiguration();
iError = QNetworkSession::SessionAbortedError;
emit QNetworkSessionPrivate::error(iError);
- if (ipConnectionNotifier) {
- ipConnectionNotifier->StopNotifications();
- }
- Cancel();
+ closeHandles();
// Start handling IAP state change signals from QNetworkConfigurationManagerPrivate
iHandleStateNotificationsFromManager = true;
emitSessionClosed = true; // Emit SessionClosed after state change has been reported
@@ -1537,6 +1455,11 @@ bool QNetworkSessionPrivateImpl::easyWlanTrueIapId(TUint32 &trueIapId) const
}
#endif
+RConnection* QNetworkSessionPrivateImpl::nativeSession()
+{
+ return &iConnection;
+}
+
ConnectionProgressNotifier::ConnectionProgressNotifier(QNetworkSessionPrivateImpl& owner, RConnection& connection)
: CActive(CActive::EPriorityUserInput), iOwner(owner), iConnection(connection)
{
@@ -1576,6 +1499,50 @@ void ConnectionProgressNotifier::RunL()
}
}
+ConnectionStarter::ConnectionStarter(QNetworkSessionPrivateImpl &owner, RConnection &connection)
+ : CActive(CActive::EPriorityUserInput), iOwner(owner), iConnection(connection)
+{
+ CActiveScheduler::Add(this);
+}
+
+ConnectionStarter::~ConnectionStarter()
+{
+ Cancel();
+}
+
+void ConnectionStarter::Start()
+{
+ if (!IsActive()) {
+ iConnection.Start(iStatus);
+ SetActive();
+ }
+}
+
+void ConnectionStarter::Start(TConnPref &pref)
+{
+ if (!IsActive()) {
+ iConnection.Start(pref, iStatus);
+ SetActive();
+ }
+}
+
+void ConnectionStarter::RunL()
+{
+ iOwner.ConnectionStartComplete(iStatus.Int());
+ //note owner deletes on callback
+}
+
+TInt ConnectionStarter::RunError(TInt err)
+{
+ qWarning() << "ConnectionStarter::RunError" << err;
+ return KErrNone;
+}
+
+void ConnectionStarter::DoCancel()
+{
+ iConnection.Close();
+}
+
QT_END_NAMESPACE
#endif //QT_NO_BEARERMANAGEMENT
diff --git a/src/plugins/bearer/symbian/qnetworksession_impl.h b/src/plugins/bearer/symbian/qnetworksession_impl.h
index d5656d9..2dda456 100644
--- a/src/plugins/bearer/symbian/qnetworksession_impl.h
+++ b/src/plugins/bearer/symbian/qnetworksession_impl.h
@@ -68,11 +68,12 @@
QT_BEGIN_NAMESPACE
class ConnectionProgressNotifier;
+class ConnectionStarter;
class SymbianEngine;
typedef void (*TOpenCUnSetdefaultifFunction)();
-class QNetworkSessionPrivateImpl : public QNetworkSessionPrivate, public CActive
+class QNetworkSessionPrivateImpl : public QNetworkSessionPrivate
#ifdef SNAP_FUNCTIONALITY_AVAILABLE
, public MMobilityProtocolResp
#endif
@@ -111,7 +112,8 @@ public:
quint64 bytesWritten() const;
quint64 bytesReceived() const;
quint64 activeTime() const;
-
+
+ RConnection* nativeSession();
#ifdef SNAP_FUNCTIONALITY_AVAILABLE
public: // From MMobilityProtocolResp
void PreferredCarrierAvailable(TAccessPointInfo aOldAPInfo,
@@ -125,7 +127,7 @@ public: // From MMobilityProtocolResp
#endif
protected: // From CActive
- void RunL();
+ void ConnectionStartComplete(TInt statusCode);
void DoCancel();
private Q_SLOTS:
@@ -149,6 +151,7 @@ private:
bool easyWlanTrueIapId(TUint32 &trueIapId) const;
#endif
+ void closeHandles();
private: // data
SymbianEngine *engine;
@@ -159,19 +162,17 @@ private: // data
QDateTime startTime;
- RLibrary iOpenCLibrary;
- TOpenCUnSetdefaultifFunction iDynamicUnSetdefaultif;
-
- mutable RSocketServ iSocketServ;
+ mutable RSocketServ &iSocketServ; //not owned, shared from QtCore
mutable RConnection iConnection;
mutable RConnectionMonitor iConnectionMonitor;
ConnectionProgressNotifier* ipConnectionNotifier;
-
+ ConnectionStarter* ipConnectionStarter;
+
bool iHandleStateNotificationsFromManager;
bool iFirstSync;
bool iStoppedByUser;
bool iClosedByUser;
-
+
#ifdef SNAP_FUNCTIONALITY_AVAILABLE
CActiveCommsMobilityApiExt* iMobility;
#endif
@@ -189,6 +190,7 @@ private: // data
bool isOpening;
friend class ConnectionProgressNotifier;
+ friend class ConnectionStarter;
};
class ConnectionProgressNotifier : public CActive
@@ -211,6 +213,24 @@ private: // Data
};
+class ConnectionStarter : public CActive
+{
+public:
+ ConnectionStarter(QNetworkSessionPrivateImpl &owner, RConnection &connection);
+ ~ConnectionStarter();
+
+ void Start();
+ void Start(TConnPref &pref);
+protected:
+ void RunL();
+ TInt RunError(TInt err);
+ void DoCancel();
+
+private: // Data
+ QNetworkSessionPrivateImpl &iOwner;
+ RConnection& iConnection;
+};
+
QT_END_NAMESPACE
#endif //QNETWORKSESSION_IMPL_H
diff --git a/src/plugins/platforms/directfb/qdirectfbglcontext.cpp b/src/plugins/platforms/directfb/qdirectfbglcontext.cpp
index ee46691..85effc9 100644
--- a/src/plugins/platforms/directfb/qdirectfbglcontext.cpp
+++ b/src/plugins/platforms/directfb/qdirectfbglcontext.cpp
@@ -70,11 +70,13 @@ QDirectFbGLContext::QDirectFbGLContext(IDirectFBGL *glContext)
void QDirectFbGLContext::makeCurrent()
{
+ QPlatformGLContext::makeCurrent();
m_dfbGlContext->Lock(m_dfbGlContext);
}
void QDirectFbGLContext::doneCurrent()
{
+ QPlatformGLContext::doneCurrent();
m_dfbGlContext->Unlock(m_dfbGlContext);
}
diff --git a/src/plugins/platforms/eglconvenience/eglconvenience.pri b/src/plugins/platforms/eglconvenience/eglconvenience.pri
new file mode 100644
index 0000000..322d4e4
--- /dev/null
+++ b/src/plugins/platforms/eglconvenience/eglconvenience.pri
@@ -0,0 +1,7 @@
+INCLUDEPATH += $$PWD
+
+SOURCES += \
+ $$PWD/qeglconvenience.cpp
+
+HEADERS += \
+ $$PWD/qeglconvenience.h
diff --git a/src/plugins/platforms/eglconvenience/qeglconvenience.cpp b/src/plugins/platforms/eglconvenience/qeglconvenience.cpp
index ec4577a..df7abc1 100644
--- a/src/plugins/platforms/eglconvenience/qeglconvenience.cpp
+++ b/src/plugins/platforms/eglconvenience/qeglconvenience.cpp
@@ -206,12 +206,12 @@ bool q_reduceConfigAttributes(QVector<EGLint> *configAttributes)
return false;
}
-EGLConfig q_configFromQPlatformWindowFormat(EGLDisplay display, const QPlatformWindowFormat &format, bool highestPixelFormat)
+EGLConfig q_configFromQPlatformWindowFormat(EGLDisplay display, const QPlatformWindowFormat &format, bool highestPixelFormat, int surfaceType)
{
EGLConfig cfg = 0;
QVector<EGLint> configureAttributes = q_createConfigAttributesFromFormat(format);
configureAttributes.append(EGL_SURFACE_TYPE); //we only support eglconfigs for windows for now
- configureAttributes.append(EGL_WINDOW_BIT);
+ configureAttributes.append(surfaceType);
configureAttributes.append(EGL_RENDERABLE_TYPE);
if (format.windowApi() == QPlatformWindowFormat::OpenVG) {
diff --git a/src/plugins/platforms/eglconvenience/qeglconvenience.h b/src/plugins/platforms/eglconvenience/qeglconvenience.h
index 8668095..c7d3d61 100644
--- a/src/plugins/platforms/eglconvenience/qeglconvenience.h
+++ b/src/plugins/platforms/eglconvenience/qeglconvenience.h
@@ -46,16 +46,12 @@
#include <QtGui/QPlatformWindowFormat>
#include <QtCore/QVector>
-#ifdef Q_PLATFORM_WAYLAND
-#include "qwaylandinclude.h"
-#else
#include <EGL/egl.h>
-#endif
QT_BEGIN_NAMESPACE
QVector<EGLint> q_createConfigAttributesFromFormat(const QPlatformWindowFormat &format);
bool q_reduceConfigAttributes(QVector<EGLint> *configAttributes);
-EGLConfig q_configFromQPlatformWindowFormat(EGLDisplay display, const QPlatformWindowFormat &format, bool highestPixelFormat = false);
+EGLConfig q_configFromQPlatformWindowFormat(EGLDisplay display, const QPlatformWindowFormat &format, bool highestPixelFormat = false, int surfaceType = EGL_WINDOW_BIT);
QPlatformWindowFormat qt_qPlatformWindowFormatFromConfig(EGLDisplay display, const EGLConfig config);
bool q_hasEglExtension(EGLDisplay display,const char* extensionName);
diff --git a/src/plugins/platforms/eglconvenience/qeglplatformcontext.cpp b/src/plugins/platforms/eglconvenience/qeglplatformcontext.cpp
index 9a2bc61..ae5215f 100644
--- a/src/plugins/platforms/eglconvenience/qeglplatformcontext.cpp
+++ b/src/plugins/platforms/eglconvenience/qeglplatformcontext.cpp
@@ -146,11 +146,6 @@ void* QEGLPlatformContext::getProcAddress(const QString& procName)
return (void *)eglGetProcAddress(qPrintable(procName));
}
-void QEGLPlatformContext::makeDefaultSharedContext()
-{
- setDefaultSharedContext(this);
-}
-
QPlatformWindowFormat QEGLPlatformContext::platformWindowFormat() const
{
return m_windowFormat;
diff --git a/src/plugins/platforms/eglconvenience/qeglplatformcontext.h b/src/plugins/platforms/eglconvenience/qeglplatformcontext.h
index d688660..69835d7 100644
--- a/src/plugins/platforms/eglconvenience/qeglplatformcontext.h
+++ b/src/plugins/platforms/eglconvenience/qeglplatformcontext.h
@@ -56,8 +56,6 @@ public:
void swapBuffers();
void* getProcAddress(const QString& procName);
- void makeDefaultSharedContext();
-
QPlatformWindowFormat platformWindowFormat() const;
EGLContext eglContext() const;
diff --git a/src/plugins/platforms/eglconvenience/qxlibeglintegration.cpp b/src/plugins/platforms/eglconvenience/qxlibeglintegration.cpp
index 7f296c5..45746e9 100644
--- a/src/plugins/platforms/eglconvenience/qxlibeglintegration.cpp
+++ b/src/plugins/platforms/eglconvenience/qxlibeglintegration.cpp
@@ -52,13 +52,11 @@ static int countBits(unsigned long mask)
return count;
}
-VisualID QXlibEglIntegration::getCompatibleVisualId(Display *display, EGLConfig config)
+VisualID QXlibEglIntegration::getCompatibleVisualId(Display *display, EGLDisplay eglDisplay, EGLConfig config)
{
VisualID visualId = 0;
EGLint eglValue = 0;
- EGLDisplay eglDisplay = eglGetDisplay(display);
-
EGLint configRedSize = 0;
eglGetConfigAttrib(eglDisplay, config, EGL_RED_SIZE, &configRedSize);
diff --git a/src/plugins/platforms/eglconvenience/qxlibeglintegration.h b/src/plugins/platforms/eglconvenience/qxlibeglintegration.h
index 51996da..6c2e266 100644
--- a/src/plugins/platforms/eglconvenience/qxlibeglintegration.h
+++ b/src/plugins/platforms/eglconvenience/qxlibeglintegration.h
@@ -47,7 +47,7 @@
class QXlibEglIntegration
{
public:
- static VisualID getCompatibleVisualId(Display *display, EGLConfig config);
+ static VisualID getCompatibleVisualId(Display *display, EGLDisplay eglDisplay, EGLConfig config);
};
#endif // QTESTLITEEGLINTEGRATION_H
diff --git a/src/plugins/platforms/eglconvenience/xlibeglintegration.pri b/src/plugins/platforms/eglconvenience/xlibeglintegration.pri
new file mode 100644
index 0000000..9404a70
--- /dev/null
+++ b/src/plugins/platforms/eglconvenience/xlibeglintegration.pri
@@ -0,0 +1,7 @@
+INCLUDEPATH += $$PWD
+
+HEADERS += \
+ $$PWD/qxlibeglintegration.h
+
+SOURCES += \
+ $$PWD/qxlibeglintegration.cpp
diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.cpp b/src/plugins/platforms/eglfs/qeglfsintegration.cpp
index 78981f9..1bc0806 100644
--- a/src/plugins/platforms/eglfs/qeglfsintegration.cpp
+++ b/src/plugins/platforms/eglfs/qeglfsintegration.cpp
@@ -44,12 +44,12 @@
#include "qeglfswindow.h"
#include "qeglfswindowsurface.h"
+#include "qgenericunixfontdatabase.h"
+
#include <QtGui/QPlatformWindow>
#include <QtGui/QPlatformWindowFormat>
#include <QtOpenGL/private/qpixmapdata_gl_p.h>
-#include "qgenericunixfontdatabase.h"
-
#include <EGL/egl.h>
QT_BEGIN_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/qeglfsscreen.cpp b/src/plugins/platforms/eglfs/qeglfsscreen.cpp
index 2200d1d..b6f2805 100644
--- a/src/plugins/platforms/eglfs/qeglfsscreen.cpp
+++ b/src/plugins/platforms/eglfs/qeglfsscreen.cpp
@@ -203,7 +203,6 @@ void QEglFSScreen::createAndSetPlatformContext()
attribList[temp++] = EGL_NONE;
QEGLPlatformContext *platformContext = new QEGLPlatformContext(m_dpy,config,attribList,m_surface,EGL_OPENGL_ES_API);
- platformContext->makeDefaultSharedContext();
m_platformContext = platformContext;
EGLint w,h; // screen size detection
diff --git a/src/plugins/platforms/eglfs/qeglfsscreen.h b/src/plugins/platforms/eglfs/qeglfsscreen.h
index 6a2a504..f300842 100644
--- a/src/plugins/platforms/eglfs/qeglfsscreen.h
+++ b/src/plugins/platforms/eglfs/qeglfsscreen.h
@@ -44,6 +44,7 @@
#include <QPlatformScreen>
+#include <QtCore/QTextStream>
#include <EGL/egl.h>
diff --git a/src/plugins/platforms/eglfs/qeglfswindow.h b/src/plugins/platforms/eglfs/qeglfswindow.h
index ad51114..f125eab 100644
--- a/src/plugins/platforms/eglfs/qeglfswindow.h
+++ b/src/plugins/platforms/eglfs/qeglfswindow.h
@@ -45,12 +45,9 @@
#include "qeglfsintegration.h"
#include "qeglfsscreen.h"
-
#include <QPlatformWindow>
#include <QtGui/QWidget>
-#include <EGL/egl.h>
-
QT_BEGIN_NAMESPACE
class QEglFSWindow : public QPlatformWindow
diff --git a/src/plugins/platforms/fontdatabases/genericunix/genericunix.pri b/src/plugins/platforms/fontdatabases/genericunix/genericunix.pri
index dbcfbce..1153ab3 100644
--- a/src/plugins/platforms/fontdatabases/genericunix/genericunix.pri
+++ b/src/plugins/platforms/fontdatabases/genericunix/genericunix.pri
@@ -5,6 +5,6 @@ contains(QT_CONFIG, fontconfig) {
include(../basicunix/basicunix.pri)
}
-INCLUDEPATH += $$QT_SOURCE_TREE/src/plugins/platforms/fontdatabases/genericunix
+INCLUDEPATH += $$PWD
HEADERS += \
- $$QT_SOURCE_TREE/src/plugins/platforms/fontdatabases/genericunix/qgenericunixfontdatabase.h
+ $$PWD/qgenericunixfontdatabase.h
diff --git a/src/plugins/platforms/glxconvenience/glxconvenience.pri b/src/plugins/platforms/glxconvenience/glxconvenience.pri
new file mode 100644
index 0000000..d6c9922
--- /dev/null
+++ b/src/plugins/platforms/glxconvenience/glxconvenience.pri
@@ -0,0 +1,7 @@
+INCLUDEPATH += $$PWD
+
+HEADERS += \
+ $$PWD/qglxconvenience.h
+
+SOURCES += \
+ $$PWD/qglxconvenience.cpp
diff --git a/src/plugins/platforms/glxconvenience/qglxconvenience.cpp b/src/plugins/platforms/glxconvenience/qglxconvenience.cpp
new file mode 100644
index 0000000..7cee3e2
--- /dev/null
+++ b/src/plugins/platforms/glxconvenience/qglxconvenience.cpp
@@ -0,0 +1,243 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qglxconvenience.h"
+
+#include <QtCore/QVector>
+
+enum {
+ XFocusOut = FocusOut,
+ XFocusIn = FocusIn,
+ XKeyPress = KeyPress,
+ XKeyRelease = KeyRelease,
+ XNone = None,
+ XRevertToParent = RevertToParent,
+ XGrayScale = GrayScale,
+ XCursorShape = CursorShape
+};
+#undef FocusOut
+#undef FocusIn
+#undef KeyPress
+#undef KeyRelease
+#undef None
+#undef RevertToParent
+#undef GrayScale
+#undef CursorShape
+
+#ifdef FontChange
+#undef FontChange
+#endif
+
+QVector<int> qglx_buildSpec(const QPlatformWindowFormat &format, int drawableBit)
+{
+ QVector<int> spec(48);
+ int i = 0;
+
+ spec[i++] = GLX_LEVEL;
+ spec[i++] = 0;
+ spec[i++] = GLX_DRAWABLE_TYPE; spec[i++] = drawableBit;
+
+ if (format.rgba()) {
+ spec[i++] = GLX_RENDER_TYPE; spec[i++] = GLX_RGBA_BIT;
+ spec[i++] = GLX_RED_SIZE; spec[i++] = (format.redBufferSize() == -1) ? 1 : format.redBufferSize();
+ spec[i++] = GLX_GREEN_SIZE; spec[i++] = (format.greenBufferSize() == -1) ? 1 : format.greenBufferSize();
+ spec[i++] = GLX_BLUE_SIZE; spec[i++] = (format.blueBufferSize() == -1) ? 1 : format.blueBufferSize();
+ if (format.alpha()) {
+ 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.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;
+ }
+
+ spec[i++] = GLX_DOUBLEBUFFER; spec[i++] = format.doubleBuffer() ? True : False;
+ spec[i++] = GLX_STEREO; spec[i++] = format.stereo() ? True : False;
+
+ if (format.depth()) {
+ spec[i++] = GLX_DEPTH_SIZE; spec[i++] = (format.depthBufferSize() == -1) ? 1 : format.depthBufferSize();
+ }
+
+ if (format.stencil()) {
+ spec[i++] = GLX_STENCIL_SIZE; spec[i++] = (format.stencilBufferSize() == -1) ? 1 : format.stencilBufferSize();
+ }
+ if (format.sampleBuffers()) {
+ spec[i++] = GLX_SAMPLE_BUFFERS_ARB;
+ spec[i++] = 1;
+ spec[i++] = GLX_SAMPLES_ARB;
+ spec[i++] = format.samples() == -1 ? 4 : format.samples();
+ }
+
+ spec[i++] = XNone;
+ return spec;
+}
+
+GLXFBConfig qglx_findConfig(Display *display, int screen , const QPlatformWindowFormat &format, int drawableBit)
+{
+ bool reduced = true;
+ GLXFBConfig chosenConfig = 0;
+ QPlatformWindowFormat reducedFormat = format;
+ while (!chosenConfig && reduced) {
+ QVector<int> spec = qglx_buildSpec(reducedFormat, drawableBit);
+ int confcount = 0;
+ GLXFBConfig *configs;
+ configs = glXChooseFBConfig(display, screen,spec.constData(),&confcount);
+ if (confcount)
+ {
+ for (int i = 0; i < confcount; i++) {
+ chosenConfig = configs[i];
+ // Make sure we try to get an ARGB visual if the format asked for an alpha:
+ if (reducedFormat.alpha()) {
+ int alphaSize;
+ glXGetFBConfigAttrib(display,configs[i],GLX_ALPHA_SIZE,&alphaSize);
+ if (alphaSize > 0)
+ break;
+ } else {
+ break; // Just choose the first in the list if there's no alpha requested
+ }
+ }
+
+ XFree(configs);
+ }
+ reducedFormat = qglx_reducePlatformWindowFormat(reducedFormat,&reduced);
+ }
+
+ if (!chosenConfig)
+ qWarning("Warning: no suitable glx confiuration found");
+
+ return chosenConfig;
+}
+
+XVisualInfo *qglx_findVisualInfo(Display *display, int screen, const QPlatformWindowFormat &format)
+{
+ GLXFBConfig config = qglx_findConfig(display,screen,format);
+ XVisualInfo *visualInfo = glXGetVisualFromFBConfig(display,config);
+ return visualInfo;
+}
+
+QPlatformWindowFormat qglx_platformWindowFromGLXFBConfig(Display *display, GLXFBConfig config, GLXContext ctx)
+{
+ QPlatformWindowFormat format;
+ int redSize = 0;
+ int greenSize = 0;
+ int blueSize = 0;
+ int alphaSize = 0;
+ int depthSize = 0;
+ int stencilSize = 0;
+ int sampleBuffers = 0;
+ int sampleCount = 0;
+ int level = 0;
+ int rgba = 0;
+ int stereo = 0;
+ int accumSizeA = 0;
+ int accumSizeR = 0;
+ int accumSizeG = 0;
+ int accumSizeB = 0;
+
+ XVisualInfo *vi = glXGetVisualFromFBConfig(display,config);
+ glXGetConfig(display,vi,GLX_RGBA,&rgba);
+ XFree(vi);
+ glXGetFBConfigAttrib(display, config, GLX_RED_SIZE, &redSize);
+ glXGetFBConfigAttrib(display, config, GLX_GREEN_SIZE, &greenSize);
+ glXGetFBConfigAttrib(display, config, GLX_BLUE_SIZE, &blueSize);
+ glXGetFBConfigAttrib(display, config, GLX_ALPHA_SIZE, &alphaSize);
+ glXGetFBConfigAttrib(display, config, GLX_DEPTH_SIZE, &depthSize);
+ glXGetFBConfigAttrib(display, config, GLX_STENCIL_SIZE, &stencilSize);
+ glXGetFBConfigAttrib(display, config, GLX_SAMPLES, &sampleBuffers);
+ glXGetFBConfigAttrib(display, config, GLX_LEVEL, &level);
+ glXGetFBConfigAttrib(display, config, GLX_STEREO, &stereo);
+ glXGetFBConfigAttrib(display, config, GLX_ACCUM_ALPHA_SIZE, &accumSizeA);
+ glXGetFBConfigAttrib(display, config, GLX_ACCUM_RED_SIZE, &accumSizeR);
+ glXGetFBConfigAttrib(display, config, GLX_ACCUM_GREEN_SIZE, &accumSizeG);
+ glXGetFBConfigAttrib(display, config, GLX_ACCUM_BLUE_SIZE, &accumSizeB);
+
+ format.setRedBufferSize(redSize);
+ format.setGreenBufferSize(greenSize);
+ format.setBlueBufferSize(blueSize);
+ format.setAlphaBufferSize(alphaSize);
+ format.setDepthBufferSize(depthSize);
+ format.setStencilBufferSize(stencilSize);
+ format.setSampleBuffers(sampleBuffers);
+ if (format.sampleBuffers()) {
+ glXGetFBConfigAttrib(display, config, GLX_SAMPLES_ARB, &sampleCount);
+ format.setSamples(sampleCount);
+ }
+
+ format.setDirectRendering(glXIsDirect(display, ctx));
+ format.setRgba(rgba);
+ format.setStereo(stereo);
+ format.setAccumBufferSize(accumSizeB);
+
+ return format;
+}
+
+QPlatformWindowFormat qglx_reducePlatformWindowFormat(const QPlatformWindowFormat &format, bool *reduced)
+{
+ QPlatformWindowFormat retFormat = format;
+ *reduced = true;
+
+ if (retFormat.sampleBuffers()) {
+ retFormat.setSampleBuffers(false);
+ } else if (retFormat.stereo()) {
+ retFormat.setStereo(false);
+ } else if (retFormat.accum()) {
+ retFormat.setAccum(false);
+ }else if (retFormat.stencil()) {
+ retFormat.setStencil(false);
+ }else if (retFormat.alpha()) {
+ retFormat.setAlpha(false);
+ }else if (retFormat.depth()) {
+ retFormat.setDepth(false);
+ }else if (retFormat.doubleBuffer()) {
+ retFormat.setDoubleBuffer(false);
+ }else{
+ *reduced = false;
+ }
+ return retFormat;
+}
diff --git a/src/plugins/platforms/glxconvenience/qglxconvenience.h b/src/plugins/platforms/glxconvenience/qglxconvenience.h
new file mode 100644
index 0000000..2c59dbb
--- /dev/null
+++ b/src/plugins/platforms/glxconvenience/qglxconvenience.h
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGLXCONVENIENCE_H
+#define QGLXCONVENIENCE_H
+
+#include <QPlatformWindowFormat>
+
+#include <X11/Xlib.h>
+#include <GL/glx.h>
+
+XVisualInfo *qglx_findVisualInfo(Display *display, int screen, const QPlatformWindowFormat &format);
+GLXFBConfig qglx_findConfig(Display *display, int screen, const QPlatformWindowFormat &format, int drawableBit = GLX_WINDOW_BIT);
+QPlatformWindowFormat qglx_platformWindowFromGLXFBConfig(Display *display, GLXFBConfig config, GLXContext context);
+QVector<int> qglx_buildSpec(const QPlatformWindowFormat &format, int drawableBit = GLX_WINDOW_BIT);
+QPlatformWindowFormat qglx_reducePlatformWindowFormat(const QPlatformWindowFormat &format, bool *reduced);
+
+#endif // QGLXCONVENIENCE_H
diff --git a/src/plugins/platforms/openkode/qopenkodeintegration.cpp b/src/plugins/platforms/openkode/qopenkodeintegration.cpp
index 35e744be..703b1a9 100644
--- a/src/plugins/platforms/openkode/qopenkodeintegration.cpp
+++ b/src/plugins/platforms/openkode/qopenkodeintegration.cpp
@@ -122,7 +122,9 @@ QOpenKODEScreen::QOpenKODEScreen(KDDisplayNV *kdDisplay, KDDesktopNV *kdDesktop
}
QOpenKODEIntegration::QOpenKODEIntegration()
- : mEventLoopIntegration(0), mFontDb(new QGenericUnixFontDatabase())
+ : mEventLoopIntegration(0)
+ , mFontDb(new QGenericUnixFontDatabase())
+ , mMainGlContext(0)
{
if (kdInitializeNV() == KD_ENOTINITIALIZED) {
qFatal("Did not manage to initialize openkode");
@@ -190,6 +192,7 @@ bool QOpenKODEIntegration::hasCapability(QPlatformIntegration::Capability cap) c
{
switch (cap) {
case ThreadedPixmaps: return true;
+ case OpenGL: return true;
default: return QPlatformIntegration::hasCapability(cap);
}
}
@@ -226,11 +229,6 @@ QWindowSurface *QOpenKODEIntegration::createWindowSurface(QWidget *widget, WId)
return returnSurface;
}
-bool QOpenKODEIntegration::hasOpenGL() const
-{
- return true;
-}
-
QPlatformEventLoopIntegration *QOpenKODEIntegration::createEventLoopIntegration() const
{
if (!mEventLoopIntegration) {
diff --git a/src/plugins/platforms/openkode/qopenkodeintegration.h b/src/plugins/platforms/openkode/qopenkodeintegration.h
index 7582e60..d5aac98 100644
--- a/src/plugins/platforms/openkode/qopenkodeintegration.h
+++ b/src/plugins/platforms/openkode/qopenkodeintegration.h
@@ -96,8 +96,6 @@ public:
QPlatformWindow *createPlatformWindow(QWidget *widget, WId winId = 0) const;
QWindowSurface *createWindowSurface(QWidget *widget, WId winId) const;
- bool hasOpenGL() const;
-
QPlatformEventLoopIntegration *createEventLoopIntegration() const;
QPlatformFontDatabase *fontDatabase() const;
@@ -106,10 +104,14 @@ public:
static GLuint blitterProgram();
+ void setMainGLContext(QEGLPlatformContext *ctx) { mMainGlContext = ctx; }
+ void mainGLContext() const { return mMainGlContext; }
+
private:
QList<QPlatformScreen *> mScreens;
QOpenKODEEventLoopIntegration *mEventLoopIntegration;
QPlatformFontDatabase *mFontDb;
+ QEGLPlatformContext *mMainGlContext;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/openkode/qopenkodewindow.cpp b/src/plugins/platforms/openkode/qopenkodewindow.cpp
index 66530a5..d34dff8 100644
--- a/src/plugins/platforms/openkode/qopenkodewindow.cpp
+++ b/src/plugins/platforms/openkode/qopenkodewindow.cpp
@@ -147,9 +147,9 @@ QOpenKODEWindow::QOpenKODEWindow(QWidget *tlw)
}
+ QOpenKODEIntegration *integration = static_cast<QOpenKODEIntegration *>(QApplicationPrivate::platformIntegration());
-
- if (!isFullScreen || (isFullScreen && !QPlatformGLContext::defaultSharedContext())) {
+ if (!isFullScreen || (isFullScreen && !integration->mainGLContext())) {
if (kdRealizeWindow(m_kdWindow, &m_eglWindow)) {
qErrnoWarning(kdGetError(), "Could not realize native window");
return;
@@ -158,9 +158,9 @@ QOpenKODEWindow::QOpenKODEWindow(QWidget *tlw)
EGLSurface surface = eglCreateWindowSurface(screen->eglDisplay(),m_eglConfig,m_eglWindow,m_eglWindowAttrs.constData());
m_platformGlContext = new QEGLPlatformContext(screen->eglDisplay(), m_eglConfig,
m_eglContextAttrs.data(), surface, m_eglApi);
- m_platformGlContext->makeDefaultSharedContext();
+ integration->setMainGLContext(m_platformGLContext);
} else {
- m_platformGlContext = const_cast<QEGLPlatformContext *>(static_cast<const QEGLPlatformContext *>(QPlatformGLContext::defaultSharedContext()));
+ m_platformGlContext = integration->mainGLContext();
kdDestroyWindow(m_kdWindow);
m_kdWindow = 0;
}
@@ -169,7 +169,7 @@ QOpenKODEWindow::QOpenKODEWindow(QWidget *tlw)
QOpenKODEWindow::~QOpenKODEWindow()
{
- if (m_platformGlContext != QPlatformGLContext::defaultSharedContext()) {
+ if (m_platformGlContext != static_cast<QOpenKODEIntegration *>(QApplicationPrivate::platformIntegration())) {
delete m_platformGlContext;
}
if (m_kdWindow)
diff --git a/src/plugins/platforms/uikit/README b/src/plugins/platforms/uikit/README
index b2984fc..a101a3a 100644
--- a/src/plugins/platforms/uikit/README
+++ b/src/plugins/platforms/uikit/README
@@ -18,11 +18,11 @@ After configuring and building Qt you need to also build src/plugins/platforms/u
Simulator:
----------
-configure -qpa -xplatform qws/macx-iphonesimulator-g++ -arch i386 -developer-build -no-accessibility -no-qt3support -no-multimedia -no-phonon -no-phonon-backend -no-svg -no-webkit -no-scripttools -no-openssl -no-sql-mysql -no-sql-odbc -no-cups -no-iconv -no-dbus -no-opengl -static -nomake tools -nomake demos -nomake docs -nomake examples -nomake translations
+configure -qpa -xplatform qws/macx-iphonesimulator-g++ -arch i386 -developer-build -opengl es1 -no-accessibility -no-qt3support -no-multimedia -no-phonon -no-phonon-backend -no-svg -no-webkit -no-scripttools -no-openssl -no-sql-mysql -no-sql-odbc -no-cups -no-iconv -no-dbus -static -nomake tools -nomake demos -nomake docs -nomake examples -nomake translations
Device:
-------
-configure -qpa -xplatform qws/macx-iphonedevice-g++ -arch armv7 -developer-build -release -no-accessibility -no-qt3support -no-multimedia -no-phonon -no-phonon-backend -no-svg -no-webkit -no-scripttools -no-openssl -no-sql-mysql -no-sql-odbc -no-cups -no-iconv -no-dbus -no-opengl -static -nomake tools -nomake demos -nomake docs -nomake examples -nomake translations
+configure -qpa -xplatform qws/macx-iphonedevice-g++ -arch armv7 -developer-build -release -opengl es1 -no-accessibility -no-qt3support -no-multimedia -no-phonon -no-phonon-backend -no-svg -no-webkit -no-scripttools -no-openssl -no-sql-mysql -no-sql-odbc -no-cups -no-iconv -no-dbus -static -nomake tools -nomake demos -nomake docs -nomake examples -nomake translations
2) XCode setup:
- there are examples in the examples subdirectory of the platform plugin
diff --git a/src/plugins/platforms/uikit/examples/qmltest/main.mm b/src/plugins/platforms/uikit/examples/qmltest/main.mm
index 6fd5629..ea4e90c 100644
--- a/src/plugins/platforms/uikit/examples/qmltest/main.mm
+++ b/src/plugins/platforms/uikit/examples/qmltest/main.mm
@@ -39,36 +39,40 @@
**
****************************************************************************/
-//
-// main.m
-// qmltest
-//
-// Created by Eike Troll on 18.02.11.
-// Copyright 2011 __MyCompanyName__. All rights reserved.
-//
-
#import <UIKit/UIKit.h>
#include "qmlapplicationviewer/qmlapplicationviewer.h"
#include <QtGui/QApplication>
#include <QtCore/QtPlugin>
+#include <QtDeclarative/QDeclarativeEngine>
Q_IMPORT_PLUGIN(UIKit)
+static QString qStringFromNSString(NSString *nsstring)
+{
+ return QString::fromUtf8([nsstring UTF8String]);
+}
+
+static QString documentsDirectory()
+{
+ NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
+ NSString *documentsDirectory = [paths objectAtIndex:0];
+ return qStringFromNSString(documentsDirectory);
+}
+
int main(int argc, char *argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
- setenv("QT_QPA_PLATFORM","uikit",1);
-
- QApplication app(argc, argv);
+ QApplication app(argc, argv);
QmlApplicationViewer viewer;
viewer.setOrientation(QmlApplicationViewer::ScreenOrientationAuto);
- NSString *resourcePath = [[NSBundle mainBundle] resourcePath];
- viewer.setMainQmlFile(QString::fromUtf8([[resourcePath stringByAppendingPathComponent:@"qml/main.qml"] UTF8String]));
+ viewer.engine()->setOfflineStoragePath(documentsDirectory());
+ NSString *resourcePath = [[NSBundle mainBundle] resourcePath];
+ viewer.setMainQmlFile(qStringFromNSString([resourcePath stringByAppendingPathComponent:@"qml/main.qml"]));
viewer.showMaximized();
- int retVal = app.exec();
+ int retVal = app.exec();
[pool release];
return retVal;
}
diff --git a/src/plugins/platforms/uikit/examples/qmltest/qmltest.xcodeproj/project.pbxproj b/src/plugins/platforms/uikit/examples/qmltest/qmltest.xcodeproj/project.pbxproj
index fc4f1df..10bb20f 100755
--- a/src/plugins/platforms/uikit/examples/qmltest/qmltest.xcodeproj/project.pbxproj
+++ b/src/plugins/platforms/uikit/examples/qmltest/qmltest.xcodeproj/project.pbxproj
@@ -10,6 +10,14 @@
1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; };
1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; };
288765A50DF7441C002DB57D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765A40DF7441C002DB57D /* CoreGraphics.framework */; };
+ D316594E1338B29E00760B02 /* libQtXml_debug.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D31659431338B21000760B02 /* libQtXml_debug.a */; };
+ D316594F1338B29E00760B02 /* libQtXmlPatterns_debug.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D31659441338B21000760B02 /* libQtXmlPatterns_debug.a */; };
+ D35784241345D8C90046D202 /* libQtOpenGL_debug.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D35784231345D8C90046D202 /* libQtOpenGL_debug.a */; };
+ D35784261345D9940046D202 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D35784251345D9940046D202 /* OpenGLES.framework */; };
+ D35784281345D9E00046D202 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D35784271345D9E00046D202 /* QuartzCore.framework */; };
+ D3578436134A09990046D202 /* libQtOpenGL.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D3578435134A09990046D202 /* libQtOpenGL.a */; };
+ D3578439134A0AAE0046D202 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D35784251345D9940046D202 /* OpenGLES.framework */; };
+ D357843A134A0AB10046D202 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D35784271345D9E00046D202 /* QuartzCore.framework */; };
D3CAA7C813264AAD008BB877 /* main.mm in Sources */ = {isa = PBXBuildFile; fileRef = D3CAA7C713264AAD008BB877 /* main.mm */; };
D3CAA7E613264EA6008BB877 /* moc_qmlapplicationviewer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D3CAA7E313264EA6008BB877 /* moc_qmlapplicationviewer.cpp */; };
D3CAA7E713264EA6008BB877 /* qmlapplicationviewer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D3CAA7E413264EA6008BB877 /* qmlapplicationviewer.cpp */; };
@@ -50,6 +58,12 @@
288765A40DF7441C002DB57D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
32CA4F630368D1EE00C91783 /* qmltest_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = qmltest_Prefix.pch; sourceTree = "<group>"; };
8D1107310486CEB800E47090 /* qmltest-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "qmltest-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = "<group>"; };
+ D31659431338B21000760B02 /* libQtXml_debug.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libQtXml_debug.a; path = "../../../../../../../qt-lighthouse-ios-simulator/lib/libQtXml_debug.a"; sourceTree = SOURCE_ROOT; };
+ D31659441338B21000760B02 /* libQtXmlPatterns_debug.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libQtXmlPatterns_debug.a; path = "../../../../../../../qt-lighthouse-ios-simulator/lib/libQtXmlPatterns_debug.a"; sourceTree = SOURCE_ROOT; };
+ D35784231345D8C90046D202 /* libQtOpenGL_debug.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libQtOpenGL_debug.a; path = "../../../../../../../qt-lighthouse-ios-simulator/lib/libQtOpenGL_debug.a"; sourceTree = "<group>"; };
+ D35784251345D9940046D202 /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; };
+ D35784271345D9E00046D202 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
+ D3578435134A09990046D202 /* libQtOpenGL.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libQtOpenGL.a; path = "../../../../../../../qt-lighthouse-ios-device/lib/libQtOpenGL.a"; sourceTree = "<group>"; };
D3CAA7C713264AAD008BB877 /* main.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = main.mm; sourceTree = "<group>"; };
D3CAA7E313264EA6008BB877 /* moc_qmlapplicationviewer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = moc_qmlapplicationviewer.cpp; path = qmlapplicationviewer/moc_qmlapplicationviewer.cpp; sourceTree = "<group>"; };
D3CAA7E413264EA6008BB877 /* qmlapplicationviewer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = qmlapplicationviewer.cpp; path = qmlapplicationviewer/qmlapplicationviewer.cpp; sourceTree = "<group>"; };
@@ -81,9 +95,11 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
+ D35784281345D9E00046D202 /* QuartzCore.framework in Frameworks */,
1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */,
1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */,
288765A50DF7441C002DB57D /* CoreGraphics.framework in Frameworks */,
+ D35784261345D9940046D202 /* OpenGLES.framework in Frameworks */,
D3CAA7FA13264F8A008BB877 /* libz.1.2.3.dylib in Frameworks */,
D3CAA81B13265056008BB877 /* libQtCore_debug.a in Frameworks */,
D3CAA81C13265056008BB877 /* libQtDeclarative_debug.a in Frameworks */,
@@ -92,6 +108,9 @@
D3CAA81F13265056008BB877 /* libQtSql_debug.a in Frameworks */,
D3CAA8211326507D008BB877 /* libquikit_debug.a in Frameworks */,
D3CAA82813265220008BB877 /* libQtNetwork_debug.a in Frameworks */,
+ D316594E1338B29E00760B02 /* libQtXml_debug.a in Frameworks */,
+ D316594F1338B29E00760B02 /* libQtXmlPatterns_debug.a in Frameworks */,
+ D35784241345D8C90046D202 /* libQtOpenGL_debug.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -99,6 +118,8 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
+ D357843A134A0AB10046D202 /* QuartzCore.framework in Frameworks */,
+ D3578439134A0AAE0046D202 /* OpenGLES.framework in Frameworks */,
D3CAA7F013264F52008BB877 /* Foundation.framework in Frameworks */,
D3CAA7F113264F52008BB877 /* UIKit.framework in Frameworks */,
D3CAA7F213264F52008BB877 /* CoreGraphics.framework in Frameworks */,
@@ -112,6 +133,7 @@
D3D817B8132A2CFD00CDE422 /* libQtXml.a in Frameworks */,
D3D817B9132A2CFD00CDE422 /* libQtXmlPatterns.a in Frameworks */,
D3D817BB132A2D0E00CDE422 /* libquikit.a in Frameworks */,
+ D3578436134A09990046D202 /* libQtOpenGL.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -166,6 +188,8 @@
1DF5F4DF0D08C38300B7A737 /* UIKit.framework */,
1D30AB110D05D00D00671497 /* Foundation.framework */,
288765A40DF7441C002DB57D /* CoreGraphics.framework */,
+ D35784251345D9940046D202 /* OpenGLES.framework */,
+ D35784271345D9E00046D202 /* QuartzCore.framework */,
D3CAA7F913264F8A008BB877 /* libz.1.2.3.dylib */,
);
name = Frameworks;
@@ -189,6 +213,7 @@
D3D817AB132A2CFD00CDE422 /* libQtDeclarative.a */,
D3D817AC132A2CFD00CDE422 /* libQtGui.a */,
D3D817AD132A2CFD00CDE422 /* libQtNetwork.a */,
+ D3578435134A09990046D202 /* libQtOpenGL.a */,
D3D817AE132A2CFD00CDE422 /* libQtScript.a */,
D3D817AF132A2CFD00CDE422 /* libQtSql.a */,
D3D817B0132A2CFD00CDE422 /* libQtXml.a */,
@@ -205,8 +230,11 @@
D3CAA81713265056008BB877 /* libQtDeclarative_debug.a */,
D3CAA81813265056008BB877 /* libQtGui_debug.a */,
D3CAA82713265220008BB877 /* libQtNetwork_debug.a */,
+ D35784231345D8C90046D202 /* libQtOpenGL_debug.a */,
D3CAA81913265056008BB877 /* libQtScript_debug.a */,
D3CAA81A13265056008BB877 /* libQtSql_debug.a */,
+ D31659431338B21000760B02 /* libQtXml_debug.a */,
+ D31659441338B21000760B02 /* libQtXmlPatterns_debug.a */,
);
name = Simulator;
sourceTree = "<group>";
diff --git a/src/plugins/platforms/uikit/quikiteventloop.h b/src/plugins/platforms/uikit/quikiteventloop.h
index cf5c682..b81e0fd 100644
--- a/src/plugins/platforms/uikit/quikiteventloop.h
+++ b/src/plugins/platforms/uikit/quikiteventloop.h
@@ -42,6 +42,9 @@
#ifndef QUIKITEVENTLOOP_H
#define QUIKITEVENTLOOP_H
+#include "quikitsoftwareinputhandler.h"
+
+#include <QtCore/QEvent>
#include <QtGui/QPlatformEventLoopIntegration>
@class EventLoopHelper;
@@ -61,6 +64,7 @@ public:
EventLoopHelper *mHelper;
NSTimer *mTimer;
+ QUIKitSoftwareInputHandler *mInputHandler;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/uikit/quikiteventloop.mm b/src/plugins/platforms/uikit/quikiteventloop.mm
index 70757b1..8d2603c 100644
--- a/src/plugins/platforms/uikit/quikiteventloop.mm
+++ b/src/plugins/platforms/uikit/quikiteventloop.mm
@@ -78,10 +78,6 @@
}
QUIKitWindow *platformWindow = static_cast<QUIKitWindow *>(widget->platformWindow());
platformWindow->ensureNativeWindow();
- QUIKitWindowSurface *surface = static_cast<QUIKitWindowSurface*>(widget->windowSurface());
- UIView *view = surface->nativeView();
- [platformWindow->nativeWindow() addSubview:view];
- [platformWindow->nativeWindow() makeKeyAndVisible];
}
return YES;
}
@@ -128,6 +124,7 @@ QT_BEGIN_NAMESPACE
QUIKitEventLoop::QUIKitEventLoop()
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
+ mInputHandler = new QUIKitSoftwareInputHandler;
mHelper = [[EventLoopHelper alloc] initWithEventLoopIntegration:this];
mTimer = [[NSTimer timerWithTimeInterval:0.030 target:mHelper selector:@selector(processEventsAndSchedule) userInfo:nil repeats:YES] retain];
[pool release];
@@ -137,10 +134,12 @@ QUIKitEventLoop::~QUIKitEventLoop()
{
[mTimer release];
[mHelper release];
+ delete mInputHandler;
}
void QUIKitEventLoop::startEventLoop()
{
+ qApp->installEventFilter(mInputHandler);
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
[[NSRunLoop currentRunLoop] addTimer:[mTimer autorelease] forMode:NSDefaultRunLoopMode];
UIApplicationMain(qApp->argc(), qApp->argv(), nil, @"QUIKitAppDelegate");
@@ -157,4 +156,24 @@ void QUIKitEventLoop::qtNeedsToProcessEvents()
[mHelper performSelectorOnMainThread:@selector(processEvents) withObject:nil waitUntilDone:NO];
}
+bool QUIKitSoftwareInputHandler::eventFilter(QObject *obj, QEvent *event)
+{
+ if (event->type() == QEvent::RequestSoftwareInputPanel) {
+ QWidget *widget = qobject_cast<QWidget *>(obj);
+ if (widget) {
+ QUIKitWindow *platformWindow = static_cast<QUIKitWindow *>(widget->platformWindow());
+ [platformWindow->nativeView() becomeFirstResponder];
+ return true;
+ }
+ } else if (event->type() == QEvent::CloseSoftwareInputPanel) {
+ QWidget *widget = qobject_cast<QWidget *>(obj);
+ if (widget) {
+ QUIKitWindow *platformWindow = static_cast<QUIKitWindow *>(widget->platformWindow());
+ [platformWindow->nativeView() resignFirstResponder];
+ return true;
+ }
+ }
+ return false;
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/uikit/quikitscreen.mm b/src/plugins/platforms/uikit/quikitscreen.mm
index ec94e3a..21494c9 100644
--- a/src/plugins/platforms/uikit/quikitscreen.mm
+++ b/src/plugins/platforms/uikit/quikitscreen.mm
@@ -41,6 +41,8 @@
#include "quikitscreen.h"
+#include <QtGui/QApplication>
+
#include <QtDebug>
QT_BEGIN_NAMESPACE
@@ -51,21 +53,22 @@ QUIKitScreen::QUIKitScreen(int screenIndex)
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
UIScreen *screen = [[UIScreen screens] objectAtIndex:screenIndex];
- UIScreenMode *mode = [screen currentMode];
- CGSize size = [mode size];
- m_geometry = QRect(0, 0, size.width, size.height);
- CGRect bounds = [screen bounds]; // in 'points', 1p == 1/160in
-
-// qreal xDpi = size.width * 160. / bounds.size.width;
-// qreal yDpi = size.height * 160. / bounds.size.height;
-// qDebug() << xDpi << yDpi;
+ CGRect bounds = [screen bounds];
+ m_geometry = QRect(0, 0, bounds.size.width, bounds.size.height);
m_format = QImage::Format_ARGB32;
m_depth = 24;
const qreal inch = 25.4;
- m_physicalSize = QSize(qRound(bounds.size.width * inch / 160.), qRound(bounds.size.height * inch / 160.));
+ qreal dpi = 160.;
+ int dragDistance = 14;
+ if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
+ dpi = 132.;
+ dragDistance = 10;
+ }
+ m_physicalSize = QSize(qRound(bounds.size.width * inch / dpi), qRound(bounds.size.height * inch / dpi));
+ qApp->setStartDragDistance(dragDistance);
[pool release];
}
diff --git a/src/plugins/platforms/uikit/quikitsoftwareinputhandler.h b/src/plugins/platforms/uikit/quikitsoftwareinputhandler.h
new file mode 100644
index 0000000..629fd13
--- /dev/null
+++ b/src/plugins/platforms/uikit/quikitsoftwareinputhandler.h
@@ -0,0 +1,61 @@
+
+
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QUIKITSOFTWAREINPUTHANDLER_H
+#define QUIKITSOFTWAREINPUTHANDLER_H
+
+#include <QtCore/QObject>
+
+QT_BEGIN_NAMESPACE
+
+class QUIKitSoftwareInputHandler : public QObject
+{
+ Q_OBJECT
+
+public:
+ bool eventFilter(QObject *obj, QEvent *event);
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/platforms/uikit/quikitwindow.h b/src/plugins/platforms/uikit/quikitwindow.h
index d5a6690..9e73754 100644
--- a/src/plugins/platforms/uikit/quikitwindow.h
+++ b/src/plugins/platforms/uikit/quikitwindow.h
@@ -43,7 +43,54 @@
#define QUIKITWINDOW_H
#include <QPlatformWindow>
-#include <UIKit/UIKit.h>
+
+#import <UIKit/UIKit.h>
+#import <OpenGLES/ES1/gl.h>
+#import <OpenGLES/ES1/glext.h>
+#import <OpenGLES/EAGL.h>
+
+@interface EAGLView : UIView <UIKeyInput>
+{
+ QPlatformWindow *mWindow;
+ EAGLContext *mContext;
+
+ GLint mFramebufferWidth;
+ GLint mFramebufferHeight;
+
+ GLuint mFramebuffer, mColorRenderbuffer, mDepthRenderbuffer;
+
+ // ------- Text Input ----------
+ UITextAutocapitalizationType autocapitalizationType;
+ UITextAutocorrectionType autocorrectionType;
+ BOOL enablesReturnKeyAutomatically;
+ UIKeyboardAppearance keyboardAppearance;
+ UIKeyboardType keyboardType;
+ UIReturnKeyType returnKeyType;
+ BOOL secureTextEntry;
+}
+
+- (void)setContext:(EAGLContext *)newContext;
+- (void)presentFramebuffer;
+- (void)deleteFramebuffer;
+- (void)createFramebuffer;
+- (void)makeCurrent;
+- (void)setWindow:(QPlatformWindow *)window;
+- (void)sendMouseEventForTouches:(NSSet *)touches withEvent:(UIEvent *)event fakeButtons:(Qt::MouseButtons)buttons;
+
+
+// ------- Text Input ----------
+
+@property(nonatomic) UITextAutocapitalizationType autocapitalizationType;
+@property(nonatomic) UITextAutocorrectionType autocorrectionType;
+@property(nonatomic) BOOL enablesReturnKeyAutomatically;
+@property(nonatomic) UIKeyboardAppearance keyboardAppearance;
+@property(nonatomic) UIKeyboardType keyboardType;
+@property(nonatomic) UIReturnKeyType returnKeyType;
+@property(nonatomic, getter=isSecureTextEntry) BOOL secureTextEntry;
+
+@end
+
+class EAGLPlatformContext;
QT_BEGIN_NAMESPACE
@@ -56,13 +103,18 @@ public:
~QUIKitWindow();
UIWindow *nativeWindow() const { return mWindow; }
+ UIView *nativeView() const { return mView; }
void setGeometry(const QRect &rect);
UIWindow *ensureNativeWindow();
+ QPlatformGLContext *glContext() const;
+
private:
QUIKitScreen *mScreen;
UIWindow *mWindow;
+ EAGLView *mView;
+ mutable EAGLPlatformContext *mContext;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/uikit/quikitwindow.mm b/src/plugins/platforms/uikit/quikitwindow.mm
index ebdee06..52d1846 100644
--- a/src/plugins/platforms/uikit/quikitwindow.mm
+++ b/src/plugins/platforms/uikit/quikitwindow.mm
@@ -39,17 +39,284 @@
**
****************************************************************************/
+#import <QuartzCore/CAEAGLLayer.h>
+
#include "quikitwindow.h"
#include "quikitscreen.h"
#include <QtDebug>
+#include <QtGui/QApplication>
+#include <QtGui/QKeyEvent>
+#include <QtGui/QPlatformGLContext>
+#include <QtGui/QWindowSystemInterface>
+
+#include <QtDebug>
+
+class EAGLPlatformContext : public QPlatformGLContext
+{
+public:
+ EAGLPlatformContext(EAGLView *view)
+ : mView(view)
+ {
+ mFormat.setWindowApi(QPlatformWindowFormat::OpenGL);
+ mFormat.setDepthBufferSize(24);
+ mFormat.setAccumBufferSize(0);
+ mFormat.setRedBufferSize(8);
+ mFormat.setGreenBufferSize(8);
+ mFormat.setBlueBufferSize(8);
+ mFormat.setAlphaBufferSize(8);
+ mFormat.setStencilBufferSize(8);
+ mFormat.setSampleBuffers(false);
+ mFormat.setSamples(1);
+// mFormat.setSwapInterval(?)
+ mFormat.setDoubleBuffer(true);
+ mFormat.setDepth(true);
+ mFormat.setRgba(true);
+ mFormat.setAlpha(true);
+ mFormat.setAccum(false);
+ mFormat.setStencil(true);
+ mFormat.setStereo(false);
+ mFormat.setDirectRendering(false);
+
+ EAGLContext *aContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
+ [mView setContext:aContext];
+ }
+
+ ~EAGLPlatformContext() { }
+
+ void makeCurrent()
+ {
+ QPlatformGLContext::makeCurrent();
+ [mView makeCurrent];
+ }
+
+ void doneCurrent()
+ {
+ QPlatformGLContext::doneCurrent();
+ }
+
+ void swapBuffers()
+ {
+ [mView presentFramebuffer];
+ }
+
+ void* getProcAddress(const QString& ) { return 0; }
+
+ QPlatformWindowFormat platformWindowFormat() const
+ {
+ return mFormat;
+ }
+
+private:
+ EAGLView *mView;
+
+ QPlatformWindowFormat mFormat;
+};
+
+@implementation EAGLView
+
++ (Class)layerClass
+{
+ return [CAEAGLLayer class];
+}
+
+- (id)initWithFrame:(CGRect)frame
+{
+ if ((self = [super initWithFrame:frame])) {
+ CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;
+ eaglLayer.opaque = TRUE;
+ eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
+ [NSNumber numberWithBool:YES], kEAGLDrawablePropertyRetainedBacking,
+ kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat,
+ nil];
+ autocapitalizationType = UITextAutocapitalizationTypeNone;
+ autocorrectionType = UITextAutocorrectionTypeNo;
+ enablesReturnKeyAutomatically = NO;
+ keyboardAppearance = UIKeyboardAppearanceDefault;
+ keyboardType = UIKeyboardTypeDefault;
+ returnKeyType = UIReturnKeyDone;
+ secureTextEntry = NO;
+ }
+ return self;
+}
+
+- (void)setContext:(EAGLContext *)newContext
+{
+ if (mContext != newContext)
+ {
+ [self deleteFramebuffer];
+ [mContext release];
+ mContext = [newContext retain];
+ [EAGLContext setCurrentContext:nil];
+ }
+}
+
+- (void)presentFramebuffer
+{
+ if (mContext) {
+ [EAGLContext setCurrentContext:mContext];
+ glBindRenderbufferOES(GL_RENDERBUFFER_OES, mColorRenderbuffer);
+ [mContext presentRenderbuffer:GL_RENDERBUFFER_OES];
+ }
+}
+
+- (void)deleteFramebuffer
+{
+ if (mContext)
+ {
+ [EAGLContext setCurrentContext:mContext];
+ if (mFramebuffer) {
+ glDeleteFramebuffersOES(1, &mFramebuffer);
+ mFramebuffer = 0;
+ }
+ if (mColorRenderbuffer) {
+ glDeleteRenderbuffersOES(1, &mColorRenderbuffer);
+ mColorRenderbuffer = 0;
+ }
+ if (mDepthRenderbuffer) {
+ glDeleteRenderbuffersOES(1, &mDepthRenderbuffer);
+ mDepthRenderbuffer = 0;
+ }
+ }
+}
+
+- (void)createFramebuffer
+{
+ if (mContext && !mFramebuffer)
+ {
+ [EAGLContext setCurrentContext:mContext];
+ glGenFramebuffersOES(1, &mFramebuffer);
+ glBindFramebufferOES(GL_FRAMEBUFFER_OES, mFramebuffer);
+
+ glGenRenderbuffersOES(1, &mColorRenderbuffer);
+ glBindRenderbufferOES(GL_RENDERBUFFER_OES, mColorRenderbuffer);
+ [mContext renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer *)self.layer];
+ glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &mFramebufferWidth);
+ glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &mFramebufferHeight);
+ glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, mColorRenderbuffer);
+
+ glGenRenderbuffersOES(1, &mDepthRenderbuffer);
+ glBindRenderbufferOES(GL_RENDERBUFFER_OES, mDepthRenderbuffer);
+ glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH24_STENCIL8_OES, mFramebufferWidth, mFramebufferHeight);
+ glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, mDepthRenderbuffer);
+ glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_STENCIL_ATTACHMENT_OES, GL_RENDERBUFFER_OES, mDepthRenderbuffer);
+
+ if (glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES)
+ NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES));
+ }
+}
+
+- (void)makeCurrent
+{
+ if (mContext)
+ {
+ [EAGLContext setCurrentContext:mContext];
+ if (!mFramebuffer)
+ [self createFramebuffer];
+ glBindFramebufferOES(GL_FRAMEBUFFER_OES, mFramebuffer);
+ glViewport(0, 0, mFramebufferWidth, mFramebufferHeight);
+ }
+}
+
+- (void)setWindow:(QPlatformWindow *)window
+{
+ mWindow = window;
+}
+
+- (void)sendMouseEventForTouches:(NSSet *)touches withEvent:(UIEvent *)event fakeButtons:(Qt::MouseButtons)buttons
+{
+ UITouch *touch = [touches anyObject];
+ CGPoint locationInView = [touch locationInView:self];
+ QPoint p(locationInView.x, locationInView.y);
+ // TODO handle global touch point? for status bar?
+ QWindowSystemInterface::handleMouseEvent(mWindow->widget(), (ulong)(event.timestamp*1000),
+ p, p, buttons);
+}
+
+- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
+{
+ [self sendMouseEventForTouches:touches withEvent:event fakeButtons:Qt::LeftButton];
+}
+
+- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
+{
+ [self sendMouseEventForTouches:touches withEvent:event fakeButtons:Qt::LeftButton];
+}
+
+- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
+{
+ [self sendMouseEventForTouches:touches withEvent:event fakeButtons:Qt::NoButton];
+}
+
+- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
+{
+ [self sendMouseEventForTouches:touches withEvent:event fakeButtons:Qt::NoButton];
+}
+
+// ------- Text Input ----------
+
+@synthesize autocapitalizationType;
+@synthesize autocorrectionType;
+@synthesize enablesReturnKeyAutomatically;
+@synthesize keyboardAppearance;
+@synthesize keyboardType;
+@synthesize returnKeyType;
+@synthesize secureTextEntry;
+
+- (BOOL)canBecomeFirstResponder
+{
+ return YES;
+}
+
+- (BOOL)hasText
+{
+ return YES;
+}
+
+- (void)insertText:(NSString *)text
+{
+ QKeyEvent *ev;
+ int key = 0;
+ if ([text isEqualToString:@"\n"])
+ key = (int)Qt::Key_Return;
+ ev = new QKeyEvent(QEvent::KeyPress,
+ key,
+ Qt::NoModifier,
+ QString::fromUtf8([text UTF8String])
+ );
+ qApp->postEvent(qApp->focusWidget(), ev);
+ ev = new QKeyEvent(QEvent::KeyRelease,
+ key,
+ Qt::NoModifier,
+ QString::fromUtf8([text UTF8String])
+ );
+ qApp->postEvent(qApp->focusWidget(), ev);
+}
+
+- (void)deleteBackward
+{
+ QKeyEvent *ev;
+ ev = new QKeyEvent(QEvent::KeyPress,
+ (int)Qt::Key_Backspace,
+ Qt::NoModifier
+ );
+ qApp->postEvent(qApp->focusWidget(), ev);
+ ev = new QKeyEvent(QEvent::KeyRelease,
+ (int)Qt::Key_Backspace,
+ Qt::NoModifier
+ );
+ qApp->postEvent(qApp->focusWidget(), ev);
+}
+
+@end
QT_BEGIN_NAMESPACE
QUIKitWindow::QUIKitWindow(QWidget *tlw) :
QPlatformWindow(tlw),
- mWindow(nil)
+ mWindow(nil),
+ mContext(0)
{
mScreen = static_cast<QUIKitScreen *>(QPlatformScreen::platformScreenForWidget(tlw));
CGRect screenBounds = [mScreen->uiScreen() bounds];
@@ -60,6 +327,8 @@ QUIKitWindow::QUIKitWindow(QWidget *tlw) :
QUIKitWindow::~QUIKitWindow()
{
+ delete mContext; mContext = 0;
+ [mView release];
[mWindow release];
}
@@ -67,6 +336,8 @@ void QUIKitWindow::setGeometry(const QRect &rect)
{
if (mWindow) {
mWindow.frame = CGRectMake(rect.x(), rect.y(), rect.width(), rect.height());
+ mView.frame = CGRectMake(0, 0, rect.width(), rect.height());
+ [mView deleteFramebuffer];
[mWindow setNeedsDisplay];
}
QPlatformWindow::setGeometry(rect);
@@ -75,15 +346,30 @@ void QUIKitWindow::setGeometry(const QRect &rect)
UIWindow *QUIKitWindow::ensureNativeWindow()
{
if (!mWindow) {
- CGRect screenBounds = [mScreen->uiScreen() bounds];
+ // window
QRect geom = geometry();
CGRect frame = CGRectMake(geom.x(), geom.y(), geom.width(), geom.height());
mWindow = [[UIWindow alloc] initWithFrame:frame];
mWindow.screen = mScreen->uiScreen();
mWindow.frame = frame; // for some reason setting the screen resets frame.origin
+
+ // view
+ mView = [[EAGLView alloc] initWithFrame:CGRectMake(0, 0, geom.width(), geom.height())];
+ [mView setMultipleTouchEnabled:YES];
+ [mView setWindow:this];
+ [mWindow addSubview:mView];
[mWindow setNeedsDisplay];
+ [mWindow makeKeyAndVisible];
}
return mWindow;
}
+QPlatformGLContext *QUIKitWindow::glContext() const
+{
+ if (!mContext) {
+ mContext = new EAGLPlatformContext(mView);
+ }
+ return mContext;
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/uikit/quikitwindowsurface.h b/src/plugins/platforms/uikit/quikitwindowsurface.h
index 50d02b4..ca10a71 100644
--- a/src/plugins/platforms/uikit/quikitwindowsurface.h
+++ b/src/plugins/platforms/uikit/quikitwindowsurface.h
@@ -43,23 +43,6 @@
#define QUIKITWINDOWSURFACE_H
#include <QtGui/QPlatformIntegration>
-#include <QtGui/QImage>
-#include <QtGui/QWindowSystemInterface>
-
-#include <UIKit/UIKit.h>
-
-@interface QImageView : UIView
-{
- CGImageRef m_cgImage;
- QWidget *m_widget;
-}
-
-- (void)setImage:(QImage *)image;
-- (void)setWidget:(QWidget *)widget;
-
-//- (QList<struct QWindowSystemInterface::TouchPoint>)touchPointsForTouches:(NSSet *)touches;
-- (void)sendMouseEventForTouches:(NSSet *)touches withEvent:(UIEvent *)event fakeButtons:(Qt::MouseButtons)buttons;
-@end
QT_BEGIN_NAMESPACE
@@ -70,12 +53,10 @@ public:
QPaintDevice *paintDevice();
void flush(QWidget *widget, const QRegion &region, const QPoint &offset);
- void resize (const QSize &size);
+ WindowSurfaceFeatures features() const;
- QImageView *nativeView() const { return mView; }
private:
- QImage *mImage;
- QImageView *mView;
+ QPaintDevice *mPaintDevice;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/uikit/quikitwindowsurface.mm b/src/plugins/platforms/uikit/quikitwindowsurface.mm
index 1274fca..bb7dcd7 100644
--- a/src/plugins/platforms/uikit/quikitwindowsurface.mm
+++ b/src/plugins/platforms/uikit/quikitwindowsurface.mm
@@ -42,201 +42,55 @@
#include "quikitwindowsurface.h"
#include "quikitwindow.h"
-#include <QtDebug>
-
-@implementation QImageView
-
-- (void)dealloc
-{
- CGImageRelease(m_cgImage);
- [super dealloc];
-}
-
-- (void)setImage:(QImage *)image
-{
- CGImageRelease(m_cgImage);
-
- const uchar *imageData = image->bits();
- int bitDepth = image->depth();
- int colorBufferSize = 8;
- int bytesPrLine = image->bytesPerLine();
- int width = image->width();
- int height = image->height();
-
- CGColorSpaceRef cgColourSpaceRef = CGColorSpaceCreateDeviceRGB();
-
- CGDataProviderRef cgDataProviderRef = CGDataProviderCreateWithData(
- NULL,
- imageData,
- image->byteCount(),
- NULL);
-
- m_cgImage = CGImageCreate(width,
- height,
- colorBufferSize,
- bitDepth,
- bytesPrLine,
- cgColourSpaceRef,
- kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little,
- cgDataProviderRef,
- NULL,
- false,
- kCGRenderingIntentDefault);
-
- CGDataProviderRelease(cgDataProviderRef);
- CGColorSpaceRelease(cgColourSpaceRef);
-}
-
-- (void)setWidget:(QWidget *)widget
-{
- m_widget = widget;
-}
-
-- (void)drawRect:(CGRect)rect
-{
-
- if (!m_cgImage)
- return;
-
- CGContextRef cgContext = UIGraphicsGetCurrentContext();
- CGContextSaveGState( cgContext );
+#include <QtOpenGL/private/qgl_p.h>
+#include <QtOpenGL/private/qglpaintdevice_p.h>
- int dy = rect.origin.y + CGRectGetMaxY(rect);
- CGContextTranslateCTM(cgContext, 0, dy);
- CGContextScaleCTM(cgContext, 1, -1);
- CGImageRef subImage = CGImageCreateWithImageInRect(m_cgImage, rect);
- CGContextDrawImage(cgContext,rect,subImage);
- CGImageRelease(subImage);
-
- CGContextRestoreGState(cgContext);
-}
-
-//- (QList<struct QWindowSystemInterface::TouchPoint>)touchPointsForTouches:(NSSet *)touches
-//{
-// NSEnumerator *enumerator = [touches objectEnumerator];
-// id touch;
-// int count = 0;
-// QList<struct QWindowSystemInterface::TouchPoint> result;
-// while ((touch = [enumerator nextObject])) {
-// CGPoint locationInView = [touch locationInView:self];
-// CGRect bounds = [self bounds];
-// struct QWindowSystemInterface::TouchPoint p;
-// p.id = count;
-// p.isPrimary = true;
-// p.normalPosition = QPointF(locationInView.x / bounds.size.width,
-// locationInView.y / bounds.size.height);
-// p.area = QRectF(locationInView.x, locationInView.y, 1, 1);
-// p.pressure = 1.;
-// switch ([touch phase]) {
-// case UITouchPhaseBegan:
-// p.state = Qt::TouchPointPressed;
-// break;
-// case UITouchPhaseMoved:
-// p.state = Qt::TouchPointMoved;
-// break;
-// case UITouchPhaseStationary:
-// p.state = Qt::TouchPointStationary;
-// break;
-// case UITouchPhaseEnded:
-// case UITouchPhaseCancelled:
-// p.state = Qt::TouchPointReleased;
-// break;
-// }
-// result << p;
-// qDebug() << p.id << ":" << p.normalPosition << p.area << p.state;
-// ++count;
-// }
-// qDebug() << result.size();
-// return result;
-//}
-
-- (void)sendMouseEventForTouches:(NSSet *)touches withEvent:(UIEvent *)event fakeButtons:(Qt::MouseButtons)buttons
-{
- UITouch *touch = [touches anyObject];
- CGPoint locationInView = [touch locationInView:self];
- QPoint p(locationInView.x, locationInView.y);
- // TODO handle global touch point? for status bar?
- QWindowSystemInterface::handleMouseEvent(m_widget, (ulong)(event.timestamp*1000),
- p, p, buttons);
-}
-
-- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
-{
- //QWindowSystemInterface::handleTouchEvent(m_widget, (ulong)(event.timestamp*1000),
- // QEvent::TouchBegin, QTouchEvent::TouchScreen,
- // [self touchPointsForTouches:touches]);
- [self sendMouseEventForTouches:touches withEvent:event fakeButtons:Qt::LeftButton];
-}
+#include <QtDebug>
-- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
+class EAGLPaintDevice : public QGLPaintDevice
{
- //QWindowSystemInterface::handleTouchEvent(m_widget, (ulong)(event.timestamp*1000),
- // QEvent::TouchUpdate, QTouchEvent::TouchScreen,
- // [self touchPointsForTouches:touches]);
- [self sendMouseEventForTouches:touches withEvent:event fakeButtons:Qt::LeftButton];
-}
+public:
+ EAGLPaintDevice(QPlatformWindow *window)
+ :QGLPaintDevice(), mWindow(window)
+ {
+ }
-- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
-{
- //QWindowSystemInterface::handleTouchEvent(m_widget, (ulong)(event.timestamp*1000),
- // QEvent::TouchEnd, QTouchEvent::TouchScreen,
- // [self touchPointsForTouches:touches]);
- [self sendMouseEventForTouches:touches withEvent:event fakeButtons:Qt::NoButton];
-}
+ int devType() const { return QInternal::OpenGL; }
+ QSize size() const { return mWindow->geometry().size(); }
+ QGLContext* context() const { return QGLContext::fromPlatformGLContext(mWindow->glContext()); }
-- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
-{
- //QWindowSystemInterface::handleTouchEvent(m_widget, (ulong)(event.timestamp*1000),
- // QEvent::TouchEnd, QTouchEvent::TouchScreen,
- // [self touchPointsForTouches:touches]);
- [self sendMouseEventForTouches:touches withEvent:event fakeButtons:Qt::NoButton];
-}
+ QPaintEngine *paintEngine() const { return qt_qgl_paint_engine(); }
-@end
+ void beginPaint(){
+ QGLPaintDevice::beginPaint();
+ }
+private:
+ QPlatformWindow *mWindow;
+};
QT_BEGIN_NAMESPACE
QUIKitWindowSurface::QUIKitWindowSurface(QWidget *window)
- : QWindowSurface(window)
+ : QWindowSurface(window), mPaintDevice(new EAGLPaintDevice(window->platformWindow()))
{
- QUIKitWindow *platformWindow = static_cast<QUIKitWindow *>(window->platformWindow());
- Q_ASSERT(platformWindow);
- const QRect geo = window->geometry();
- mView = [[QImageView alloc] initWithFrame:CGRectMake(geo.x(),geo.y(),geo.width(),geo.height())];
- [mView setMultipleTouchEnabled:YES];
- [mView setWidget:window];
- mImage = new QImage(window->size(),QImage::Format_ARGB32_Premultiplied);
- [mView setImage:mImage];
- if (platformWindow->nativeWindow()) {
- [platformWindow->nativeWindow() addSubview:mView];
- [mView setNeedsDisplay];
- }
}
QPaintDevice *QUIKitWindowSurface::paintDevice()
{
- return mImage;
+ return mPaintDevice;
}
void QUIKitWindowSurface::flush(QWidget *widget, const QRegion &region, const QPoint &offset)
{
Q_UNUSED(widget);
+ Q_UNUSED(region);
Q_UNUSED(offset);
-
- QRect geo = region.boundingRect();
- [mView setNeedsDisplayInRect:CGRectMake(geo.x(),geo.y(),geo.width(),geo.height())];
+ widget->platformWindow()->glContext()->swapBuffers();
}
-void QUIKitWindowSurface::resize (const QSize &size)
+QWindowSurface::WindowSurfaceFeatures QUIKitWindowSurface::features() const
{
- QWindowSurface::resize(size);
-
- delete mImage;
- mImage = new QImage(size,QImage::Format_ARGB32_Premultiplied);
- [mView setImage:mImage];
- const QRect geo = geometry();
- [mView setFrame:CGRectMake(geo.x(), geo.y(), size.width(), size.height())];
- [mView setNeedsDisplay];
+ return PartialUpdates;
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/uikit/uikit.pro b/src/plugins/platforms/uikit/uikit.pro
index b73c334..6f5947f 100644
--- a/src/plugins/platforms/uikit/uikit.pro
+++ b/src/plugins/platforms/uikit/uikit.pro
@@ -2,6 +2,8 @@ TARGET = quikit
include(../../qpluginbase.pri)
QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/platforms
+QT += opengl
+
OBJECTIVE_SOURCES = main.mm \
quikitintegration.mm \
quikitwindow.mm \
@@ -15,6 +17,8 @@ OBJECTIVE_HEADERS = quikitintegration.h \
quikiteventloop.h \
quikitwindowsurface.h
+HEADERS = quikitsoftwareinputhandler.h
+
#add libz for freetype.
LIBS += -lz
diff --git a/src/plugins/platforms/wayland/gl_integration/gl_integration.pri b/src/plugins/platforms/wayland/gl_integration/gl_integration.pri
new file mode 100644
index 0000000..d9b5fa9
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/gl_integration.pri
@@ -0,0 +1,57 @@
+contains(QT_CONFIG, opengl) {
+ DEFINES += QT_WAYLAND_GL_SUPPORT
+ QT += opengl
+
+HEADERS += \
+ $$PWD/qwaylandglintegration.h \
+ $$PWD/qwaylandglwindowsurface.h
+
+SOURCES += \
+ $$PWD/qwaylandglintegration.cpp \
+ $$PWD/qwaylandglwindowsurface.cpp
+
+ QT_WAYLAND_GL_CONFIG = $$(QT_WAYLAND_GL_CONFIG)
+ contains(QT_CONFIG, opengles2) {
+ isEqual(QT_WAYLAND_GL_CONFIG, wayland_egl) {
+ QT_WAYLAND_GL_INTEGRATION = $$QT_WAYLAND_GL_CONFIG
+ CONFIG += wayland_egl
+ } else:isEqual(QT_WAYLAND_GL_CONFIG,readback) {
+ QT_WAYLAND_GL_INTEGRATION = readback_egl
+ CONFIG += readback_egl
+ } else {
+ QT_WAYLAND_GL_INTEGRATION = xcomposite_egl
+ CONFIG += xcomposite_egl
+ }
+ } else {
+ isEqual(QT_WAYLAND_GL_CONFIG, readback) {
+ QT_WAYLAND_GL_INTEGRATION = readback_glx
+ CONFIG += readback_glx
+ } else {
+ QT_WAYLAND_GL_INTEGRATION = xcomposite_glx
+ CONFIG += xcomposite_glx
+ }
+ }
+
+ message("Wayland GL Integration: $$QT_WAYLAND_GL_INTEGRATION")
+}
+
+
+wayland_egl {
+ include ($$PWD/wayland_egl/wayland_egl.pri)
+}
+
+readback_egl {
+ include ($$PWD/readback_egl/readback_egl.pri)
+}
+
+readback_glx {
+ include ($$PWD/readback_glx/readback_glx.pri)
+}
+
+xcomposite_glx {
+ include ($$PWD/xcomposite_glx/xcomposite_glx.pri)
+}
+
+xcomposite_egl {
+ include ($$PWD/xcomposite_egl/xcomposite_egl.pri)
+}
diff --git a/src/plugins/platforms/wayland/gl_integration/qwaylandglintegration.cpp b/src/plugins/platforms/wayland/gl_integration/qwaylandglintegration.cpp
new file mode 100644
index 0000000..9c8ef4e
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/qwaylandglintegration.cpp
@@ -0,0 +1,52 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwaylandglintegration.h"
+
+QWaylandGLIntegration::QWaylandGLIntegration()
+{
+
+}
+
+QWaylandGLIntegration::~QWaylandGLIntegration()
+{
+
+}
diff --git a/src/plugins/platforms/wayland/gl_integration/qwaylandglintegration.h b/src/plugins/platforms/wayland/gl_integration/qwaylandglintegration.h
new file mode 100644
index 0000000..ac16039
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/qwaylandglintegration.h
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWAYLANDGLINTEGRATION_H
+#define QWAYLANDGLINTEGRATION_H
+
+class QWaylandWindow;
+class QWaylandDisplay;
+class QWidget;
+
+class QWaylandGLIntegration
+{
+public:
+ QWaylandGLIntegration();
+ virtual ~QWaylandGLIntegration();
+
+ virtual void initialize() = 0;
+
+ virtual QWaylandWindow *createEglWindow(QWidget *widget) = 0;
+
+ static QWaylandGLIntegration *createGLIntegration(QWaylandDisplay *waylandDisplay);
+};
+
+#endif // QWAYLANDGLINTEGRATION_H
diff --git a/src/plugins/platforms/wayland/qwaylanddrmsurface.cpp b/src/plugins/platforms/wayland/gl_integration/qwaylandglwindowsurface.cpp
index a8bc352..ebe4c7b 100644
--- a/src/plugins/platforms/wayland/qwaylanddrmsurface.cpp
+++ b/src/plugins/platforms/wayland/gl_integration/qwaylandglwindowsurface.cpp
@@ -39,7 +39,7 @@
**
****************************************************************************/
-#include "qwaylanddrmsurface.h"
+#include "qwaylandglwindowsurface.h"
#include "qwaylanddisplay.h"
#include "qwaylandwindow.h"
@@ -52,10 +52,11 @@
QT_BEGIN_NAMESPACE
-
-
static void drawTexture(const QRectF &rect, GLuint tex_id, const QSize &texSize, const QRectF &br)
{
+#if !defined(QT_OPENGL_ES_2)
+ QGLContext *ctx = const_cast<QGLContext *>(QGLContext::currentContext());
+#endif
const GLenum target = GL_TEXTURE_2D;
QRectF src = br.isEmpty()
? QRectF(QPointF(), texSize)
@@ -132,7 +133,7 @@ static void blitTexture(QGLContext *ctx, GLuint texture, const QSize &viewport,
drawTexture(r, texture, texSize, sourceRect);
}
-QWaylandDrmWindowSurface::QWaylandDrmWindowSurface(QWidget *window)
+QWaylandGLWindowSurface::QWaylandGLWindowSurface(QWidget *window)
: QWindowSurface(window)
, mDisplay(QWaylandScreen::waylandScreenFromWidget(window)->display())
, mPaintDevice(0)
@@ -140,24 +141,24 @@ QWaylandDrmWindowSurface::QWaylandDrmWindowSurface(QWidget *window)
}
-QWaylandDrmWindowSurface::~QWaylandDrmWindowSurface()
+QWaylandGLWindowSurface::~QWaylandGLWindowSurface()
{
delete mPaintDevice;
}
-QPaintDevice *QWaylandDrmWindowSurface::paintDevice()
+QPaintDevice *QWaylandGLWindowSurface::paintDevice()
{
return mPaintDevice;
}
-void QWaylandDrmWindowSurface::beginPaint(const QRegion &)
+void QWaylandGLWindowSurface::beginPaint(const QRegion &)
{
window()->platformWindow()->glContext()->makeCurrent();
glClearColor(0,0,0,0xff);
glClear(GL_COLOR_BUFFER_BIT);
}
-void QWaylandDrmWindowSurface::flush(QWidget *widget, const QRegion &region, const QPoint &offset)
+void QWaylandGLWindowSurface::flush(QWidget *widget, const QRegion &region, const QPoint &offset)
{
Q_UNUSED(offset);
Q_UNUSED(region);
@@ -172,12 +173,12 @@ void QWaylandDrmWindowSurface::flush(QWidget *widget, const QRegion &region, con
ww->glContext()->swapBuffers();
}
-void QWaylandDrmWindowSurface::resize(const QSize &size)
+void QWaylandGLWindowSurface::resize(const QSize &size)
{
QWindowSurface::resize(size);
window()->platformWindow()->glContext()->makeCurrent();
delete mPaintDevice;
- mPaintDevice = new QGLFramebufferObject(size,QGLFramebufferObject::CombinedDepthStencil,GL_TEXTURE_2D,GL_RGBA);
+ mPaintDevice = new QGLFramebufferObject(size);
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/wayland/qwaylanddrmsurface.h b/src/plugins/platforms/wayland/gl_integration/qwaylandglwindowsurface.h
index 78418ee..8d53b42 100644
--- a/src/plugins/platforms/wayland/qwaylanddrmsurface.h
+++ b/src/plugins/platforms/wayland/gl_integration/qwaylandglwindowsurface.h
@@ -4,7 +4,7 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of the config.tests of the Qt Toolkit.
+** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
@@ -48,11 +48,11 @@
class QGLFramebufferObject;
-class QWaylandDrmWindowSurface : public QWindowSurface
+class QWaylandGLWindowSurface : public QWindowSurface
{
public:
- QWaylandDrmWindowSurface(QWidget *window);
- ~QWaylandDrmWindowSurface();
+ QWaylandGLWindowSurface(QWidget *window);
+ ~QWaylandGLWindowSurface();
void beginPaint(const QRegion &);
@@ -62,7 +62,6 @@ public:
void resize(const QSize &size);
private:
-
QWaylandDisplay *mDisplay;
QGLFramebufferObject *mPaintDevice;
};
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglcontext.cpp b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglcontext.cpp
new file mode 100644
index 0000000..d63087d
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglcontext.cpp
@@ -0,0 +1,174 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwaylandreadbackeglcontext.h"
+
+#include "../../../eglconvenience/qeglconvenience.h"
+
+#include <QtOpenGL/QGLContext>
+#include <QtOpenGL/private/qglextensions_p.h>
+
+#include "qwaylandshmsurface.h"
+
+#include <QtCore/QDebug>
+
+static inline void qgl_byteSwapImage(QImage &img, GLenum pixel_type)
+{
+ const int width = img.width();
+ const int height = img.height();
+
+ if (pixel_type == GL_UNSIGNED_INT_8_8_8_8_REV
+ || (pixel_type == GL_UNSIGNED_BYTE && QSysInfo::ByteOrder == QSysInfo::LittleEndian))
+ {
+ for (int i = 0; i < height; ++i) {
+ uint *p = (uint *) img.scanLine(i);
+ for (int x = 0; x < width; ++x)
+ p[x] = ((p[x] << 16) & 0xff0000) | ((p[x] >> 16) & 0xff) | (p[x] & 0xff00ff00);
+ }
+ } else {
+ for (int i = 0; i < height; ++i) {
+ uint *p = (uint *) img.scanLine(i);
+ for (int x = 0; x < width; ++x)
+ p[x] = (p[x] << 8) | ((p[x] >> 24) & 0xff);
+ }
+ }
+}
+
+QWaylandReadbackEglContext::QWaylandReadbackEglContext(QWaylandReadbackEglIntegration *eglIntegration, QWaylandReadbackEglWindow *window)
+ : mEglIntegration(eglIntegration)
+ , mWindow(window)
+ , mBuffer(0)
+ , mPixmap(0)
+ , mConfig(q_configFromQPlatformWindowFormat(eglIntegration->eglDisplay(),window->widget()->platformWindowFormat(),true,EGL_PIXMAP_BIT))
+ , mPixmapSurface(EGL_NO_SURFACE)
+{
+ QVector<EGLint> eglContextAttrs;
+ eglContextAttrs.append(EGL_CONTEXT_CLIENT_VERSION);
+ eglContextAttrs.append(2);
+ eglContextAttrs.append(EGL_NONE);
+
+ mContext = eglCreateContext(eglIntegration->eglDisplay(),mConfig,0,eglContextAttrs.constData());
+
+ geometryChanged();
+}
+
+QWaylandReadbackEglContext::~QWaylandReadbackEglContext()
+{
+ eglDestroyContext(mEglIntegration->eglDisplay(),mContext);
+}
+
+void QWaylandReadbackEglContext::makeCurrent()
+{
+ QPlatformGLContext::makeCurrent();
+
+ mWindow->waitForFrameSync();
+
+ eglMakeCurrent(mEglIntegration->eglDisplay(),mPixmapSurface,mPixmapSurface,mContext);
+}
+
+void QWaylandReadbackEglContext::doneCurrent()
+{
+ QPlatformGLContext::doneCurrent();
+ eglMakeCurrent(mEglIntegration->eglDisplay(),EGL_NO_SURFACE,EGL_NO_SURFACE,EGL_NO_CONTEXT);
+}
+
+void QWaylandReadbackEglContext::swapBuffers()
+{
+ eglSwapBuffers(mEglIntegration->eglDisplay(),mPixmapSurface);
+
+ if (QPlatformGLContext::currentContext() != this) {
+ makeCurrent();
+ }
+
+ QSize size = mWindow->geometry().size();
+
+ QImage img(size,QImage::Format_ARGB32);
+ const uchar *constBits = img.bits();
+ void *pixels = const_cast<uchar *>(constBits);
+
+ glReadPixels(0,0, size.width(), size.height(), GL_RGBA,GL_UNSIGNED_BYTE, pixels);
+
+ img = img.mirrored();
+ qgl_byteSwapImage(img,GL_UNSIGNED_INT_8_8_8_8_REV);
+ constBits = img.bits();
+
+ const uchar *constDstBits = mBuffer->image()->bits();
+ uchar *dstBits = const_cast<uchar *>(constDstBits);
+ memcpy(dstBits,constBits,(img.width()*4) * img.height());
+
+
+ mWindow->damage(QRegion(QRect(QPoint(0,0),size)));
+}
+
+void * QWaylandReadbackEglContext::getProcAddress(const QString &procName)
+{
+ return (void *) eglGetProcAddress(procName.toLatin1().data());
+}
+
+QPlatformWindowFormat QWaylandReadbackEglContext::platformWindowFormat() const
+{
+ return qt_qPlatformWindowFormatFromConfig(mEglIntegration->eglDisplay(),mConfig);
+}
+
+void QWaylandReadbackEglContext::geometryChanged()
+{
+ QSize size(mWindow->geometry().size());
+ if (size.isEmpty()) {
+ //QGLWidget wants a context for a window without geometry
+ size = QSize(1,1);
+ }
+
+ mWindow->waitForFrameSync();
+
+ delete mBuffer;
+ if (mPixmap)
+ XFreePixmap(mEglIntegration->xDisplay(),mPixmap);
+
+ mBuffer = new QWaylandShmBuffer(mEglIntegration->waylandDisplay(),size,QImage::Format_ARGB32);
+ mWindow->attach(mBuffer);
+ mPixmap = XCreatePixmap(mEglIntegration->xDisplay(),mEglIntegration->rootWindow(),size.width(),size.height(),mEglIntegration->depth());
+ XSync(mEglIntegration->xDisplay(),False);
+
+ mPixmapSurface = eglCreatePixmapSurface(mEglIntegration->eglDisplay(),mConfig,mPixmap,0);
+ if (mPixmapSurface == EGL_NO_SURFACE) {
+ qDebug() << "Could not make egl surface out of pixmap :(";
+ }
+}
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglcontext.h b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglcontext.h
new file mode 100644
index 0000000..ac68275
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglcontext.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWAYLANDREADBACKEGLGLCONTEXT_H
+#define QWAYLANDREADBACKEGLGLCONTEXT_H
+
+#include <QPlatformGLContext>
+#include <QtGui/QWidget>
+
+#include "qwaylandreadbackeglintegration.h"
+#include "qwaylandreadbackeglwindow.h"
+
+class QWaylandShmBuffer;
+
+class QWaylandReadbackEglContext : public QPlatformGLContext
+{
+public:
+ QWaylandReadbackEglContext(QWaylandReadbackEglIntegration *eglIntegration, QWaylandReadbackEglWindow *window);
+ ~QWaylandReadbackEglContext();
+
+ void makeCurrent();
+ void doneCurrent();
+ void swapBuffers();
+ void* getProcAddress(const QString& procName);
+
+ virtual QPlatformWindowFormat platformWindowFormat() const;
+
+ void geometryChanged();
+
+private:
+ QWaylandReadbackEglIntegration *mEglIntegration;
+ QWaylandReadbackEglWindow *mWindow;
+ QWaylandShmBuffer *mBuffer;
+
+ Pixmap mPixmap;
+
+ EGLConfig mConfig;
+ EGLContext mContext;
+ EGLSurface mPixmapSurface;
+};
+
+#endif // QWAYLANDREADBACKEGLGLCONTEXT_H
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.cpp b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.cpp
new file mode 100644
index 0000000..20f7ffb
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.cpp
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwaylandreadbackeglintegration.h"
+
+#include <QDebug>
+
+#include "qwaylandreadbackeglwindow.h"
+
+QWaylandReadbackEglIntegration::QWaylandReadbackEglIntegration(QWaylandDisplay *display)
+ : QWaylandGLIntegration()
+ , mWaylandDisplay(display)
+{
+ qDebug() << "Using Readback-EGL";
+ char *display_name = getenv("DISPLAY");
+ mDisplay = XOpenDisplay(display_name);
+ mScreen = XDefaultScreen(mDisplay);
+ mRootWindow = XDefaultRootWindow(mDisplay);
+ XSync(mDisplay, False);
+}
+
+QWaylandReadbackEglIntegration::~QWaylandReadbackEglIntegration()
+{
+ XCloseDisplay(mDisplay);
+}
+
+
+QWaylandGLIntegration *QWaylandGLIntegration::createGLIntegration(QWaylandDisplay *waylandDisplay)
+{
+ return new QWaylandReadbackEglIntegration(waylandDisplay);
+}
+
+void QWaylandReadbackEglIntegration::initialize()
+{
+ eglBindAPI(EGL_OPENGL_ES_API);
+ mEglDisplay = eglGetDisplay(mDisplay);
+ EGLint major, minor;
+ EGLBoolean initialized = eglInitialize(mEglDisplay,&major,&minor);
+ if (initialized) {
+ qDebug() << "EGL initialized successfully" << major << "," << minor;
+ } else {
+ qDebug() << "EGL could not initialized. All EGL and GL operations will fail";
+ }
+}
+
+QWaylandWindow * QWaylandReadbackEglIntegration::createEglWindow(QWidget *widget)
+{
+ return new QWaylandReadbackEglWindow(widget,this);
+}
+
+EGLDisplay QWaylandReadbackEglIntegration::eglDisplay()
+{
+ return mEglDisplay;
+}
+
+Window QWaylandReadbackEglIntegration::rootWindow() const
+{
+ return mRootWindow;
+}
+
+int QWaylandReadbackEglIntegration::depth() const
+{
+ return XDefaultDepth(mDisplay,mScreen);
+}
+
+Display * QWaylandReadbackEglIntegration::xDisplay() const
+{
+ return mDisplay;
+}
+
+QWaylandDisplay * QWaylandReadbackEglIntegration::waylandDisplay() const
+{
+ return mWaylandDisplay;
+}
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.h b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.h
new file mode 100644
index 0000000..84fa64f
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWAYLANDREADBACKEGLINTEGRATION_H
+#define QWAYLANDREADBACKEGLINTEGRATION_H
+
+#include "gl_integration/qwaylandglintegration.h"
+
+#include <QtCore/QTextStream>
+#include <QtCore/QDataStream>
+#include <QtCore/QMetaType>
+#include <QtCore/QVariant>
+#include <QtGui/QWidget>
+
+#include <X11/Xlib.h>
+
+#include <EGL/egl.h>
+
+class QWaylandReadbackEglIntegration : public QWaylandGLIntegration
+{
+public:
+ QWaylandReadbackEglIntegration(QWaylandDisplay *display);
+ ~QWaylandReadbackEglIntegration();
+
+ void initialize();
+ QWaylandWindow *createEglWindow(QWidget *widget);
+
+ QWaylandDisplay *waylandDisplay() const;
+ Display *xDisplay() const;
+ Window rootWindow() const;
+ int depth() const;
+
+ EGLDisplay eglDisplay();
+
+private:
+ QWaylandDisplay *mWaylandDisplay;
+ Display *mDisplay;
+ int mScreen;
+ Window mRootWindow;
+ EGLDisplay mEglDisplay;
+
+};
+
+#endif // QWAYLANDREADBACKEGLINTEGRATION_H
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglwindow.cpp b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglwindow.cpp
new file mode 100644
index 0000000..2ae212b
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglwindow.cpp
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwaylandreadbackeglwindow.h"
+
+#include "qwaylandreadbackeglcontext.h"
+
+QWaylandReadbackEglWindow::QWaylandReadbackEglWindow(QWidget *window, QWaylandReadbackEglIntegration *eglIntegration)
+ : QWaylandShmWindow(window)
+ , mEglIntegration(eglIntegration)
+ , mContext(0)
+{
+}
+
+QWaylandWindow::WindowType QWaylandReadbackEglWindow::windowType() const
+{
+ //We'r lying, maybe we should add a type, but for now it will do
+ //since this is primarly used by the windowsurface.
+ return QWaylandWindow::Egl;
+}
+
+QPlatformGLContext *QWaylandReadbackEglWindow::glContext() const
+{
+ if (!mContext) {
+ QWaylandReadbackEglWindow *that = const_cast<QWaylandReadbackEglWindow *>(this);
+ that->mContext = new QWaylandReadbackEglContext(mEglIntegration,that);
+ }
+ return mContext;
+}
+
+void QWaylandReadbackEglWindow::setGeometry(const QRect &rect)
+{
+ QPlatformWindow::setGeometry(rect);
+
+ if (mContext)
+ mContext->geometryChanged();
+}
+
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglwindow.h b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglwindow.h
new file mode 100644
index 0000000..453ad27
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglwindow.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWAYLANDREADBACKEGLWINDOW_H
+#define QWAYLANDREADBACKEGLWINDOW_H
+
+#include "qwaylandshmwindow.h"
+#include "qwaylandreadbackeglintegration.h"
+
+class QWaylandReadbackEglContext;
+
+class QWaylandReadbackEglWindow : public QWaylandShmWindow
+{
+public:
+ QWaylandReadbackEglWindow(QWidget *window, QWaylandReadbackEglIntegration *eglIntegration);
+
+ WindowType windowType() const;
+
+ QPlatformGLContext *glContext() const;
+
+ void setGeometry(const QRect &rect);
+
+private:
+ QWaylandReadbackEglIntegration *mEglIntegration;
+ QWaylandReadbackEglContext *mContext;
+};
+
+#endif // QWAYLANDREADBACKEGLWINDOW_H
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_egl/readback_egl.pri b/src/plugins/platforms/wayland/gl_integration/readback_egl/readback_egl.pri
new file mode 100644
index 0000000..0d8e01b
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/readback_egl/readback_egl.pri
@@ -0,0 +1,14 @@
+
+LIBS += -lX11 -lXext -lEGL
+
+HEADERS += \
+ $$PWD/qwaylandreadbackeglintegration.h \
+ $$PWD/qwaylandreadbackeglcontext.h \
+ $$PWD/qwaylandreadbackeglwindow.h \
+ $$PWD/../../../eglconvenience/qeglconvenience.h
+
+SOURCES += \
+ $$PWD/qwaylandreadbackeglintegration.cpp \
+ $$PWD/qwaylandreadbackeglwindow.cpp \
+ $$PWD/qwaylandreadbackeglcontext.cpp \
+ $$PWD/../../../eglconvenience/qeglconvenience.cpp
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.cpp b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.cpp
new file mode 100644
index 0000000..08c5cf6c
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.cpp
@@ -0,0 +1,163 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwaylandreadbackglxcontext.h"
+
+#include "qwaylandshmsurface.h"
+#include "qwaylandreadbackglxwindow.h"
+
+#include <QtCore/QDebug>
+
+static inline void qgl_byteSwapImage(QImage &img, GLenum pixel_type)
+{
+ const int width = img.width();
+ const int height = img.height();
+
+ if (pixel_type == GL_UNSIGNED_INT_8_8_8_8_REV
+ || (pixel_type == GL_UNSIGNED_BYTE && QSysInfo::ByteOrder == QSysInfo::LittleEndian))
+ {
+ for (int i = 0; i < height; ++i) {
+ uint *p = (uint *) img.scanLine(i);
+ for (int x = 0; x < width; ++x)
+ p[x] = ((p[x] << 16) & 0xff0000) | ((p[x] >> 16) & 0xff) | (p[x] & 0xff00ff00);
+ }
+ } else {
+ for (int i = 0; i < height; ++i) {
+ uint *p = (uint *) img.scanLine(i);
+ for (int x = 0; x < width; ++x)
+ p[x] = (p[x] << 8) | ((p[x] >> 24) & 0xff);
+ }
+ }
+}
+
+QWaylandReadbackGlxContext::QWaylandReadbackGlxContext(QWaylandReadbackGlxIntegration *glxIntegration, QWaylandReadbackGlxWindow *window)
+ : QPlatformGLContext()
+ , mGlxIntegration(glxIntegration)
+ , mWindow(window)
+ , mBuffer(0)
+ , mPixmap(0)
+ , mConfig(qglx_findConfig(glxIntegration->xDisplay(),glxIntegration->screen(),window->widget()->platformWindowFormat(),GLX_PIXMAP_BIT))
+ , mGlxPixmap(0)
+{
+ XVisualInfo *visualInfo = glXGetVisualFromFBConfig(glxIntegration->xDisplay(),mConfig);
+ mContext = glXCreateContext(glxIntegration->xDisplay(),visualInfo,0,TRUE);
+
+ geometryChanged();
+}
+
+void QWaylandReadbackGlxContext::makeCurrent()
+{
+ QPlatformGLContext::makeCurrent();
+
+ glXMakeCurrent(mGlxIntegration->xDisplay(),mGlxPixmap,mContext);
+}
+
+void QWaylandReadbackGlxContext::doneCurrent()
+{
+ QPlatformGLContext::doneCurrent();
+}
+
+void QWaylandReadbackGlxContext::swapBuffers()
+{
+ if (QPlatformGLContext::currentContext() != this) {
+ makeCurrent();
+ }
+
+ QSize size = mWindow->geometry().size();
+
+ QImage img(size,QImage::Format_ARGB32);
+ const uchar *constBits = img.bits();
+ void *pixels = const_cast<uchar *>(constBits);
+
+ glReadPixels(0,0, size.width(), size.height(), GL_RGBA,GL_UNSIGNED_BYTE, pixels);
+
+ img = img.mirrored();
+ qgl_byteSwapImage(img,GL_UNSIGNED_INT_8_8_8_8_REV);
+ constBits = img.bits();
+
+ const uchar *constDstBits = mBuffer->image()->bits();
+ uchar *dstBits = const_cast<uchar *>(constDstBits);
+ memcpy(dstBits,constBits,(img.width()*4) * img.height());
+
+
+ mWindow->damage(QRegion(QRect(QPoint(0,0),size)));
+ mWindow->waitForFrameSync();
+
+}
+
+void * QWaylandReadbackGlxContext::getProcAddress(const QString &procName)
+{
+ return (void *) glXGetProcAddress(reinterpret_cast<GLubyte *>(procName.toLatin1().data()));
+}
+
+QPlatformWindowFormat QWaylandReadbackGlxContext::platformWindowFormat() const
+{
+ return qglx_platformWindowFromGLXFBConfig(mGlxIntegration->xDisplay(),mConfig,mContext);
+}
+
+void QWaylandReadbackGlxContext::geometryChanged()
+{
+ QSize size(mWindow->geometry().size());
+ if (size.isEmpty()) {
+ //QGLWidget wants a context for a window without geometry
+ size = QSize(1,1);
+ }
+
+ mWindow->waitForFrameSync();
+
+ delete mBuffer;
+ //XFreePixmap deletes the glxPixmap as well
+ if (mPixmap) {
+ XFreePixmap(mGlxIntegration->xDisplay(),mPixmap);
+ }
+
+ mBuffer = new QWaylandShmBuffer(mGlxIntegration->waylandDisplay(),size,QImage::Format_ARGB32);
+ mWindow->attach(mBuffer);
+ int depth = XDefaultDepth(mGlxIntegration->xDisplay(),mGlxIntegration->screen());
+ mPixmap = XCreatePixmap(mGlxIntegration->xDisplay(),mGlxIntegration->rootWindow(),size.width(),size.height(),depth);
+ XSync(mGlxIntegration->xDisplay(),False);
+
+ mGlxPixmap = glXCreatePixmap(mGlxIntegration->xDisplay(),mConfig,mPixmap,0);
+
+ if (!mGlxPixmap) {
+ qDebug() << "Could not make egl surface out of pixmap :(";
+ }
+}
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.h b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.h
new file mode 100644
index 0000000..5fafcf0
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.h
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWAYLANDREADBACKGLXCONTEXT_H
+#define QWAYLANDREADBACKGLXCONTEXT_H
+
+#include <QPlatformGLContext>
+
+#include "qwaylandreadbackglxintegration.h"
+
+#include "qglxconvenience.h"
+
+class QWaylandReadbackGlxWindow;
+class QWaylandShmBuffer;
+
+class QWaylandReadbackGlxContext : public QPlatformGLContext
+{
+public:
+ QWaylandReadbackGlxContext(QWaylandReadbackGlxIntegration *glxIntegration, QWaylandReadbackGlxWindow *window);
+
+ void makeCurrent();
+ void doneCurrent();
+ void swapBuffers();
+ void* getProcAddress(const QString& procName);
+
+ QPlatformWindowFormat platformWindowFormat() const;
+
+ void geometryChanged();
+
+private:
+ QWaylandReadbackGlxIntegration *mGlxIntegration;
+ QWaylandReadbackGlxWindow *mWindow;
+ QWaylandShmBuffer *mBuffer;
+
+ Pixmap mPixmap;
+ GLXFBConfig mConfig;
+ GLXContext mContext;
+ GLXPixmap mGlxPixmap;
+};
+
+#endif // QWAYLANDREADBACKGLXCONTEXT_H
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.cpp b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.cpp
new file mode 100644
index 0000000..4651f0c
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.cpp
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwaylandreadbackglxintegration.h"
+
+#include "qwaylandreadbackglxwindow.h"
+
+#include <QtCore/QDebug>
+
+QWaylandReadbackGlxIntegration::QWaylandReadbackGlxIntegration(QWaylandDisplay * waylandDispaly)
+ : QWaylandGLIntegration()
+ , mWaylandDisplay(waylandDispaly)
+{
+ qDebug() << "Using Readback-GLX";
+ char *display_name = getenv("DISPLAY");
+ mDisplay = XOpenDisplay(display_name);
+ mScreen = XDefaultScreen(mDisplay);
+ mRootWindow = XDefaultRootWindow(mDisplay);
+ XSync(mDisplay, False);
+}
+
+QWaylandReadbackGlxIntegration::~QWaylandReadbackGlxIntegration()
+{
+ XCloseDisplay(mDisplay);
+}
+
+void QWaylandReadbackGlxIntegration::initialize()
+{
+}
+
+QWaylandWindow * QWaylandReadbackGlxIntegration::createEglWindow(QWidget *widget)
+{
+ return new QWaylandReadbackGlxWindow(widget,this);
+}
+
+QWaylandGLIntegration * QWaylandGLIntegration::createGLIntegration(QWaylandDisplay *waylandDisplay)
+{
+ return new QWaylandReadbackGlxIntegration(waylandDisplay);
+}
+
+Display * QWaylandReadbackGlxIntegration::xDisplay() const
+{
+ return mDisplay;
+}
+
+int QWaylandReadbackGlxIntegration::screen() const
+{
+ return mScreen;
+}
+
+Window QWaylandReadbackGlxIntegration::rootWindow() const
+{
+ return mRootWindow;
+}
+
+QWaylandDisplay * QWaylandReadbackGlxIntegration::waylandDisplay() const
+{
+ return mWaylandDisplay;
+}
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.h b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.h
new file mode 100644
index 0000000..9056393
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWAYLANDREADBACKGLXINTEGRATION_H
+#define QWAYLANDREADBACKGLXINTEGRATION_H
+
+#include "gl_integration/qwaylandglintegration.h"
+
+#include <QtCore/QTextStream>
+#include <QtCore/QDataStream>
+#include <QtCore/QMetaType>
+#include <QtCore/QVariant>
+#include <QtGui/QWidget>
+
+#include <X11/Xlib.h>
+
+class QWaylandReadbackGlxIntegration : public QWaylandGLIntegration
+{
+public:
+ QWaylandReadbackGlxIntegration(QWaylandDisplay * waylandDispaly);
+ ~QWaylandReadbackGlxIntegration();
+
+ void initialize();
+
+ QWaylandWindow *createEglWindow(QWidget *widget);
+
+ QWaylandDisplay *waylandDisplay() const;
+
+ Display *xDisplay() const;
+ int screen() const;
+ Window rootWindow() const;
+
+private:
+ QWaylandDisplay *mWaylandDisplay;
+
+ Display *mDisplay;
+ int mScreen;
+ Window mRootWindow;
+
+};
+
+#endif // QWAYLANDREADBACKGLXINTEGRATION_H
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.cpp b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.cpp
new file mode 100644
index 0000000..ca1603c
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.cpp
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwaylandreadbackglxwindow.h"
+
+QWaylandReadbackGlxWindow::QWaylandReadbackGlxWindow(QWidget *window, QWaylandReadbackGlxIntegration *glxIntegration)
+ : QWaylandShmWindow(window)
+ , mGlxIntegration(glxIntegration)
+ , mContext(0)
+{
+}
+
+QWaylandWindow::WindowType QWaylandReadbackGlxWindow::windowType() const
+{
+ //yeah. this type needs a new name
+ return QWaylandWindow::Egl;
+}
+
+QPlatformGLContext * QWaylandReadbackGlxWindow::glContext() const
+{
+ if (!mContext) {
+ QWaylandReadbackGlxWindow *that = const_cast<QWaylandReadbackGlxWindow *>(this);
+ that->mContext = new QWaylandReadbackGlxContext(mGlxIntegration,that);
+ }
+ return mContext;
+}
+
+void QWaylandReadbackGlxWindow::setGeometry(const QRect &rect)
+{
+ QWaylandShmWindow::setGeometry(rect);
+
+ if (mContext) {
+ mContext->geometryChanged();
+ }
+}
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.h b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.h
new file mode 100644
index 0000000..4d7bb3e
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.h
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWAYLANDREADBACKGLXWINDOW_H
+#define QWAYLANDREADBACKGLXWINDOW_H
+
+#include "qwaylandshmwindow.h"
+#include "qwaylandreadbackglxintegration.h"
+#include "qwaylandreadbackglxcontext.h"
+
+class QWaylandReadbackGlxWindow : public QWaylandShmWindow
+{
+public:
+ QWaylandReadbackGlxWindow(QWidget *window, QWaylandReadbackGlxIntegration *glxIntegration);
+ WindowType windowType() const;
+
+ QPlatformGLContext *glContext() const;
+
+ void setGeometry(const QRect &rect);
+
+private:
+ QWaylandReadbackGlxIntegration *mGlxIntegration;
+ QWaylandReadbackGlxContext *mContext;
+
+};
+
+#endif // QWAYLANDREADBACKGLXWINDOW_H
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_glx/readback_glx.pri b/src/plugins/platforms/wayland/gl_integration/readback_glx/readback_glx.pri
new file mode 100644
index 0000000..f8ea005
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/readback_glx/readback_glx.pri
@@ -0,0 +1,12 @@
+include (../../../glxconvenience/glxconvenience.pri)
+HEADERS += \
+ $$PWD/qwaylandreadbackglxintegration.h \
+ $$PWD/qwaylandreadbackglxwindow.h \
+ $$PWD/qwaylandreadbackglxcontext.h
+
+SOURCES += \
+ $$PWD/qwaylandreadbackglxintegration.cpp \
+ $$PWD/qwaylandreadbackglxwindow.cpp \
+ $$PWD/qwaylandreadbackglxcontext.cpp
+
+LIBS += -lX11
diff --git a/src/plugins/platforms/wayland/qwaylandinclude.h b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglinclude.h
index 0135251..5dc2add 100644
--- a/src/plugins/platforms/wayland/qwaylandinclude.h
+++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglinclude.h
@@ -4,7 +4,7 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of the config.tests of the Qt Toolkit.
+** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
@@ -39,12 +39,11 @@
**
****************************************************************************/
-#ifndef QWAYLANDINCLUDE_H
-#define QWAYLANDINCLUDE_H
+#ifndef QWAYLANDEGLINCLUDE_H
+#define QWAYLANDEGLINCLUDE_H
#include <wayland-client.h>
-#ifdef QT_WAYLAND_GL_SUPPORT
#include <wayland-egl.h>
#define GL_GLEXT_PROTOTYPES
@@ -52,12 +51,7 @@
#include <GLES2/gl2ext.h>
#define EGL_EGLEXT_PROTOTYPES
- #include <EGL/egl.h>
- #include <EGL/eglext.h>
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
-#else
-typedef void* EGLDisplay;
-typedef void* EGLConfig;
-#endif
-
-#endif // QWAYLANDINCLUDE_H
+#endif // QWAYLANDEGLINCLUDE_H
diff --git a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.cpp b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.cpp
new file mode 100644
index 0000000..39e7be5
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.cpp
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwaylandeglintegration.h"
+
+#include "gl_integration/qwaylandglintegration.h"
+
+#include "qwaylandeglwindow.h"
+
+#include <QtCore/QDebug>
+
+QWaylandEglIntegration::QWaylandEglIntegration(struct wl_display *waylandDisplay)
+ : mWaylandDisplay(waylandDisplay)
+ , mNativeEglDisplay(wl_egl_display_create(mWaylandDisplay))
+{
+ qDebug() << "Using Wayland-EGL";
+}
+
+
+QWaylandEglIntegration::~QWaylandEglIntegration()
+{
+ eglTerminate(mEglDisplay);
+}
+
+void QWaylandEglIntegration::initialize()
+{
+ EGLint major,minor;
+ mEglDisplay = eglGetDisplay((EGLNativeDisplayType)mNativeEglDisplay);
+ if (mEglDisplay == NULL) {
+ qWarning("EGL not available");
+ } else {
+ if (!eglInitialize(mEglDisplay, &major, &minor)) {
+ qWarning("failed to initialize EGL display");
+ return;
+ }
+ }
+}
+
+QWaylandWindow *QWaylandEglIntegration::createEglWindow(QWidget *window)
+{
+ return new QWaylandEglWindow(window);
+}
+
+EGLDisplay QWaylandEglIntegration::eglDisplay() const
+{
+ return mEglDisplay;
+}
+
+wl_egl_display * QWaylandEglIntegration::nativeDisplay() const
+{
+ return mNativeEglDisplay;
+}
+
+QWaylandGLIntegration *QWaylandGLIntegration::createGLIntegration(QWaylandDisplay *waylandDisplay)
+{
+ return new QWaylandEglIntegration(waylandDisplay->wl_display());
+}
diff --git a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.h b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.h
new file mode 100644
index 0000000..bf4c3fe
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWAYLANDEGLINTEGRATION_H
+#define QWAYLANDEGLINTEGRATION_H
+
+#include "gl_integration/qwaylandglintegration.h"
+
+#include "qwaylandeglinclude.h"
+
+class QWaylandWindow;
+class QWidget;
+
+class QWaylandEglIntegration : public QWaylandGLIntegration
+{
+public:
+ QWaylandEglIntegration(struct wl_display *waylandDisplay);
+ ~QWaylandEglIntegration();
+
+ void initialize();
+
+ QWaylandWindow *createEglWindow(QWidget *window);
+
+ EGLDisplay eglDisplay() const;
+ struct wl_egl_display *nativeDisplay() const;
+private:
+ struct wl_display *mWaylandDisplay;
+
+ EGLDisplay mEglDisplay;
+ struct wl_egl_display *mNativeEglDisplay;
+
+
+};
+
+#endif // QWAYLANDEGLINTEGRATION_H
diff --git a/src/plugins/platforms/wayland/qwaylandeglwindow.cpp b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.cpp
index ed54bb9..d7cf0a5 100644
--- a/src/plugins/platforms/wayland/qwaylandeglwindow.cpp
+++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.cpp
@@ -4,7 +4,7 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of the config.tests of the Qt Toolkit.
+** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
@@ -43,21 +43,20 @@
#include "qwaylandscreen.h"
#include "qwaylandglcontext.h"
-#include "qwaylandinclude.h"
QWaylandEglWindow::QWaylandEglWindow(QWidget *window)
: QWaylandWindow(window)
, mGLContext(0)
, mWaylandEglWindow(0)
{
+ mEglIntegration = static_cast<QWaylandEglIntegration *>(mDisplay->eglIntegration());
//super creates a new surface
newSurfaceCreated();
}
QWaylandEglWindow::~QWaylandEglWindow()
{
- if (mGLContext)
- delete mGLContext;
+ delete mGLContext;
}
QWaylandWindow::WindowType QWaylandEglWindow::windowType() const
@@ -84,10 +83,10 @@ QPlatformGLContext * QWaylandEglWindow::glContext() const
{
if (!mGLContext) {
QWaylandEglWindow *that = const_cast<QWaylandEglWindow *>(this);
- that->mGLContext = new QWaylandGLContext(that->mDisplay,widget()->platformWindowFormat());
+ that->mGLContext = new QWaylandGLContext(mEglIntegration->eglDisplay(),widget()->platformWindowFormat());
EGLNativeWindowType window(reinterpret_cast<EGLNativeWindowType>(mWaylandEglWindow));
- EGLSurface surface = eglCreateWindowSurface(mDisplay->eglDisplay(),mGLContext->eglConfig(),window,NULL);
+ EGLSurface surface = eglCreateWindowSurface(mEglIntegration->eglDisplay(),mGLContext->eglConfig(),window,NULL);
that->mGLContext->setEglSurface(surface);
}
@@ -104,10 +103,10 @@ void QWaylandEglWindow::newSurfaceCreated()
if (!size.isValid())
size = QSize(0,0);
- mWaylandEglWindow = wl_egl_window_create(mDisplay->nativeDisplay(),mSurface,size.width(),size.height(),visual);
+ mWaylandEglWindow = wl_egl_window_create(mEglIntegration->nativeDisplay(),mSurface,size.width(),size.height(),visual);
if (mGLContext) {
EGLNativeWindowType window(reinterpret_cast<EGLNativeWindowType>(mWaylandEglWindow));
- EGLSurface surface = eglCreateWindowSurface(mDisplay->eglDisplay(),mGLContext->eglConfig(),window,NULL);
+ EGLSurface surface = eglCreateWindowSurface(mEglIntegration->eglDisplay(),mGLContext->eglConfig(),window,NULL);
mGLContext->setEglSurface(surface);
}
}
diff --git a/src/plugins/platforms/wayland/qwaylandeglwindow.h b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.h
index 4b3bb5b..549d039 100644
--- a/src/plugins/platforms/wayland/qwaylandeglwindow.h
+++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.h
@@ -4,7 +4,7 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of the config.tests of the Qt Toolkit.
+** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
@@ -43,6 +43,8 @@
#define QWAYLANDEGLWINDOW_H
#include "qwaylandwindow.h"
+#include "qwaylandeglinclude.h"
+#include "qwaylandeglintegration.h"
class QWaylandGLContext;
@@ -58,6 +60,7 @@ public:
protected:
void newSurfaceCreated();
private:
+ QWaylandEglIntegration *mEglIntegration;
QWaylandGLContext *mGLContext;
struct wl_egl_window *mWaylandEglWindow;
EGLConfig mConfig;
diff --git a/src/plugins/platforms/wayland/qwaylandglcontext.cpp b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandglcontext.cpp
index 3720567..d293019 100644
--- a/src/plugins/platforms/wayland/qwaylandglcontext.cpp
+++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandglcontext.cpp
@@ -43,37 +43,22 @@
#include "qwaylanddisplay.h"
#include "qwaylandwindow.h"
-#include "qwaylanddrmsurface.h"
-#include "../eglconvenience/qeglconvenience.h"
+#include "../../../eglconvenience/qeglconvenience.h"
#include <QtGui/QPlatformGLContext>
#include <QtGui/QPlatformWindowFormat>
+#include <QtCore/QMutex>
-Q_GLOBAL_STATIC(QMutex,qt_defaultSharedContextMutex)
-
-QWaylandGLContext::QWaylandGLContext(QWaylandDisplay *wd, const QPlatformWindowFormat &format)
+QWaylandGLContext::QWaylandGLContext(EGLDisplay eglDisplay, const QPlatformWindowFormat &format)
: QPlatformGLContext()
- , mDisplay(wd)
+ , mEglDisplay(eglDisplay)
, mSurface(EGL_NO_SURFACE)
- , mConfig(q_configFromQPlatformWindowFormat(mDisplay->eglDisplay(),format,true))
- , mFormat(qt_qPlatformWindowFormatFromConfig(mDisplay->eglDisplay(),mConfig))
+ , mConfig(q_configFromQPlatformWindowFormat(mEglDisplay,format,true))
+ , mFormat(qt_qPlatformWindowFormatFromConfig(mEglDisplay,mConfig))
{
QPlatformGLContext *sharePlatformContext = 0;
- if (format.useDefaultSharedContext()) {
- if (!QPlatformGLContext::defaultSharedContext()) {
- if (qt_defaultSharedContextMutex()->tryLock()){
- createDefaultSharedContex(wd);
- qt_defaultSharedContextMutex()->unlock();
- } else {
- qt_defaultSharedContextMutex()->lock(); //wait to the the shared context is created
- qt_defaultSharedContextMutex()->unlock();
- }
- }
- sharePlatformContext = QPlatformGLContext::defaultSharedContext();
- } else {
- sharePlatformContext = format.sharedGLContext();
- }
+ sharePlatformContext = format.sharedGLContext();
mFormat.setSharedContext(sharePlatformContext);
EGLContext shareEGLContext = EGL_NO_CONTEXT;
if (sharePlatformContext)
@@ -86,13 +71,13 @@ QWaylandGLContext::QWaylandGLContext(QWaylandDisplay *wd, const QPlatformWindowF
eglContextAttrs.append(2);
eglContextAttrs.append(EGL_NONE);
- mContext = eglCreateContext(mDisplay->eglDisplay(), mConfig,
+ mContext = eglCreateContext(mEglDisplay, mConfig,
shareEGLContext, eglContextAttrs.constData());
}
QWaylandGLContext::QWaylandGLContext()
: QPlatformGLContext()
- , mDisplay(0)
+ , mEglDisplay(0)
, mContext(EGL_NO_CONTEXT)
, mSurface(EGL_NO_SURFACE)
, mConfig(0)
@@ -100,7 +85,7 @@ QWaylandGLContext::QWaylandGLContext()
QWaylandGLContext::~QWaylandGLContext()
{
- eglDestroyContext(mDisplay->eglDisplay(),mContext);
+ eglDestroyContext(mEglDisplay,mContext);
}
void QWaylandGLContext::makeCurrent()
@@ -109,18 +94,18 @@ void QWaylandGLContext::makeCurrent()
if (mSurface == EGL_NO_SURFACE) {
qWarning("makeCurrent with EGL_NO_SURFACE");
}
- eglMakeCurrent(mDisplay->eglDisplay(), mSurface, mSurface, mContext);
+ eglMakeCurrent(mEglDisplay, mSurface, mSurface, mContext);
}
void QWaylandGLContext::doneCurrent()
{
QPlatformGLContext::doneCurrent();
- eglMakeCurrent(mDisplay->eglDisplay(), EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
}
void QWaylandGLContext::swapBuffers()
{
- eglSwapBuffers(mDisplay->eglDisplay(),mSurface);
+ eglSwapBuffers(mEglDisplay,mSurface);
}
void *QWaylandGLContext::getProcAddress(const QString &string)
@@ -128,20 +113,6 @@ void *QWaylandGLContext::getProcAddress(const QString &string)
return (void *) eglGetProcAddress(string.toLatin1().data());
}
-void QWaylandGLContext::createDefaultSharedContex(QWaylandDisplay *display)
-{
- QVector<EGLint> eglContextAttrs;
- eglContextAttrs.append(EGL_CONTEXT_CLIENT_VERSION);
- eglContextAttrs.append(2);
- eglContextAttrs.append(EGL_NONE);
-
- QWaylandGLContext *defaultSharedContext = new QWaylandGLContext;
- defaultSharedContext->mDisplay = display;
- defaultSharedContext->mContext = eglCreateContext(mDisplay->eglDisplay(),mConfig,
- EGL_NO_CONTEXT, eglContextAttrs.constData());
- QPlatformGLContext::setDefaultSharedContext(defaultSharedContext);
-}
-
void QWaylandGLContext::setEglSurface(EGLSurface surface)
{
doneCurrent();
diff --git a/src/plugins/platforms/wayland/qwaylandglcontext.h b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandglcontext.h
index dd319fd..76caffa 100644
--- a/src/plugins/platforms/wayland/qwaylandglcontext.h
+++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandglcontext.h
@@ -46,14 +46,14 @@
#include <QtGui/QPlatformGLContext>
-class QWaylandWindow;
-class QWaylandDrmWindowSurface;
+#include "qwaylandeglinclude.h"
-#include "qwaylandinclude.h"
+class QWaylandWindow;
+class QWaylandGLWindowSurface;
class QWaylandGLContext : public QPlatformGLContext {
public:
- QWaylandGLContext(QWaylandDisplay *wd, const QPlatformWindowFormat &format);
+ QWaylandGLContext(EGLDisplay eglDisplay, const QPlatformWindowFormat &format);
~QWaylandGLContext();
void makeCurrent();
void doneCurrent();
@@ -65,14 +65,13 @@ public:
void setEglSurface(EGLSurface surface);
EGLConfig eglConfig() const;
private:
- QWaylandDisplay *mDisplay;
+ EGLDisplay mEglDisplay;
EGLContext mContext;
EGLSurface mSurface;
EGLConfig mConfig;
QPlatformWindowFormat mFormat;
- void createDefaultSharedContex(QWaylandDisplay *display);
QWaylandGLContext();
};
diff --git a/src/plugins/platforms/wayland/gl_integration/wayland_egl/wayland_egl.pri b/src/plugins/platforms/wayland/gl_integration/wayland_egl/wayland_egl.pri
new file mode 100644
index 0000000..bc97864
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/wayland_egl.pri
@@ -0,0 +1,12 @@
+LIBS += -lwayland-egl -lEGL
+INCLUDEPATH += $$PWD
+SOURCES += $$PWD/qwaylandeglintegration.cpp \
+ $$PWD/qwaylandglcontext.cpp \
+ $$PWD/qwaylandeglwindow.cpp \
+ $$PWD/../../../eglconvenience/qeglconvenience.cpp
+
+HEADERS += $$PWD/qwaylandeglintegration.h \
+ $$PWD/qwaylandglcontext.h \
+ $$PWD/qwaylandeglwindow.h \
+ $$PWD/../../../eglconvenience/qeglconvenience.h \
+ gl_integration/wayland_egl/qwaylandeglinclude.h
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.cpp b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.cpp
new file mode 100644
index 0000000..92acf75
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.cpp
@@ -0,0 +1,169 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwaylandxcompositeeglcontext.h"
+
+#include "qwaylandxcompositeeglwindow.h"
+#include "qwaylandxcompositebuffer.h"
+
+#include "wayland-xcomposite-client-protocol.h"
+#include <QtCore/QDebug>
+
+#include "qeglconvenience.h"
+#include "qxlibeglintegration.h"
+
+#include <X11/extensions/Xcomposite.h>
+
+QWaylandXCompositeEGLContext::QWaylandXCompositeEGLContext(QWaylandXCompositeEGLIntegration *glxIntegration, QWaylandXCompositeEGLWindow *window)
+ : QPlatformGLContext()
+ , mEglIntegration(glxIntegration)
+ , mWindow(window)
+ , mBuffer(0)
+ , mXWindow(0)
+ , mConfig(q_configFromQPlatformWindowFormat(glxIntegration->eglDisplay(),window->widget()->platformWindowFormat(),true,EGL_WINDOW_BIT))
+ , mWaitingForSync(false)
+{
+ QVector<EGLint> eglContextAttrs;
+ eglContextAttrs.append(EGL_CONTEXT_CLIENT_VERSION); eglContextAttrs.append(2);
+ eglContextAttrs.append(EGL_NONE);
+
+ mContext = eglCreateContext(glxIntegration->eglDisplay(),mConfig,EGL_NO_CONTEXT,eglContextAttrs.constData());
+ if (mContext == EGL_NO_CONTEXT) {
+ qFatal("failed to find context");
+ }
+
+ geometryChanged();
+}
+
+void QWaylandXCompositeEGLContext::makeCurrent()
+{
+ QPlatformGLContext::makeCurrent();
+
+ eglMakeCurrent(mEglIntegration->eglDisplay(),mEglWindowSurface,mEglWindowSurface,mContext);
+}
+
+void QWaylandXCompositeEGLContext::doneCurrent()
+{
+ QPlatformGLContext::doneCurrent();
+ eglMakeCurrent(mEglIntegration->eglDisplay(),EGL_NO_SURFACE,EGL_NO_SURFACE,EGL_NO_CONTEXT);
+}
+
+void QWaylandXCompositeEGLContext::swapBuffers()
+{
+ QSize size = mWindow->geometry().size();
+
+ eglSwapBuffers(mEglIntegration->eglDisplay(),mEglWindowSurface);
+ mWindow->damage(QRegion(QRect(QPoint(0,0),size)));
+ mWindow->waitForFrameSync();
+}
+
+void * QWaylandXCompositeEGLContext::getProcAddress(const QString &procName)
+{
+ return (void *)eglGetProcAddress(qPrintable(procName));
+}
+
+QPlatformWindowFormat QWaylandXCompositeEGLContext::platformWindowFormat() const
+{
+ return qt_qPlatformWindowFormatFromConfig(mEglIntegration->eglDisplay(),mConfig);
+}
+
+void QWaylandXCompositeEGLContext::sync_function(void *data)
+{
+ QWaylandXCompositeEGLContext *that = static_cast<QWaylandXCompositeEGLContext *>(data);
+ that->mWaitingForSync = false;
+}
+
+void QWaylandXCompositeEGLContext::geometryChanged()
+{
+ QSize size(mWindow->geometry().size());
+ if (size.isEmpty()) {
+ //QGLWidget wants a context for a window without geometry
+ size = QSize(1,1);
+ }
+
+ delete mBuffer;
+ //XFreePixmap deletes the glxPixmap as well
+ if (mXWindow) {
+ XDestroyWindow(mEglIntegration->xDisplay(),mXWindow);
+ }
+
+ VisualID visualId = QXlibEglIntegration::getCompatibleVisualId(mEglIntegration->xDisplay(),mEglIntegration->eglDisplay(),mConfig);
+
+ XVisualInfo visualInfoTemplate;
+ memset(&visualInfoTemplate, 0, sizeof(XVisualInfo));
+ visualInfoTemplate.visualid = visualId;
+
+ int matchingCount = 0;
+ XVisualInfo *visualInfo = XGetVisualInfo(mEglIntegration->xDisplay(), VisualIDMask, &visualInfoTemplate, &matchingCount);
+
+ Colormap cmap = XCreateColormap(mEglIntegration->xDisplay(),mEglIntegration->rootWindow(),visualInfo->visual,AllocNone);
+
+ XSetWindowAttributes a;
+ a.colormap = cmap;
+ mXWindow = XCreateWindow(mEglIntegration->xDisplay(), mEglIntegration->rootWindow(),0, 0, size.width(), size.height(),
+ 0, visualInfo->depth, InputOutput, visualInfo->visual,
+ CWColormap, &a);
+
+ XCompositeRedirectWindow(mEglIntegration->xDisplay(), mXWindow, CompositeRedirectManual);
+ XMapWindow(mEglIntegration->xDisplay(), mXWindow);
+
+ mEglWindowSurface = eglCreateWindowSurface(mEglIntegration->eglDisplay(),mConfig,mXWindow,0);
+ if (mEglWindowSurface == EGL_NO_SURFACE) {
+ qFatal("Could not make eglsurface");
+ }
+
+ XSync(mEglIntegration->xDisplay(),False);
+ mBuffer = new QWaylandXCompositeBuffer(mEglIntegration->waylandXComposite(),
+ (uint32_t)mXWindow,
+ size,
+ mEglIntegration->waylandDisplay()->argbVisual());
+ mWindow->attach(mBuffer);
+ wl_display_sync_callback(mEglIntegration->waylandDisplay()->wl_display(),
+ QWaylandXCompositeEGLContext::sync_function,
+ this);
+
+ mWaitingForSync = true;
+ wl_display_sync(mEglIntegration->waylandDisplay()->wl_display(),0);
+ mEglIntegration->waylandDisplay()->flushRequests();
+ while (mWaitingForSync) {
+ mEglIntegration->waylandDisplay()->readEvents();
+ }
+}
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.h b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.h
new file mode 100644
index 0000000..f0693d4
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWAYLANDXCOMPOSITEEGLCONTEXT_H
+#define QWAYLANDXCOMPOSITEEGLCONTEXT_H
+
+#include <QtGui/QPlatformGLContext>
+
+#include <QtCore/QWaitCondition>
+
+#include "qwaylandbuffer.h"
+#include "qwaylandxcompositeeglintegration.h"
+
+class QWaylandXCompositeEGLWindow;
+
+class QWaylandXCompositeEGLContext : public QPlatformGLContext
+{
+public:
+ QWaylandXCompositeEGLContext(QWaylandXCompositeEGLIntegration *glxIntegration, QWaylandXCompositeEGLWindow *window);
+
+ void makeCurrent();
+ void doneCurrent();
+ void swapBuffers();
+ void* getProcAddress(const QString& procName);
+
+ QPlatformWindowFormat platformWindowFormat() const;
+
+ void geometryChanged();
+
+private:
+ QWaylandXCompositeEGLIntegration *mEglIntegration;
+ QWaylandXCompositeEGLWindow *mWindow;
+ QWaylandBuffer *mBuffer;
+
+ Window mXWindow;
+ EGLConfig mConfig;
+ EGLContext mContext;
+ EGLSurface mEglWindowSurface;
+
+ static void sync_function(void *data);
+ bool mWaitingForSync;
+};
+
+#endif // QWAYLANDXCOMPOSITEEGLCONTEXT_H
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.cpp b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.cpp
new file mode 100644
index 0000000..95b4112
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.cpp
@@ -0,0 +1,139 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwaylandxcompositeeglintegration.h"
+
+#include "qwaylandxcompositeeglwindow.h"
+
+#include <QtCore/QDebug>
+
+#include "wayland-xcomposite-client-protocol.h"
+
+QWaylandGLIntegration * QWaylandGLIntegration::createGLIntegration(QWaylandDisplay *waylandDisplay)
+{
+ return new QWaylandXCompositeEGLIntegration(waylandDisplay);
+}
+
+QWaylandXCompositeEGLIntegration::QWaylandXCompositeEGLIntegration(QWaylandDisplay * waylandDispaly)
+ : QWaylandGLIntegration()
+ , mWaylandDisplay(waylandDispaly)
+{
+ qDebug() << "Using XComposite-EGL";
+ wl_display_add_global_listener(mWaylandDisplay->wl_display(), QWaylandXCompositeEGLIntegration::wlDisplayHandleGlobal,
+ this);
+}
+
+QWaylandXCompositeEGLIntegration::~QWaylandXCompositeEGLIntegration()
+{
+ XCloseDisplay(mDisplay);
+}
+
+void QWaylandXCompositeEGLIntegration::initialize()
+{
+}
+
+QWaylandWindow * QWaylandXCompositeEGLIntegration::createEglWindow(QWidget *widget)
+{
+ return new QWaylandXCompositeEGLWindow(widget,this);
+}
+
+Display * QWaylandXCompositeEGLIntegration::xDisplay() const
+{
+ return mDisplay;
+}
+
+EGLDisplay QWaylandXCompositeEGLIntegration::eglDisplay() const
+{
+ return mEglDisplay;
+}
+
+int QWaylandXCompositeEGLIntegration::screen() const
+{
+ return mScreen;
+}
+
+Window QWaylandXCompositeEGLIntegration::rootWindow() const
+{
+ return mRootWindow;
+}
+
+QWaylandDisplay * QWaylandXCompositeEGLIntegration::waylandDisplay() const
+{
+ return mWaylandDisplay;
+}
+wl_xcomposite * QWaylandXCompositeEGLIntegration::waylandXComposite() const
+{
+ return mWaylandComposite;
+}
+
+const struct wl_xcomposite_listener QWaylandXCompositeEGLIntegration::xcomposite_listener = {
+ QWaylandXCompositeEGLIntegration::rootInformation
+};
+
+void QWaylandXCompositeEGLIntegration::wlDisplayHandleGlobal(wl_display *display, uint32_t id, const char *interface, uint32_t version, void *data)
+{
+ Q_UNUSED(version);
+ if (strcmp(interface, "xcomposite") == 0) {
+ QWaylandXCompositeEGLIntegration *integration = static_cast<QWaylandXCompositeEGLIntegration *>(data);
+ integration->mWaylandComposite = wl_xcomposite_create(display,id);
+ wl_xcomposite_add_listener(integration->mWaylandComposite,&xcomposite_listener,integration);
+ }
+
+}
+
+void QWaylandXCompositeEGLIntegration::rootInformation(void *data, wl_xcomposite *xcomposite, const char *display_name, uint32_t root_window)
+{
+ Q_UNUSED(xcomposite);
+ QWaylandXCompositeEGLIntegration *integration = static_cast<QWaylandXCompositeEGLIntegration *>(data);
+
+ integration->mDisplay = XOpenDisplay(display_name);
+ integration->mRootWindow = (Window) root_window;
+ integration->mScreen = XDefaultScreen(integration->mDisplay);
+ integration->mEglDisplay = eglGetDisplay(integration->mDisplay);
+ eglBindAPI(EGL_OPENGL_ES_API);
+ EGLint minor,major;
+ if (!eglInitialize(integration->mEglDisplay,&major,&minor)) {
+ qFatal("Failed to initialize EGL");
+ }
+ eglSwapInterval(integration->eglDisplay(),0);
+ qDebug() << "ROOT INFORMATION" << integration->mDisplay << integration->mRootWindow << integration->mScreen;
+}
+
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.h b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.h
new file mode 100644
index 0000000..590ae37
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.h
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWAYLANDXCOMPOSITEEGLINTEGRATION_H
+#define QWAYLANDXCOMPOSITEEGLINTEGRATION_H
+
+#include "gl_integration/qwaylandglintegration.h"
+#include "wayland-client.h"
+
+#include <QtCore/QTextStream>
+#include <QtCore/QDataStream>
+#include <QtCore/QMetaType>
+#include <QtCore/QVariant>
+#include <QtGui/QWidget>
+
+#include <QWaitCondition>
+
+#include <X11/Xlib.h>
+#include <EGL/egl.h>
+
+struct wl_xcomposite;
+
+class QWaylandXCompositeEGLIntegration : public QWaylandGLIntegration
+{
+public:
+ QWaylandXCompositeEGLIntegration(QWaylandDisplay * waylandDispaly);
+ ~QWaylandXCompositeEGLIntegration();
+
+ void initialize();
+
+ QWaylandWindow *createEglWindow(QWidget *widget);
+
+ QWaylandDisplay *waylandDisplay() const;
+ struct wl_xcomposite *waylandXComposite() const;
+
+ Display *xDisplay() const;
+ EGLDisplay eglDisplay() const;
+ int screen() const;
+ Window rootWindow() const;
+
+private:
+ QWaylandDisplay *mWaylandDisplay;
+ struct wl_xcomposite *mWaylandComposite;
+
+ Display *mDisplay;
+ EGLDisplay mEglDisplay;
+ int mScreen;
+ Window mRootWindow;
+
+ static void wlDisplayHandleGlobal(struct wl_display *display, uint32_t id,
+ const char *interface, uint32_t version, void *data);
+
+ static const struct wl_xcomposite_listener xcomposite_listener;
+ static void rootInformation(void *data,
+ struct wl_xcomposite *xcomposite,
+ const char *display_name,
+ uint32_t root_window);
+};
+
+#endif // QWAYLANDXCOMPOSITEEGLINTEGRATION_H
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.cpp b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.cpp
new file mode 100644
index 0000000..1c9d36f
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.cpp
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwaylandxcompositeeglwindow.h"
+
+#include <QtCore/QDebug>
+
+QWaylandXCompositeEGLWindow::QWaylandXCompositeEGLWindow(QWidget *window, QWaylandXCompositeEGLIntegration *glxIntegration)
+ : QWaylandWindow(window)
+ , mGlxIntegration(glxIntegration)
+ , mContext(0)
+{
+
+}
+
+QWaylandWindow::WindowType QWaylandXCompositeEGLWindow::windowType() const
+{
+ //yeah. this type needs a new name
+ return QWaylandWindow::Egl;
+}
+
+QPlatformGLContext * QWaylandXCompositeEGLWindow::glContext() const
+{
+ if (!mContext) {
+ qDebug() << "creating glcontext;";
+ QWaylandXCompositeEGLWindow *that = const_cast<QWaylandXCompositeEGLWindow *>(this);
+ that->mContext = new QWaylandXCompositeEGLContext(mGlxIntegration,that);
+ }
+ return mContext;
+}
+
+void QWaylandXCompositeEGLWindow::setGeometry(const QRect &rect)
+{
+ QWaylandWindow::setGeometry(rect);
+
+ if (mContext) {
+ mContext->geometryChanged();
+ }
+}
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.h b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.h
new file mode 100644
index 0000000..fc33b32
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.h
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWAYLANDXCOMPOSITEEGLWINDOW_H
+#define QWAYLANDXCOMPOSITEEGLWINDOW_H
+
+#include "qwaylandwindow.h"
+#include "qwaylandxcompositeeglintegration.h"
+#include "qwaylandxcompositeeglcontext.h"
+
+class QWaylandXCompositeEGLWindow : public QWaylandWindow
+{
+public:
+ QWaylandXCompositeEGLWindow(QWidget *window, QWaylandXCompositeEGLIntegration *glxIntegration);
+ WindowType windowType() const;
+
+ QPlatformGLContext *glContext() const;
+
+ void setGeometry(const QRect &rect);
+
+private:
+ QWaylandXCompositeEGLIntegration *mGlxIntegration;
+ QWaylandXCompositeEGLContext *mContext;
+
+};
+
+#endif // QWAYLANDXCOMPOSITEEGLWINDOW_H
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/xcomposite_egl.pri b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/xcomposite_egl.pri
new file mode 100644
index 0000000..c3533f9
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/xcomposite_egl.pri
@@ -0,0 +1,15 @@
+include (../xcomposite_share/xcomposite_share.pri)
+include (../../../eglconvenience/eglconvenience.pri)
+include (../../../eglconvenience/xlibeglintegration.pri)
+
+LIBS += -lXcomposite -lEGL
+
+SOURCES += \
+ $$PWD/qwaylandxcompositeeglcontext.cpp \
+ $$PWD/qwaylandxcompositeeglintegration.cpp \
+ $$PWD/qwaylandxcompositeeglwindow.cpp
+
+HEADERS += \
+ $$PWD/qwaylandxcompositeeglcontext.h \
+ $$PWD/qwaylandxcompositeeglintegration.h \
+ $$PWD/qwaylandxcompositeeglwindow.h
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.cpp b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.cpp
new file mode 100644
index 0000000..caf5117
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.cpp
@@ -0,0 +1,150 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwaylandxcompositeglxcontext.h"
+
+#include "qwaylandxcompositeglxwindow.h"
+#include "qwaylandxcompositebuffer.h"
+
+#include "wayland-xcomposite-client-protocol.h"
+#include <QtCore/QDebug>
+
+#include <X11/extensions/Xcomposite.h>
+
+QWaylandXCompositeGLXContext::QWaylandXCompositeGLXContext(QWaylandXCompositeGLXIntegration *glxIntegration, QWaylandXCompositeGLXWindow *window)
+ : QPlatformGLContext()
+ , mGlxIntegration(glxIntegration)
+ , mWindow(window)
+ , mBuffer(0)
+ , mXWindow(0)
+ , mConfig(qglx_findConfig(glxIntegration->xDisplay(),glxIntegration->screen(),window->widget()->platformWindowFormat()))
+ , mWaitingForSyncCallback(false)
+{
+ XVisualInfo *visualInfo = glXGetVisualFromFBConfig(glxIntegration->xDisplay(),mConfig);
+ mContext = glXCreateContext(glxIntegration->xDisplay(),visualInfo,0,TRUE);
+
+ geometryChanged();
+}
+
+void QWaylandXCompositeGLXContext::makeCurrent()
+{
+ QPlatformGLContext::makeCurrent();
+ glXMakeCurrent(mGlxIntegration->xDisplay(),mXWindow,mContext);
+}
+
+void QWaylandXCompositeGLXContext::doneCurrent()
+{
+ glXMakeCurrent(mGlxIntegration->xDisplay(),0,0);
+ QPlatformGLContext::doneCurrent();
+}
+
+void QWaylandXCompositeGLXContext::swapBuffers()
+{
+ QSize size = mWindow->geometry().size();
+
+ glXSwapBuffers(mGlxIntegration->xDisplay(),mXWindow);
+ mWindow->damage(QRegion(QRect(QPoint(0,0),size)));
+ mWindow->waitForFrameSync();
+}
+
+void * QWaylandXCompositeGLXContext::getProcAddress(const QString &procName)
+{
+ return (void *) glXGetProcAddress(reinterpret_cast<GLubyte *>(procName.toLatin1().data()));
+}
+
+QPlatformWindowFormat QWaylandXCompositeGLXContext::platformWindowFormat() const
+{
+ return qglx_platformWindowFromGLXFBConfig(mGlxIntegration->xDisplay(),mConfig,mContext);
+}
+
+void QWaylandXCompositeGLXContext::sync_function(void *data)
+{
+ QWaylandXCompositeGLXContext *that = static_cast<QWaylandXCompositeGLXContext *>(data);
+ that->mWaitingForSyncCallback = false;
+}
+
+void QWaylandXCompositeGLXContext::waitForSync()
+{
+ wl_display_sync_callback(mGlxIntegration->waylandDisplay()->wl_display(),
+ QWaylandXCompositeGLXContext::sync_function,
+ this);
+ mWaitingForSyncCallback = true;
+ wl_display_sync(mGlxIntegration->waylandDisplay()->wl_display(),0);
+ mGlxIntegration->waylandDisplay()->flushRequests();
+ while (mWaitingForSyncCallback) {
+ mGlxIntegration->waylandDisplay()->readEvents();
+ }
+}
+
+void QWaylandXCompositeGLXContext::geometryChanged()
+{
+ QSize size(mWindow->geometry().size());
+ if (size.isEmpty()) {
+ //QGLWidget wants a context for a window without geometry
+ size = QSize(1,1);
+ }
+
+ delete mBuffer;
+ //XFreePixmap deletes the glxPixmap as well
+ if (mXWindow) {
+ XDestroyWindow(mGlxIntegration->xDisplay(),mXWindow);
+ }
+
+ XVisualInfo *visualInfo = glXGetVisualFromFBConfig(mGlxIntegration->xDisplay(),mConfig);
+ Colormap cmap = XCreateColormap(mGlxIntegration->xDisplay(),mGlxIntegration->rootWindow(),visualInfo->visual,AllocNone);
+
+ XSetWindowAttributes a;
+ a.colormap = cmap;
+ mXWindow = XCreateWindow(mGlxIntegration->xDisplay(), mGlxIntegration->rootWindow(),0, 0, size.width(), size.height(),
+ 0, visualInfo->depth, InputOutput, visualInfo->visual,
+ CWColormap, &a);
+
+ XCompositeRedirectWindow(mGlxIntegration->xDisplay(), mXWindow, CompositeRedirectManual);
+ XMapWindow(mGlxIntegration->xDisplay(), mXWindow);
+
+ XSync(mGlxIntegration->xDisplay(),False);
+ mBuffer = new QWaylandXCompositeBuffer(mGlxIntegration->waylandXComposite(),
+ (uint32_t)mXWindow,
+ size,
+ mGlxIntegration->waylandDisplay()->argbVisual());
+ mWindow->attach(mBuffer);
+ waitForSync();
+}
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.h b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.h
new file mode 100644
index 0000000..eb2e5a5
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWAYLANDXCOMPOSITEGLXCONTEXT_H
+#define QWAYLANDXCOMPOSITEGLXCONTEXT_H
+
+#include <QtGui/QPlatformGLContext>
+
+#include <QtCore/QWaitCondition>
+
+#include "qwaylandbuffer.h"
+#include "qwaylandxcompositeglxintegration.h"
+
+#include "qglxconvenience.h"
+
+class QWaylandXCompositeGLXWindow;
+class QWaylandShmBuffer;
+
+class QWaylandXCompositeGLXContext : public QPlatformGLContext
+{
+public:
+ QWaylandXCompositeGLXContext(QWaylandXCompositeGLXIntegration *glxIntegration, QWaylandXCompositeGLXWindow *window);
+
+ void makeCurrent();
+ void doneCurrent();
+ void swapBuffers();
+ void* getProcAddress(const QString& procName);
+
+ QPlatformWindowFormat platformWindowFormat() const;
+
+ void geometryChanged();
+
+private:
+ QWaylandXCompositeGLXIntegration *mGlxIntegration;
+ QWaylandXCompositeGLXWindow *mWindow;
+ QWaylandBuffer *mBuffer;
+
+ Window mXWindow;
+ GLXFBConfig mConfig;
+ GLXContext mContext;
+
+ static void sync_function(void *data);
+ void waitForSync();
+ bool mWaitingForSyncCallback;
+};
+
+#endif // QWAYLANDXCOMPOSITEGLXCONTEXT_H
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.cpp b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.cpp
new file mode 100644
index 0000000..43c0135
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.cpp
@@ -0,0 +1,126 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwaylandxcompositeglxintegration.h"
+
+#include "qwaylandxcompositeglxwindow.h"
+
+#include <QtCore/QDebug>
+
+#include "wayland-xcomposite-client-protocol.h"
+
+QWaylandGLIntegration * QWaylandGLIntegration::createGLIntegration(QWaylandDisplay *waylandDisplay)
+{
+ return new QWaylandXCompositeGLXIntegration(waylandDisplay);
+}
+
+QWaylandXCompositeGLXIntegration::QWaylandXCompositeGLXIntegration(QWaylandDisplay * waylandDispaly)
+ : QWaylandGLIntegration()
+ , mWaylandDisplay(waylandDispaly)
+{
+ qDebug() << "Using XComposite-GLX";
+ wl_display_add_global_listener(waylandDispaly->wl_display(), QWaylandXCompositeGLXIntegration::wlDisplayHandleGlobal,
+ this);
+}
+
+QWaylandXCompositeGLXIntegration::~QWaylandXCompositeGLXIntegration()
+{
+ XCloseDisplay(mDisplay);
+}
+
+void QWaylandXCompositeGLXIntegration::initialize()
+{
+}
+
+QWaylandWindow * QWaylandXCompositeGLXIntegration::createEglWindow(QWidget *widget)
+{
+ return new QWaylandXCompositeGLXWindow(widget,this);
+}
+
+Display * QWaylandXCompositeGLXIntegration::xDisplay() const
+{
+ return mDisplay;
+}
+
+int QWaylandXCompositeGLXIntegration::screen() const
+{
+ return mScreen;
+}
+
+Window QWaylandXCompositeGLXIntegration::rootWindow() const
+{
+ return mRootWindow;
+}
+
+QWaylandDisplay * QWaylandXCompositeGLXIntegration::waylandDisplay() const
+{
+ return mWaylandDisplay;
+}
+wl_xcomposite * QWaylandXCompositeGLXIntegration::waylandXComposite() const
+{
+ return mWaylandComposite;
+}
+
+const struct wl_xcomposite_listener QWaylandXCompositeGLXIntegration::xcomposite_listener = {
+ QWaylandXCompositeGLXIntegration::rootInformation
+};
+
+void QWaylandXCompositeGLXIntegration::wlDisplayHandleGlobal(wl_display *display, uint32_t id, const char *interface, uint32_t version, void *data)
+{
+ Q_UNUSED(version);
+ if (strcmp(interface, "xcomposite") == 0) {
+ QWaylandXCompositeGLXIntegration *integration = static_cast<QWaylandXCompositeGLXIntegration *>(data);
+ integration->mWaylandComposite = wl_xcomposite_create(display,id);
+ wl_xcomposite_add_listener(integration->mWaylandComposite,&xcomposite_listener,integration);
+ }
+
+}
+
+void QWaylandXCompositeGLXIntegration::rootInformation(void *data, wl_xcomposite *xcomposite, const char *display_name, uint32_t root_window)
+{
+ Q_UNUSED(xcomposite);
+ QWaylandXCompositeGLXIntegration *integration = static_cast<QWaylandXCompositeGLXIntegration *>(data);
+
+ integration->mDisplay = XOpenDisplay(display_name);
+ integration->mRootWindow = (Window) root_window;
+ integration->mScreen = XDefaultScreen(integration->mDisplay);
+}
+
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.h b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.h
new file mode 100644
index 0000000..24a4016
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.h
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWAYLANDXCOMPOSITEGLXINTEGRATION_H
+#define QWAYLANDXCOMPOSITEGLXINTEGRATION_H
+
+#include "gl_integration/qwaylandglintegration.h"
+#include "wayland-client.h"
+
+#include <QtCore/QTextStream>
+#include <QtCore/QDataStream>
+#include <QtCore/QMetaType>
+#include <QtCore/QVariant>
+#include <QtGui/QWidget>
+
+#include <X11/Xlib.h>
+
+struct wl_xcomposite;
+
+class QWaylandXCompositeGLXIntegration : public QWaylandGLIntegration
+{
+public:
+ QWaylandXCompositeGLXIntegration(QWaylandDisplay * waylandDispaly);
+ ~QWaylandXCompositeGLXIntegration();
+
+ void initialize();
+
+ QWaylandWindow *createEglWindow(QWidget *widget);
+
+ QWaylandDisplay *waylandDisplay() const;
+ struct wl_xcomposite *waylandXComposite() const;
+
+ Display *xDisplay() const;
+ int screen() const;
+ Window rootWindow() const;
+
+private:
+ QWaylandDisplay *mWaylandDisplay;
+ struct wl_xcomposite *mWaylandComposite;
+
+ Display *mDisplay;
+ int mScreen;
+ Window mRootWindow;
+
+ static void wlDisplayHandleGlobal(struct wl_display *display, uint32_t id,
+ const char *interface, uint32_t version, void *data);
+
+ static const struct wl_xcomposite_listener xcomposite_listener;
+ static void rootInformation(void *data,
+ struct wl_xcomposite *xcomposite,
+ const char *display_name,
+ uint32_t root_window);
+};
+
+#endif // QWAYLANDXCOMPOSITEGLXINTEGRATION_H
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.cpp b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.cpp
new file mode 100644
index 0000000..db0f254
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.cpp
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwaylandxcompositeglxwindow.h"
+
+#include <QtCore/QDebug>
+
+QWaylandXCompositeGLXWindow::QWaylandXCompositeGLXWindow(QWidget *window, QWaylandXCompositeGLXIntegration *glxIntegration)
+ : QWaylandWindow(window)
+ , mGlxIntegration(glxIntegration)
+ , mContext(0)
+{
+
+}
+
+QWaylandWindow::WindowType QWaylandXCompositeGLXWindow::windowType() const
+{
+ //yeah. this type needs a new name
+ return QWaylandWindow::Egl;
+}
+
+QPlatformGLContext * QWaylandXCompositeGLXWindow::glContext() const
+{
+ if (!mContext) {
+ qDebug() << "creating glcontext;";
+ QWaylandXCompositeGLXWindow *that = const_cast<QWaylandXCompositeGLXWindow *>(this);
+ that->mContext = new QWaylandXCompositeGLXContext(mGlxIntegration,that);
+ }
+ return mContext;
+}
+
+void QWaylandXCompositeGLXWindow::setGeometry(const QRect &rect)
+{
+ QWaylandWindow::setGeometry(rect);
+
+ if (mContext) {
+ mContext->geometryChanged();
+ }
+}
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.h b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.h
new file mode 100644
index 0000000..536153d
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.h
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWAYLANDXCOMPOSITEGLXWINDOW_H
+#define QWAYLANDXCOMPOSITEGLXWINDOW_H
+
+#include "qwaylandwindow.h"
+#include "qwaylandxcompositeglxintegration.h"
+#include "qwaylandxcompositeglxcontext.h"
+
+class QWaylandXCompositeGLXWindow : public QWaylandWindow
+{
+public:
+ QWaylandXCompositeGLXWindow(QWidget *window, QWaylandXCompositeGLXIntegration *glxIntegration);
+ WindowType windowType() const;
+
+ QPlatformGLContext *glContext() const;
+
+ void setGeometry(const QRect &rect);
+
+private:
+ QWaylandXCompositeGLXIntegration *mGlxIntegration;
+ QWaylandXCompositeGLXContext *mContext;
+
+};
+
+#endif // QWAYLANDXCOMPOSITEGLXWINDOW_H
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/xcomposite_glx.pri b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/xcomposite_glx.pri
new file mode 100644
index 0000000..43295e9
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/xcomposite_glx.pri
@@ -0,0 +1,13 @@
+include (../xcomposite_share/xcomposite_share.pri)
+include (../../../glxconvenience/glxconvenience.pri)
+
+LIBS += -lXcomposite
+SOURCES += \
+ $$PWD/qwaylandxcompositeglxcontext.cpp \
+ $$PWD/qwaylandxcompositeglxintegration.cpp \
+ $$PWD/qwaylandxcompositeglxwindow.cpp
+
+HEADERS += \
+ $$PWD/qwaylandxcompositeglxcontext.h \
+ $$PWD/qwaylandxcompositeglxintegration.h \
+ $$PWD/qwaylandxcompositeglxwindow.h
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_share/qwaylandxcompositebuffer.cpp b/src/plugins/platforms/wayland/gl_integration/xcomposite_share/qwaylandxcompositebuffer.cpp
new file mode 100644
index 0000000..4b0d3a0
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_share/qwaylandxcompositebuffer.cpp
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwaylandxcompositebuffer.h"
+
+#include "wayland-client.h"
+
+QWaylandXCompositeBuffer::QWaylandXCompositeBuffer(wl_xcomposite *xcomposite, uint32_t window, const QSize &size, wl_visual *visual)
+ :mSize(size)
+{
+ mBuffer = wl_xcomposite_create_buffer(xcomposite,
+ window,
+ size.width(),
+ size.height(),
+ visual);
+}
+
+QSize QWaylandXCompositeBuffer::size() const
+{
+ return mSize;
+}
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_share/qwaylandxcompositebuffer.h b/src/plugins/platforms/wayland/gl_integration/xcomposite_share/qwaylandxcompositebuffer.h
new file mode 100644
index 0000000..b346651
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_share/qwaylandxcompositebuffer.h
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWAYLANDXCOMPOSITEBUFFER_H
+#define QWAYLANDXCOMPOSITEBUFFER_H
+
+#include "qwaylandbuffer.h"
+
+#include "wayland-xcomposite-client-protocol.h"
+
+class QWaylandXCompositeBuffer : public QWaylandBuffer
+{
+public:
+ QWaylandXCompositeBuffer(struct wl_xcomposite *xcomposite,
+ uint32_t window,
+ const QSize &size,
+ struct wl_visual *visual);
+
+ QSize size() const;
+private:
+ QSize mSize;
+};
+
+#endif // QWAYLANDXCOMPOSITEBUFFER_H
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_share/wayland-xcomposite-client-protocol.h b/src/plugins/platforms/wayland/gl_integration/xcomposite_share/wayland-xcomposite-client-protocol.h
new file mode 100644
index 0000000..72376e1
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_share/wayland-xcomposite-client-protocol.h
@@ -0,0 +1,145 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef XCOMPOSITE_CLIENT_PROTOCOL_H
+#define XCOMPOSITE_CLIENT_PROTOCOL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <stddef.h>
+#include "wayland-util.h"
+
+struct wl_client;
+
+struct wl_xcomposite;
+
+struct wl_proxy;
+
+extern void
+wl_proxy_marshal(struct wl_proxy *p, uint32_t opcode, ...);
+extern struct wl_proxy *
+wl_proxy_create(struct wl_proxy *factory,
+ const struct wl_interface *interface);
+extern struct wl_proxy *
+wl_proxy_create_for_id(struct wl_display *display,
+ const struct wl_interface *interface, uint32_t id);
+extern void
+wl_proxy_destroy(struct wl_proxy *proxy);
+
+extern int
+wl_proxy_add_listener(struct wl_proxy *proxy,
+ void (**implementation)(void), void *data);
+
+extern void
+wl_proxy_set_user_data(struct wl_proxy *proxy, void *user_data);
+
+extern void *
+wl_proxy_get_user_data(struct wl_proxy *proxy);
+
+extern const struct wl_interface wl_xcomposite_interface;
+
+struct wl_xcomposite_listener {
+ void (*root)(void *data,
+ struct wl_xcomposite *xcomposite,
+ const char *display_name,
+ uint32_t root_window);
+};
+
+static inline int
+wl_xcomposite_add_listener(struct wl_xcomposite *xcomposite,
+ const struct wl_xcomposite_listener *listener, void *data)
+{
+ return wl_proxy_add_listener((struct wl_proxy *) xcomposite,
+ (void (**)(void)) listener, data);
+}
+
+#define WL_XCOMPOSITE_CREATE_BUFFER 0
+
+static inline struct wl_xcomposite *
+wl_xcomposite_create(struct wl_display *display, uint32_t id)
+{
+ return (struct wl_xcomposite *)
+ wl_proxy_create_for_id(display, &wl_xcomposite_interface, id);
+}
+
+static inline void
+wl_xcomposite_set_user_data(struct wl_xcomposite *xcomposite, void *user_data)
+{
+ wl_proxy_set_user_data((struct wl_proxy *) xcomposite, user_data);
+}
+
+static inline void *
+wl_xcomposite_get_user_data(struct wl_xcomposite *xcomposite)
+{
+ return wl_proxy_get_user_data((struct wl_proxy *) xcomposite);
+}
+
+static inline void
+wl_xcomposite_destroy(struct wl_xcomposite *xcomposite)
+{
+ wl_proxy_destroy((struct wl_proxy *) xcomposite);
+}
+
+static inline struct wl_buffer *
+wl_xcomposite_create_buffer(struct wl_xcomposite *xcomposite, uint32_t x_window, int width, int height, struct wl_visual *visual)
+{
+ struct wl_proxy *id;
+
+ id = wl_proxy_create((struct wl_proxy *) xcomposite,
+ &wl_buffer_interface);
+ if (!id)
+ return NULL;
+
+ wl_proxy_marshal((struct wl_proxy *) xcomposite,
+ WL_XCOMPOSITE_CREATE_BUFFER, id, x_window, width, height, visual);
+
+ return (struct wl_buffer *) id;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_share/wayland-xcomposite-protocol.c b/src/plugins/platforms/wayland/gl_integration/xcomposite_share/wayland-xcomposite-protocol.c
new file mode 100644
index 0000000..5c966fd
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_share/wayland-xcomposite-protocol.c
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <stdlib.h>
+#include <stdint.h>
+#include "wayland-util.h"
+
+static const struct wl_message xcomposite_requests[] = {
+ { "create_buffer", "nuiio" },
+};
+
+static const struct wl_message xcomposite_events[] = {
+ { "root", "su" },
+};
+
+WL_EXPORT const struct wl_interface wl_xcomposite_interface = {
+ "xcomposite", 1,
+ ARRAY_LENGTH(xcomposite_requests), xcomposite_requests,
+ ARRAY_LENGTH(xcomposite_events), xcomposite_events,
+};
+
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_share/xcomposite_share.pri b/src/plugins/platforms/wayland/gl_integration/xcomposite_share/xcomposite_share.pri
new file mode 100644
index 0000000..03b3521
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_share/xcomposite_share.pri
@@ -0,0 +1,9 @@
+INCLUDEPATH += $$PWD
+
+HEADERS += \
+ $$PWD/wayland-xcomposite-client-protocol.h \
+ gl_integration/xcomposite_share/qwaylandxcompositebuffer.h
+
+SOURCES += \
+ $$PWD/wayland-xcomposite-protocol.c \
+ gl_integration/xcomposite_share/qwaylandxcompositebuffer.cpp
diff --git a/src/plugins/platforms/wayland/qwaylandbuffer.h b/src/plugins/platforms/wayland/qwaylandbuffer.h
index 643e89c..8779d5f 100644
--- a/src/plugins/platforms/wayland/qwaylandbuffer.h
+++ b/src/plugins/platforms/wayland/qwaylandbuffer.h
@@ -4,7 +4,7 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of the config.tests of the Qt Toolkit.
+** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
diff --git a/src/plugins/platforms/wayland/qwaylanddisplay.cpp b/src/plugins/platforms/wayland/qwaylanddisplay.cpp
index 27f4334..1c56561 100644
--- a/src/plugins/platforms/wayland/qwaylanddisplay.cpp
+++ b/src/plugins/platforms/wayland/qwaylanddisplay.cpp
@@ -46,13 +46,23 @@
#include "qwaylandcursor.h"
#include "qwaylandinputdevice.h"
+#ifdef QT_WAYLAND_GL_SUPPORT
+#include "gl_integration/qwaylandglintegration.h"
+#endif
+
+#include <QtCore/QAbstractEventDispatcher>
+#include <QtGui/QApplication>
+
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
+#include <errno.h>
-struct wl_surface *QWaylandDisplay::createSurface()
+struct wl_surface *QWaylandDisplay::createSurface(void *handle)
{
- return wl_compositor_create_surface(mCompositor);
+ struct wl_surface * surface = wl_compositor_create_surface(mCompositor);
+ wl_surface_set_user_data(surface, handle);
+ return surface;
}
struct wl_buffer *QWaylandDisplay::createShmBuffer(int fd,
@@ -78,10 +88,12 @@ struct wl_visual *QWaylandDisplay::argbPremultipliedVisual()
return wl_display_get_premultiplied_argb_visual(mDisplay);
}
-struct wl_egl_display *QWaylandDisplay::nativeDisplay()
+#ifdef QT_WAYLAND_GL_SUPPORT
+QWaylandGLIntegration * QWaylandDisplay::eglIntegration()
{
- return mNativeEglDisplay;
+ return mEglIntegration;
}
+#endif
void QWaylandDisplay::shellHandleConfigure(void *data, struct wl_shell *shell,
uint32_t time, uint32_t edges,
@@ -101,147 +113,158 @@ const struct wl_shell_listener QWaylandDisplay::shellListener = {
QWaylandDisplay::shellHandleConfigure,
};
-void QWaylandDisplay::outputHandleGeometry(void *data,
- struct wl_output *output,
- int32_t x, int32_t y,
- int32_t width, int32_t height)
+QWaylandDisplay::QWaylandDisplay(void)
{
- QWaylandDisplay *waylandDisplay = (QWaylandDisplay *) data;
+ mDisplay = wl_display_connect(NULL);
+ if (mDisplay == NULL) {
+ qErrnoWarning(errno, "Failed to create display");
+ qFatal("No wayland connection available.");
+ }
- QRect outputRect = QRect(x, y, width, height);
- waylandDisplay->createNewScreen(output, outputRect);
-}
+ wl_display_add_global_listener(mDisplay, QWaylandDisplay::displayHandleGlobal, this);
-const struct wl_output_listener QWaylandDisplay::outputListener = {
- QWaylandDisplay::outputHandleGeometry
-};
+#ifdef QT_WAYLAND_GL_SUPPORT
+ mEglIntegration = QWaylandGLIntegration::createGLIntegration(this);
+#endif
-void QWaylandDisplay::displayHandleGlobal(struct wl_display *display,
- uint32_t id,
- const char *interface,
- uint32_t version, void *data)
-{
- Q_UNUSED(version);
- QWaylandDisplay *qwd = (QWaylandDisplay *) data;
-
- if (strcmp(interface, "compositor") == 0) {
- qwd->mCompositor = wl_compositor_create(display, id);
- } else if (strcmp(interface, "shm") == 0) {
- qwd->mShm = wl_shm_create(display, id);
- } else if (strcmp(interface, "shell") == 0) {
- qwd->mShell = wl_shell_create(display, id);
- wl_shell_add_listener(qwd->mShell, &shellListener, qwd);
- } else if (strcmp(interface, "output") == 0) {
- struct wl_output *output = wl_output_create(display, id);
- wl_output_add_listener(output, &outputListener, qwd);
- } else if (strcmp(interface, "input_device") == 0) {
- QWaylandInputDevice *inputDevice =
- new QWaylandInputDevice(display, id);
- qwd->mInputDevices.append(inputDevice);
- }
+ qRegisterMetaType<uint32_t>("uint32_t");
+
+#ifdef QT_WAYLAND_GL_SUPPORT
+ mEglIntegration->initialize();
+#endif
+
+ connect(QAbstractEventDispatcher::instance(), SIGNAL(aboutToBlock()), this, SLOT(flushRequests()));
+
+ mFd = wl_display_get_fd(mDisplay, sourceUpdate, this);
+
+ mReadNotifier = new QSocketNotifier(mFd, QSocketNotifier::Read, this);
+ connect(mReadNotifier, SIGNAL(activated(int)), this, SLOT(readEvents()));
+
+ waitForScreens();
}
-void QWaylandDisplay::iterate()
+QWaylandDisplay::~QWaylandDisplay(void)
{
- wl_display_iterate(mDisplay, WL_DISPLAY_READABLE | WL_DISPLAY_WRITABLE);
+ close(mFd);
+#ifdef QT_WAYLAND_GL_SUPPORT
+ delete mEglIntegration;
+#endif
+ wl_display_destroy(mDisplay);
}
-void QWaylandDisplay::readEvents(void)
+void QWaylandDisplay::createNewScreen(struct wl_output *output, QRect geometry)
{
- wl_display_iterate(mDisplay, WL_DISPLAY_READABLE);
+ QWaylandScreen *waylandScreen = new QWaylandScreen(this,output,geometry);
+ mScreens.append(waylandScreen);
}
-int
-QWaylandDisplay::sourceUpdate(uint32_t mask, void *data)
+void QWaylandDisplay::syncCallback(wl_display_sync_func_t func, void *data)
{
- QWaylandDisplay *qwd = (QWaylandDisplay *) data;
-
- /* FIXME: We get a callback here when we ask wl_display for the
- * fd, but at that point we don't have the socket notifier as we
- * need the fd to create that. We'll probably need to split that
- * API into get_fd and set_update_func functions. */
- if (qwd->mWriteNotifier == NULL)
- return 0;
-
- qwd->mWriteNotifier->setEnabled(mask & WL_DISPLAY_WRITABLE);
+ wl_display_sync_callback(mDisplay, func, data);
+}
- return 0;
+void QWaylandDisplay::frameCallback(wl_display_frame_func_t func, struct wl_surface *surface, void *data)
+{
+ wl_display_frame_callback(mDisplay, surface, func, data);
}
-void QWaylandDisplay::flushRequests(void)
+void QWaylandDisplay::flushRequests()
{
- wl_display_iterate(mDisplay, WL_DISPLAY_WRITABLE);
+ if (mSocketMask & WL_DISPLAY_WRITABLE)
+ wl_display_iterate(mDisplay, WL_DISPLAY_WRITABLE);
}
-QWaylandDisplay::QWaylandDisplay(void)
- : mWriteNotifier(0)
+void QWaylandDisplay::readEvents()
{
-#ifdef QT_WAYLAND_GL_SUPPORT
- EGLint major, minor;
-#endif
- mDisplay = wl_display_connect(NULL);
- if (mDisplay == NULL) {
- fprintf(stderr, "failed to create display: %m\n");
+// verify that there is still data on the socket
+ fd_set fds;
+ FD_ZERO(&fds);
+ FD_SET(mFd, &fds);
+ fd_set nds;
+ FD_ZERO(&nds);
+ fd_set rs = fds;
+ fd_set ws = nds;
+ fd_set es = nds;
+ timeval timeout;
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 0;
+ int ret = ::select(mFd+1, &rs, &ws, &es, &timeout );
+
+ if (ret <= 0) {
+ //qDebug("QWaylandDisplay::readEvents() No data... blocking avoided");
return;
}
- wl_display_add_global_listener(mDisplay,
- QWaylandDisplay::displayHandleGlobal, this);
-
-#ifdef QT_WAYLAND_GL_SUPPORT
- mNativeEglDisplay = wl_egl_display_create(mDisplay);
-#else
- mNativeEglDisplay = 0;
-#endif
-
- readEvents();
+ wl_display_iterate(mDisplay, WL_DISPLAY_READABLE);
+}
-#ifdef QT_WAYLAND_GL_SUPPORT
- mEglDisplay = eglGetDisplay((EGLNativeDisplayType)mNativeEglDisplay);
- if (mEglDisplay == NULL) {
- qWarning("EGL not available");
- } else {
- if (!eglInitialize(mEglDisplay, &major, &minor)) {
- qWarning("failed to initialize EGL display");
- return;
- }
- }
-#else
- mEglDisplay = 0;
-#endif
+void QWaylandDisplay::blockingReadEvents()
+{
+ wl_display_iterate(mDisplay, WL_DISPLAY_READABLE);
+}
- int fd = wl_display_get_fd(mDisplay, sourceUpdate, this);
- mReadNotifier = new QSocketNotifier(fd, QSocketNotifier::Read, this);
- connect(mReadNotifier,
- SIGNAL(activated(int)), this, SLOT(readEvents()));
+int QWaylandDisplay::sourceUpdate(uint32_t mask, void *data)
+{
+ QWaylandDisplay *waylandDisplay = static_cast<QWaylandDisplay *>(data);
+ waylandDisplay->mSocketMask = mask;
- mWriteNotifier = new QSocketNotifier(fd, QSocketNotifier::Write, this);
- connect(mWriteNotifier,
- SIGNAL(activated(int)), this, SLOT(flushRequests()));
- mWriteNotifier->setEnabled(false);
+ return 0;
}
-QWaylandDisplay::~QWaylandDisplay(void)
+void QWaylandDisplay::outputHandleGeometry(void *data,
+ struct wl_output *output,
+ int32_t x, int32_t y,
+ int32_t width, int32_t height)
{
- close(mFd);
-#ifdef QT_WAYLAND_GL_SUPPORT
- eglTerminate(mEglDisplay);
-#endif
- wl_display_destroy(mDisplay);
+ //call back function called from another thread;
+ //but its safe to call createScreen from another thread since
+ //QWaylandScreen does a moveToThread
+ QWaylandDisplay *waylandDisplay = static_cast<QWaylandDisplay *>(data);
+ QRect outputRect = QRect(x, y, width, height);
+ waylandDisplay->createNewScreen(output,outputRect);
}
-void QWaylandDisplay::createNewScreen(struct wl_output *output, QRect geometry)
+const struct wl_output_listener QWaylandDisplay::outputListener = {
+ QWaylandDisplay::outputHandleGeometry
+};
+
+void QWaylandDisplay::waitForScreens()
{
- QWaylandScreen *waylandScreen = new QWaylandScreen(this,output,geometry);
- mScreens.append(waylandScreen);
+ flushRequests();
+ while (mScreens.isEmpty())
+ blockingReadEvents();
}
-void QWaylandDisplay::syncCallback(wl_display_sync_func_t func, void *data)
+void QWaylandDisplay::displayHandleGlobal(struct wl_display *display,
+ uint32_t id,
+ const char *interface,
+ uint32_t version,
+ void *data)
{
- wl_display_sync_callback(mDisplay, func, data);
+ Q_UNUSED(display);
+ QWaylandDisplay *that = static_cast<QWaylandDisplay *>(data);
+ that->displayHandleGlobal(id, QByteArray(interface), version);
}
-void QWaylandDisplay::frameCallback(wl_display_frame_func_t func, void *data)
+void QWaylandDisplay::displayHandleGlobal(uint32_t id,
+ const QByteArray &interface,
+ uint32_t version)
{
- wl_display_frame_callback(mDisplay, func, data);
+ Q_UNUSED(version);
+
+ if (interface == "output") {
+ struct wl_output *output = wl_output_create(mDisplay, id);
+ wl_output_add_listener(output, &outputListener, this);
+ } else if (interface == "compositor") {
+ mCompositor = wl_compositor_create(mDisplay, id);
+ } else if (interface == "shm") {
+ mShm = wl_shm_create(mDisplay, id);
+ } else if (interface == "shell"){
+ mShell = wl_shell_create(mDisplay, id);
+ wl_shell_add_listener(mShell, &shellListener, this);
+ } else if (interface == "input_device") {
+ QWaylandInputDevice *inputDevice =
+ new QWaylandInputDevice(mDisplay, id);
+ mInputDevices.append(inputDevice);
+ }
}
diff --git a/src/plugins/platforms/wayland/qwaylanddisplay.h b/src/plugins/platforms/wayland/qwaylanddisplay.h
index d994ffe..a2cb1b2 100644
--- a/src/plugins/platforms/wayland/qwaylanddisplay.h
+++ b/src/plugins/platforms/wayland/qwaylanddisplay.h
@@ -44,19 +44,17 @@
#include <QtCore/QObject>
#include <QtCore/QRect>
-#include <QtCore/QDataStream>
-#include <QtCore/QTextStream>
-#include <QtCore/QMetaType>
-#include <QtGui>
-#include "qwaylandinclude.h"
+#include <QtCore/QWaitCondition>
+
+#include <wayland-client.h>
class QWaylandInputDevice;
class QSocketNotifier;
class QWaylandBuffer;
class QPlatformScreen;
class QWaylandScreen;
-
+class QWaylandGLIntegration;
class QWaylandDisplay : public QObject {
Q_OBJECT
@@ -64,61 +62,72 @@ public:
QWaylandDisplay(void);
~QWaylandDisplay(void);
- void createNewScreen(struct wl_output *output, QRect geometry);
QList<QPlatformScreen *> screens() const { return mScreens; }
- struct wl_surface *createSurface();
+ struct wl_surface *createSurface(void *handle);
struct wl_buffer *createShmBuffer(int fd, int width, int height,
uint32_t stride,
struct wl_visual *visual);
struct wl_visual *rgbVisual();
struct wl_visual *argbVisual();
struct wl_visual *argbPremultipliedVisual();
- struct wl_egl_display *nativeDisplay();
- EGLDisplay eglDisplay() { return mEglDisplay; }
+#ifdef QT_WAYLAND_GL_SUPPORT
+ QWaylandGLIntegration *eglIntegration();
+#endif
void setCursor(QWaylandBuffer *buffer, int32_t x, int32_t y);
void syncCallback(wl_display_sync_func_t func, void *data);
- void frameCallback(wl_display_frame_func_t func, void *data);
+ void frameCallback(wl_display_frame_func_t func, struct wl_surface *surface, void *data);
- void iterate();
+ struct wl_display *wl_display() const { return mDisplay; }
+
+ QList<QWaylandInputDevice *> inputDevices() const { return mInputDevices; }
public slots:
- void readEvents(void);
- void flushRequests(void);
+ void createNewScreen(struct wl_output *output, QRect geometry);
+ void readEvents();
+ void blockingReadEvents();
+ void flushRequests();
private:
+ void waitForScreens();
+ void displayHandleGlobal(uint32_t id,
+ const QByteArray &interface,
+ uint32_t version);
+
struct wl_display *mDisplay;
struct wl_compositor *mCompositor;
struct wl_shm *mShm;
struct wl_shell *mShell;
- char *mDeviceName;
- int mFd;
QList<QPlatformScreen *> mScreens;
QList<QWaylandInputDevice *> mInputDevices;
+
QSocketNotifier *mReadNotifier;
- QSocketNotifier *mWriteNotifier;
- EGLDisplay mEglDisplay;
- struct wl_egl_display *mNativeEglDisplay;
+ int mFd;
+ bool mScreensInitialized;
+ uint32_t mSocketMask;
+
+ static const struct wl_output_listener outputListener;
+ static int sourceUpdate(uint32_t mask, void *data);
static void displayHandleGlobal(struct wl_display *display,
uint32_t id,
const char *interface,
uint32_t version, void *data);
-
static void outputHandleGeometry(void *data,
struct wl_output *output,
int32_t x, int32_t y,
int32_t width, int32_t height);
+#ifdef QT_WAYLAND_GL_SUPPORT
+ QWaylandGLIntegration *mEglIntegration;
+#endif
+
static void shellHandleConfigure(void *data, struct wl_shell *shell,
uint32_t time, uint32_t edges,
struct wl_surface *surface,
int32_t width, int32_t height);
- static int sourceUpdate(uint32_t mask, void *data);
-
- static const struct wl_output_listener outputListener;
static const struct wl_shell_listener shellListener;
};
diff --git a/src/plugins/platforms/wayland/qwaylandinputdevice.cpp b/src/plugins/platforms/wayland/qwaylandinputdevice.cpp
index 47f9c91..6c2f341 100644
--- a/src/plugins/platforms/wayland/qwaylandinputdevice.cpp
+++ b/src/plugins/platforms/wayland/qwaylandinputdevice.cpp
@@ -83,6 +83,14 @@ QWaylandInputDevice::QWaylandInputDevice(struct wl_display *display,
#endif
}
+void QWaylandInputDevice::handleWindowDestroyed(QWaylandWindow *window)
+{
+ if (window == mPointerFocus)
+ mPointerFocus = 0;
+ if (window == mKeyboardFocus)
+ mKeyboardFocus = 0;
+}
+
void QWaylandInputDevice::inputHandleMotion(void *data,
struct wl_input_device *input_device,
uint32_t time,
diff --git a/src/plugins/platforms/wayland/qwaylandinputdevice.h b/src/plugins/platforms/wayland/qwaylandinputdevice.h
index 2328db8..3c83252 100644
--- a/src/plugins/platforms/wayland/qwaylandinputdevice.h
+++ b/src/plugins/platforms/wayland/qwaylandinputdevice.h
@@ -59,6 +59,7 @@ class QWaylandInputDevice {
public:
QWaylandInputDevice(struct wl_display *display, uint32_t id);
void attach(QWaylandBuffer *buffer, int x, int y);
+ void handleWindowDestroyed(QWaylandWindow *window);
private:
struct wl_display *mDisplay;
diff --git a/src/plugins/platforms/wayland/qwaylandintegration.cpp b/src/plugins/platforms/wayland/qwaylandintegration.cpp
index 267a037..3f3ee5e 100644
--- a/src/plugins/platforms/wayland/qwaylandintegration.cpp
+++ b/src/plugins/platforms/wayland/qwaylandintegration.cpp
@@ -43,9 +43,7 @@
#include "qwaylanddisplay.h"
#include "qwaylandshmsurface.h"
-#include "qwaylanddrmsurface.h"
#include "qwaylandshmwindow.h"
-#include "qwaylandeglwindow.h"
#include "qgenericunixfontdatabase.h"
@@ -55,6 +53,8 @@
#include <QtGui/private/qpixmap_raster_p.h>
#ifdef QT_WAYLAND_GL_SUPPORT
+#include "gl_integration/qwaylandglintegration.h"
+#include "gl_integration/qwaylandglwindowsurface.h"
#include <QtOpenGL/private/qpixmapdata_gl_p.h>
#endif
@@ -75,6 +75,7 @@ bool QWaylandIntegration::hasCapability(QPlatformIntegration::Capability cap) co
{
switch (cap) {
case ThreadedPixmaps: return true;
+ case OpenGL: return hasOpenGL();
default: return QPlatformIntegration::hasCapability(cap);
}
}
@@ -91,10 +92,11 @@ QPixmapData *QWaylandIntegration::createPixmapData(QPixmapData::PixelType type)
QPlatformWindow *QWaylandIntegration::createPlatformWindow(QWidget *widget, WId winId) const
{
Q_UNUSED(winId);
+#ifdef QT_WAYLAND_GL_SUPPORT
bool useOpenGL = mUseOpenGL || (widget->platformWindowFormat().windowApi() == QPlatformWindowFormat::OpenGL);
if (useOpenGL)
- return new QWaylandEglWindow(widget);
-
+ return mDisplay->eglIntegration()->createEglWindow(widget);
+#endif
return new QWaylandShmWindow(widget);
}
@@ -102,10 +104,11 @@ QWindowSurface *QWaylandIntegration::createWindowSurface(QWidget *widget, WId wi
{
Q_UNUSED(winId);
Q_UNUSED(winId);
+#ifdef QT_WAYLAND_GL_SUPPORT
bool useOpenGL = mUseOpenGL || (widget->platformWindowFormat().windowApi() == QPlatformWindowFormat::OpenGL);
if (useOpenGL)
- return new QWaylandDrmWindowSurface(widget);
-
+ return new QWaylandGLWindowSurface(widget);
+#endif
return new QWaylandShmWindowSurface(widget);
}
@@ -113,3 +116,12 @@ QPlatformFontDatabase *QWaylandIntegration::fontDatabase() const
{
return mFontDb;
}
+
+bool QWaylandIntegration::hasOpenGL() const
+{
+#ifdef QT_WAYLAND_GL_SUPPORT
+ return true;
+#else
+ return false;
+#endif
+}
diff --git a/src/plugins/platforms/wayland/qwaylandintegration.h b/src/plugins/platforms/wayland/qwaylandintegration.h
index 067b6e4..fc9b8d6 100644
--- a/src/plugins/platforms/wayland/qwaylandintegration.h
+++ b/src/plugins/platforms/wayland/qwaylandintegration.h
@@ -64,6 +64,8 @@ public:
QPlatformFontDatabase *fontDatabase() const;
private:
+ bool hasOpenGL() const;
+
QPlatformFontDatabase *mFontDb;
QWaylandDisplay *mDisplay;
bool mUseOpenGL;
diff --git a/src/plugins/platforms/wayland/qwaylandscreen.cpp b/src/plugins/platforms/wayland/qwaylandscreen.cpp
index 35e2532..4f50cb6 100644
--- a/src/plugins/platforms/wayland/qwaylandscreen.cpp
+++ b/src/plugins/platforms/wayland/qwaylandscreen.cpp
@@ -53,6 +53,7 @@ QWaylandScreen::QWaylandScreen(QWaylandDisplay *waylandDisplay, struct wl_output
, mFormat(QImage::Format_ARGB32_Premultiplied)
, mWaylandCursor(new QWaylandCursor(this))
{
+ moveToThread(waylandDisplay->thread());
}
QWaylandScreen::~QWaylandScreen()
diff --git a/src/plugins/platforms/wayland/qwaylandshmsurface.cpp b/src/plugins/platforms/wayland/qwaylandshmsurface.cpp
index 54da9a1..34f4436 100644
--- a/src/plugins/platforms/wayland/qwaylandshmsurface.cpp
+++ b/src/plugins/platforms/wayland/qwaylandshmsurface.cpp
@@ -95,7 +95,6 @@ QWaylandShmWindowSurface::QWaylandShmWindowSurface(QWidget *window)
: QWindowSurface(window)
, mBuffer(0)
, mDisplay(QWaylandScreen::waylandScreenFromWidget(window)->display())
- , mWaitingForFrameSync(false)
{
}
@@ -110,15 +109,9 @@ QPaintDevice *QWaylandShmWindowSurface::paintDevice()
void QWaylandShmWindowSurface::beginPaint(const QRegion &)
{
- while (mWaitingForFrameSync) {
- mDisplay->iterate();
- }
-}
-
-void QWaylandShmWindowSurface::frameCallback(void *data, uint32_t time)
-{
- QWaylandShmWindowSurface *self = static_cast<QWaylandShmWindowSurface*>(data);
- self->mWaitingForFrameSync = false;
+ QWaylandShmWindow *waylandWindow = static_cast<QWaylandShmWindow *>(window()->platformWindow());
+ Q_ASSERT(waylandWindow->windowType() == QWaylandWindow::Shm);
+ waylandWindow->waitForFrameSync();
}
void QWaylandShmWindowSurface::flush(QWidget *widget, const QRegion &region, const QPoint &offset)
@@ -127,13 +120,7 @@ void QWaylandShmWindowSurface::flush(QWidget *widget, const QRegion &region, con
Q_UNUSED(offset);
QWaylandShmWindow *waylandWindow = static_cast<QWaylandShmWindow *>(window()->platformWindow());
Q_ASSERT(waylandWindow->windowType() == QWaylandWindow::Shm);
-
- QVector<QRect> rects = region.rects();
- for (int i = 0; i < rects.size(); i++) {
- waylandWindow->damage(rects.at(i));
- }
- mWaitingForFrameSync = true;
- mDisplay->frameCallback(QWaylandShmWindowSurface::frameCallback, this);
+ waylandWindow->damage(region);
}
void QWaylandShmWindowSurface::resize(const QSize &size)
diff --git a/src/plugins/platforms/wayland/qwaylandshmsurface.h b/src/plugins/platforms/wayland/qwaylandshmsurface.h
index 02b324a..b29ceaf 100644
--- a/src/plugins/platforms/wayland/qwaylandshmsurface.h
+++ b/src/plugins/platforms/wayland/qwaylandshmsurface.h
@@ -74,11 +74,8 @@ public:
void beginPaint(const QRegion &);
private:
- static void frameCallback(void *data, uint32_t time);\
-
QWaylandShmBuffer *mBuffer;
QWaylandDisplay *mDisplay;
- bool mWaitingForFrameSync;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/wayland/qwaylandshmwindow.cpp b/src/plugins/platforms/wayland/qwaylandshmwindow.cpp
index cafd2d0..c083e58 100644
--- a/src/plugins/platforms/wayland/qwaylandshmwindow.cpp
+++ b/src/plugins/platforms/wayland/qwaylandshmwindow.cpp
@@ -43,9 +43,12 @@
#include "qwaylandbuffer.h"
+#include <QtCore/QVector>
+
+#include <QtCore/QDebug>
+
QWaylandShmWindow::QWaylandShmWindow(QWidget *widget)
: QWaylandWindow(widget)
- , mBuffer(0)
{
newSurfaceCreated();
}
@@ -66,24 +69,3 @@ QPlatformGLContext * QWaylandShmWindow::glContext() const
return 0;
}
-void QWaylandShmWindow::attach(QWaylandBuffer *buffer)
-{
- mBuffer = buffer;
- if (mSurface) {
- wl_surface_attach(mSurface, buffer->buffer(),0,0);
- }
-}
-
-
-void QWaylandShmWindow::damage(const QRect &rect)
-{
- wl_surface_damage(mSurface,
- rect.x(), rect.y(), rect.width(), rect.height());
-}
-
-void QWaylandShmWindow::newSurfaceCreated()
-{
- if (mBuffer) {
- wl_surface_attach(mSurface,mBuffer->buffer(),0,0);
- }
-}
diff --git a/src/plugins/platforms/wayland/qwaylandshmwindow.h b/src/plugins/platforms/wayland/qwaylandshmwindow.h
index 14a29d2..5dc6351 100644
--- a/src/plugins/platforms/wayland/qwaylandshmwindow.h
+++ b/src/plugins/platforms/wayland/qwaylandshmwindow.h
@@ -43,6 +43,7 @@
#define QWAYLANDSHMWINDOW_H
#include "qwaylandwindow.h"
+#include <QtGui/QRegion>
class QWaylandShmWindow : public QWaylandWindow
{
@@ -52,12 +53,6 @@ public:
WindowType windowType() const;
QPlatformGLContext *glContext() const;
- void attach(QWaylandBuffer *buffer);
- void damage(const QRect &rect);
-protected:
- void newSurfaceCreated();
-private:
- QWaylandBuffer *mBuffer;
};
#endif // QWAYLANDSHMWINDOW_H
diff --git a/src/plugins/platforms/wayland/qwaylandwindow.cpp b/src/plugins/platforms/wayland/qwaylandwindow.cpp
index a912a83..6f52291 100644
--- a/src/plugins/platforms/wayland/qwaylandwindow.cpp
+++ b/src/plugins/platforms/wayland/qwaylandwindow.cpp
@@ -41,7 +41,9 @@
#include "qwaylandwindow.h"
+#include "qwaylandbuffer.h"
#include "qwaylanddisplay.h"
+#include "qwaylandinputdevice.h"
#include "qwaylandscreen.h"
#include <QtGui/QWidget>
@@ -52,15 +54,23 @@
QWaylandWindow::QWaylandWindow(QWidget *window)
: QPlatformWindow(window)
, mDisplay(QWaylandScreen::waylandScreenFromWidget(window)->display())
+ , mBuffer(0)
+ , mWaitingForFrameSync(false)
{
static WId id = 1;
mWindowId = id++;
- mSurface = mDisplay->createSurface();
+ mSurface = mDisplay->createSurface(this);
}
QWaylandWindow::~QWaylandWindow()
{
+ if (mSurface)
+ wl_surface_destroy(mSurface);
+
+ QList<QWaylandInputDevice *> inputDevices = mDisplay->inputDevices();
+ for (int i = 0; i < inputDevices.size(); ++i)
+ inputDevices.at(i)->handleWindowDestroyed(this);
}
WId QWaylandWindow::winId() const
@@ -71,18 +81,17 @@ WId QWaylandWindow::winId() const
void QWaylandWindow::setParent(const QPlatformWindow *parent)
{
Q_UNUSED(parent);
- qWarning("Trying to add a raster window as a sub-window");
+ qWarning("Sub window is not supported");
}
void QWaylandWindow::setVisible(bool visible)
{
- if (!mSurface) {
- mSurface = mDisplay->createSurface();
+ if (!mSurface && visible) {
+ mSurface = mDisplay->createSurface(this);
newSurfaceCreated();
}
if (visible) {
- wl_surface_set_user_data(mSurface, this);
wl_surface_map_toplevel(mSurface);
} else {
wl_surface_destroy(mSurface);
@@ -102,3 +111,48 @@ void QWaylandWindow::configure(uint32_t time, uint32_t edges,
QWindowSystemInterface::handleGeometryChange(widget(), geometry);
}
+
+void QWaylandWindow::attach(QWaylandBuffer *buffer)
+{
+ mBuffer = buffer;
+ if (mSurface) {
+ wl_surface_attach(mSurface, buffer->buffer(),0,0);
+ }
+}
+
+
+void QWaylandWindow::damage(const QRegion &region)
+{
+ //We have to do sync stuff before calling damage, or we might
+ //get a frame callback before we get the timestamp
+ mDisplay->frameCallback(QWaylandWindow::frameCallback, mSurface, this);
+ mWaitingForFrameSync = true;
+
+ QVector<QRect> rects = region.rects();
+ for (int i = 0; i < rects.size(); i++) {
+ const QRect rect = rects.at(i);
+ wl_surface_damage(mSurface,
+ rect.x(), rect.y(), rect.width(), rect.height());
+ }
+}
+
+void QWaylandWindow::newSurfaceCreated()
+{
+ if (mBuffer) {
+ wl_surface_attach(mSurface,mBuffer->buffer(),0,0);
+ }
+}
+
+void QWaylandWindow::frameCallback(struct wl_surface *surface, void *data, uint32_t time)
+{
+ Q_UNUSED(time);
+ QWaylandWindow *self = static_cast<QWaylandWindow*>(data);
+ self->mWaitingForFrameSync = false;
+}
+
+void QWaylandWindow::waitForFrameSync()
+{
+ mDisplay->flushRequests();
+ while (mWaitingForFrameSync)
+ mDisplay->blockingReadEvents();
+}
diff --git a/src/plugins/platforms/wayland/qwaylandwindow.h b/src/plugins/platforms/wayland/qwaylandwindow.h
index 3b51ee7..1e60508 100644
--- a/src/plugins/platforms/wayland/qwaylandwindow.h
+++ b/src/plugins/platforms/wayland/qwaylandwindow.h
@@ -43,8 +43,8 @@
#define QWAYLANDWINDOW_H
#include <QtGui/QPlatformWindow>
+#include <QtCore/QWaitCondition>
-#include <stdint.h>
#include "qwaylanddisplay.h"
class QWaylandDisplay;
@@ -70,11 +70,21 @@ public:
void configure(uint32_t time, uint32_t edges,
int32_t x, int32_t y, int32_t width, int32_t height);
+ void attach(QWaylandBuffer *buffer);
+ void damage(const QRegion &region);
+
+ void waitForFrameSync();
protected:
struct wl_surface *mSurface;
- virtual void newSurfaceCreated() = 0;
+ virtual void newSurfaceCreated();
QWaylandDisplay *mDisplay;
+ QWaylandBuffer *mBuffer;
WId mWindowId;
+ bool mWaitingForFrameSync;
+ QWaitCondition mFrameSyncWait;
+
+private:
+ static void frameCallback(struct wl_surface *surface, void *data, uint32_t time);
};
diff --git a/src/plugins/platforms/wayland/wayland.pro b/src/plugins/platforms/wayland/wayland.pro
index face860..5945438 100644
--- a/src/plugins/platforms/wayland/wayland.pro
+++ b/src/plugins/platforms/wayland/wayland.pro
@@ -22,35 +22,16 @@ HEADERS = qwaylandintegration.h \
qwaylandwindow.h \
qwaylandscreen.h \
qwaylandshmsurface.h \
- qwaylanddrmsurface.h \
qwaylandbuffer.h \
- qwaylandinclude.h \
- qwaylandeglwindow.h \
qwaylandshmwindow.h
INCLUDEPATH += $$QMAKE_INCDIR_WAYLAND
LIBS += $$QMAKE_LIBS_WAYLAND
QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_WAYLAND
-contains(QT_CONFIG, opengles2) {
- QT += opengl
- LIBS += -lwayland-egl -lEGL
+INCLUDEPATH += $$PWD
- SOURCES += qwaylanddrmsurface.cpp \
- qwaylandglcontext.cpp \
- ../eglconvenience/qeglconvenience.cpp \
- qwaylandeglwindow.cpp
-
- HEADERS += qwaylandglcontext.h \
- ../eglconvenience/qeglconvenience.h \
-
- DEFINES += QT_WAYLAND_GL_SUPPORT
-}
-
-unix:isEmpty(QMAKE_INCDIR_WAYLAND) {
- CONFIG += link_pkgconfig
- PKGCONFIG += libdrm
-}
+include ($$PWD/gl_integration/gl_integration.pri)
include (../fontdatabases/genericunix/genericunix.pri)
diff --git a/src/plugins/platforms/xcb/README b/src/plugins/platforms/xcb/README
index e88596b..17a86e6 100644
--- a/src/plugins/platforms/xcb/README
+++ b/src/plugins/platforms/xcb/README
@@ -1,2 +1,3 @@
Required packages:
-libxcb1 libxcb1-dev libx11-xcb1 libx11-xcb-dev libxcb-keysyms1 libxcb-keysyms1-dev libxcb-image0 libxcb-image0-dev libxcb-shm0 libxcb-shm0-dev libxcb-icccm1 libxcb-icccm1-dev
+libxcb1 libxcb1-dev libx11-xcb1 libx11-xcb-dev libxcb-keysyms1 libxcb-keysyms1-dev libxcb-image0 libxcb-image0-dev libxcb-shm0 libxcb-shm0-dev libxcb-icccm1 libxcb-icccm1-dev libxcb-sync0 libxcb-sync0-dev
+
diff --git a/src/plugins/platforms/xcb/qdri2context.cpp b/src/plugins/platforms/xcb/qdri2context.cpp
index 0079f91..dbbfa67 100644
--- a/src/plugins/platforms/xcb/qdri2context.cpp
+++ b/src/plugins/platforms/xcb/qdri2context.cpp
@@ -266,6 +266,6 @@ xcb_dri2_dri2_buffer_t * QDri2Context::backBuffer()
void * QDri2Context::eglContext() const
{
- Q_D(QDri2Context);
+ Q_D(const QDri2Context);
return d->eglContext;
}
diff --git a/src/plugins/platforms/xcb/qglxintegration.cpp b/src/plugins/platforms/xcb/qglxintegration.cpp
index e94b6a6..190221c 100644
--- a/src/plugins/platforms/xcb/qglxintegration.cpp
+++ b/src/plugins/platforms/xcb/qglxintegration.cpp
@@ -51,218 +51,29 @@
#include <GL/glx.h>
#include "qglxintegration.h"
+#include "qglxconvenience.h"
#if defined(Q_OS_LINUX) || defined(Q_OS_BSD4)
#include <dlfcn.h>
#endif
-QMutex QGLXContext::m_defaultSharedContextMutex(QMutex::Recursive);
-
-QVector<int> QGLXContext::buildSpec(const QPlatformWindowFormat &format)
-{
- QVector<int> spec(48);
- int i = 0;
-
- spec[i++] = GLX_LEVEL;
- spec[i++] = 0;
- spec[i++] = GLX_DRAWABLE_TYPE; spec[i++] = GLX_WINDOW_BIT;
-
- if (format.rgba()) {
- spec[i++] = GLX_RENDER_TYPE; spec[i++] = GLX_RGBA_BIT;
- spec[i++] = GLX_RED_SIZE; spec[i++] = (format.redBufferSize() == -1) ? 1 : format.redBufferSize();
- spec[i++] = GLX_GREEN_SIZE; spec[i++] = (format.greenBufferSize() == -1) ? 1 : format.greenBufferSize();
- spec[i++] = GLX_BLUE_SIZE; spec[i++] = (format.blueBufferSize() == -1) ? 1 : format.blueBufferSize();
- if (format.alpha()) {
- 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.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;
- }
-
- spec[i++] = GLX_DOUBLEBUFFER; spec[i++] = format.doubleBuffer() ? True : False;
- spec[i++] = GLX_STEREO; spec[i++] = format.stereo() ? True : False;
-
- if (format.depth()) {
- spec[i++] = GLX_DEPTH_SIZE; spec[i++] = (format.depthBufferSize() == -1) ? 1 : format.depthBufferSize();
- }
-
- if (format.stencil()) {
- spec[i++] = GLX_STENCIL_SIZE; spec[i++] = (format.stencilBufferSize() == -1) ? 1 : format.stencilBufferSize();
- }
- if (format.sampleBuffers()) {
- spec[i++] = GLX_SAMPLE_BUFFERS_ARB;
- spec[i++] = 1;
- spec[i++] = GLX_SAMPLES_ARB;
- spec[i++] = format.samples() == -1 ? 4 : format.samples();
- }
-
- spec[i++] = None;
- return spec;
-}
-
-GLXFBConfig QGLXContext::findConfig(const QXcbScreen *screen, const QPlatformWindowFormat &format)
-{
- bool reduced = true;
- GLXFBConfig chosenConfig = 0;
- QPlatformWindowFormat reducedFormat = format;
- while (!chosenConfig && reduced) {
- QVector<int> spec = buildSpec(reducedFormat);
- int confcount = 0;
- GLXFBConfig *configs;
- configs = glXChooseFBConfig(DISPLAY_FROM_XCB(screen), screen->screenNumber(), spec.constData(), &confcount);
- if (confcount)
- {
- for (int i = 0; i < confcount; i++) {
- chosenConfig = configs[i];
- // Make sure we try to get an ARGB visual if the format asked for an alpha:
- if (reducedFormat.alpha()) {
- int alphaSize;
- glXGetFBConfigAttrib(DISPLAY_FROM_XCB(screen), configs[i], GLX_ALPHA_SIZE, &alphaSize);
- if (alphaSize > 0)
- break;
- } else {
- break; // Just choose the first in the list if there's no alpha requested
- }
- }
-
- XFree(configs);
- }
- reducedFormat = reducePlatformWindowFormat(reducedFormat,&reduced);
- }
-
- if (!chosenConfig)
- qWarning("Warning no context created");
-
- return chosenConfig;
-}
-
-XVisualInfo *QGLXContext::findVisualInfo(const QXcbScreen *screen, const QPlatformWindowFormat &format)
-{
- GLXFBConfig config = QGLXContext::findConfig(screen,format);
- XVisualInfo *visualInfo = glXGetVisualFromFBConfig(DISPLAY_FROM_XCB(screen), config);
- return visualInfo;
-}
-
-QPlatformWindowFormat QGLXContext::platformWindowFromGLXFBConfig(Display *display, GLXFBConfig config, GLXContext ctx)
-{
- QPlatformWindowFormat format;
- int redSize = 0;
- int greenSize = 0;
- int blueSize = 0;
- int alphaSize = 0;
- int depthSize = 0;
- int stencilSize = 0;
- int sampleBuffers = 0;
- int sampleCount = 0;
- int level = 0;
- int rgba = 0;
- int stereo = 0;
- int accumSizeA = 0;
- int accumSizeR = 0;
- int accumSizeG = 0;
- int accumSizeB = 0;
-
- XVisualInfo *vi = glXGetVisualFromFBConfig(display,config);
- glXGetConfig(display,vi,GLX_RGBA,&rgba);
- XFree(vi);
- glXGetFBConfigAttrib(display, config, GLX_RED_SIZE, &redSize);
- glXGetFBConfigAttrib(display, config, GLX_GREEN_SIZE, &greenSize);
- glXGetFBConfigAttrib(display, config, GLX_BLUE_SIZE, &blueSize);
- glXGetFBConfigAttrib(display, config, GLX_ALPHA_SIZE, &alphaSize);
- glXGetFBConfigAttrib(display, config, GLX_DEPTH_SIZE, &depthSize);
- glXGetFBConfigAttrib(display, config, GLX_STENCIL_SIZE, &stencilSize);
- glXGetFBConfigAttrib(display, config, GLX_SAMPLES, &sampleBuffers);
- glXGetFBConfigAttrib(display, config, GLX_LEVEL, &level);
- glXGetFBConfigAttrib(display, config, GLX_STEREO, &stereo);
- glXGetFBConfigAttrib(display, config, GLX_ACCUM_ALPHA_SIZE, &accumSizeA);
- glXGetFBConfigAttrib(display, config, GLX_ACCUM_RED_SIZE, &accumSizeR);
- glXGetFBConfigAttrib(display, config, GLX_ACCUM_GREEN_SIZE, &accumSizeG);
- glXGetFBConfigAttrib(display, config, GLX_ACCUM_BLUE_SIZE, &accumSizeB);
-
- format.setRedBufferSize(redSize);
- format.setGreenBufferSize(greenSize);
- format.setBlueBufferSize(blueSize);
- format.setAlphaBufferSize(alphaSize);
- format.setDepthBufferSize(depthSize);
- format.setStencilBufferSize(stencilSize);
- format.setSampleBuffers(sampleBuffers);
- if (format.sampleBuffers()) {
- glXGetFBConfigAttrib(display, config, GLX_SAMPLES_ARB, &sampleCount);
- format.setSamples(sampleCount);
- }
-
- format.setDirectRendering(glXIsDirect(display, ctx));
- format.setRgba(rgba);
- format.setStereo(stereo);
- format.setAccumBufferSize(accumSizeB);
-
- return format;
-}
-
-QPlatformWindowFormat QGLXContext::reducePlatformWindowFormat(const QPlatformWindowFormat &format, bool *reduced)
-{
- QPlatformWindowFormat retFormat = format;
- *reduced = true;
-
- if (retFormat.sampleBuffers()) {
- retFormat.setSampleBuffers(false);
- } else if (retFormat.stereo()) {
- retFormat.setStereo(false);
- } else if (retFormat.accum()) {
- retFormat.setAccum(false);
- }else if (retFormat.stencil()) {
- retFormat.setStencil(false);
- }else if (retFormat.alpha()) {
- retFormat.setAlpha(false);
- }else if (retFormat.depth()) {
- retFormat.setDepth(false);
- }else if (retFormat.doubleBuffer()) {
- retFormat.setDoubleBuffer(false);
- }else{
- *reduced = false;
- }
- return retFormat;
-}
-
QGLXContext::QGLXContext(Window window, QXcbScreen *screen, const QPlatformWindowFormat &format)
: QPlatformGLContext()
, m_screen(screen)
, m_drawable((Drawable)window)
, m_context(0)
{
-
+ Q_XCB_NOOP(m_screen->connection());
const QPlatformGLContext *sharePlatformContext;
- if (format.useDefaultSharedContext()) {
- if (!QPlatformGLContext::defaultSharedContext()) {
- if (m_defaultSharedContextMutex.tryLock()){
- createDefaultSharedContex(screen);
- m_defaultSharedContextMutex.unlock();
- } else {
- m_defaultSharedContextMutex.lock(); //wait to the the shared context is created
- m_defaultSharedContextMutex.unlock();
- }
- }
- sharePlatformContext = QPlatformGLContext::defaultSharedContext();
- } else {
- sharePlatformContext = format.sharedGLContext();
- }
+ sharePlatformContext = format.sharedGLContext();
GLXContext shareGlxContext = 0;
if (sharePlatformContext)
shareGlxContext = static_cast<const QGLXContext*>(sharePlatformContext)->glxContext();
- GLXFBConfig config = findConfig(screen,format);
+ GLXFBConfig config = qglx_findConfig(DISPLAY_FROM_XCB(screen),screen->screenNumber(),format);
m_context = glXCreateNewContext(DISPLAY_FROM_XCB(screen), config, GLX_RGBA_TYPE, shareGlxContext, TRUE);
- m_windowFormat = QGLXContext::platformWindowFromGLXFBConfig(DISPLAY_FROM_XCB(screen), config, m_context);
+ m_windowFormat = qglx_platformWindowFromGLXFBConfig(DISPLAY_FROM_XCB(screen), config, m_context);
+ Q_XCB_NOOP(m_screen->connection());
}
QGLXContext::QGLXContext(QXcbScreen *screen, Drawable drawable, GLXContext context)
@@ -273,56 +84,39 @@ QGLXContext::QGLXContext(QXcbScreen *screen, Drawable drawable, GLXContext conte
QGLXContext::~QGLXContext()
{
+ Q_XCB_NOOP(m_screen->connection());
if (m_context)
glXDestroyContext(DISPLAY_FROM_XCB(m_screen), m_context);
-}
-
-void QGLXContext::createDefaultSharedContex(QXcbScreen *screen)
-{
- int x = 0;
- int y = 0;
- int w = 3;
- int h = 3;
-
- QPlatformWindowFormat format = QPlatformWindowFormat::defaultFormat();
- GLXContext context;
- GLXFBConfig config = findConfig(screen,format);
- if (config) {
- XVisualInfo *visualInfo = glXGetVisualFromFBConfig(DISPLAY_FROM_XCB(screen), config);
- Colormap cmap = XCreateColormap(DISPLAY_FROM_XCB(screen), screen->root(), visualInfo->visual, AllocNone);
- XSetWindowAttributes a;
- a.colormap = cmap;
- Window sharedWindow = XCreateWindow(DISPLAY_FROM_XCB(screen), screen->root(), x, y, w, h,
- 0, visualInfo->depth, InputOutput, visualInfo->visual,
- CWColormap, &a);
-
- context = glXCreateNewContext(DISPLAY_FROM_XCB(screen), config, GLX_RGBA_TYPE, 0, TRUE);
- QPlatformGLContext *sharedContext = new QGLXContext(screen, sharedWindow, context);
- QPlatformGLContext::setDefaultSharedContext(sharedContext);
- } else {
- qWarning("Warning no shared context created");
- }
+ Q_XCB_NOOP(m_screen->connection());
}
void QGLXContext::makeCurrent()
{
+ Q_XCB_NOOP(m_screen->connection());
QPlatformGLContext::makeCurrent();
glXMakeCurrent(DISPLAY_FROM_XCB(m_screen), m_drawable, m_context);
+ Q_XCB_NOOP(m_screen->connection());
}
void QGLXContext::doneCurrent()
{
+ Q_XCB_NOOP(m_screen->connection());
QPlatformGLContext::doneCurrent();
glXMakeCurrent(DISPLAY_FROM_XCB(m_screen), 0, 0);
+ Q_XCB_NOOP(m_screen->connection());
}
void QGLXContext::swapBuffers()
{
+ Q_XCB_NOOP(m_screen->connection());
glXSwapBuffers(DISPLAY_FROM_XCB(m_screen), m_drawable);
+ doneCurrent();
+ Q_XCB_NOOP(m_screen->connection());
}
void* QGLXContext::getProcAddress(const QString& procName)
{
+ Q_XCB_NOOP(m_screen->connection());
typedef void *(*qt_glXGetProcAddressARB)(const GLubyte *);
static qt_glXGetProcAddressARB glXGetProcAddressARB = 0;
static bool resolved = false;
diff --git a/src/plugins/platforms/xcb/qglxintegration.h b/src/plugins/platforms/xcb/qglxintegration.h
index f2e20c4..99b72a0 100644
--- a/src/plugins/platforms/xcb/qglxintegration.h
+++ b/src/plugins/platforms/xcb/qglxintegration.h
@@ -66,22 +66,13 @@ public:
QPlatformWindowFormat platformWindowFormat() const;
- static XVisualInfo *findVisualInfo(const QXcbScreen *xd, const QPlatformWindowFormat &format);
-
private:
- static GLXFBConfig findConfig(const QXcbScreen *xd,const QPlatformWindowFormat &format);
- static QVector<int> buildSpec(const QPlatformWindowFormat &format);
- static QPlatformWindowFormat platformWindowFromGLXFBConfig(Display *display, GLXFBConfig config, GLXContext context);
- static QPlatformWindowFormat reducePlatformWindowFormat(const QPlatformWindowFormat &format, bool *reduced);
-
QXcbScreen *m_screen;
Drawable m_drawable;
GLXContext m_context;
QPlatformWindowFormat m_windowFormat;
QGLXContext (QXcbScreen *screen, Drawable drawable, GLXContext context);
- static QMutex m_defaultSharedContextMutex;
- static void createDefaultSharedContex(QXcbScreen *xd);
};
#endif
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
index 191699b..7ad12fe 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
@@ -47,6 +47,7 @@
#include <QtAlgorithms>
#include <QSocketNotifier>
#include <QtGui/private/qapplication_p.h>
+#include <QAbstractEventDispatcher>
#include <QtCore/QDebug>
@@ -104,6 +105,8 @@ QXcbConnection::QXcbConnection(const char *displayName)
#endif //XCB_USE_XLIB
m_setup = xcb_get_setup(xcb_connection());
+ initializeAllAtoms();
+
xcb_screen_iterator_t it = xcb_setup_roots_iterator(m_setup);
int screenNumber = 0;
@@ -112,16 +115,19 @@ QXcbConnection::QXcbConnection(const char *displayName)
xcb_screen_next(&it);
}
- QSocketNotifier *socket = new QSocketNotifier(xcb_get_file_descriptor(xcb_connection()), QSocketNotifier::Read, this);
- connect(socket, SIGNAL(activated(int)), this, SLOT(eventDispatcher()));
-
m_keyboard = new QXcbKeyboard(this);
- initializeAllAtoms();
-
#ifdef XCB_USE_DRI2
initializeDri2();
#endif
+
+ QSocketNotifier *notifier = new QSocketNotifier(xcb_get_file_descriptor(xcb_connection()), QSocketNotifier::Read, this);
+ connect(notifier, SIGNAL(activated(int)), this, SLOT(processXcbEvents()));
+
+ QAbstractEventDispatcher *dispatcher = QAbstractEventDispatcher::instance(qApp->thread());
+ connect(dispatcher, SIGNAL(aboutToBlock()), this, SLOT(processXcbEvents()));
+
+ sync();
}
QXcbConnection::~QXcbConnection()
@@ -148,8 +154,11 @@ QXcbWindow *platformWindowFromId(xcb_window_t id)
#define HANDLE_PLATFORM_WINDOW_EVENT(event_t, window, handler) \
{ \
event_t *e = (event_t *)event; \
- if (QXcbWindow *platformWindow = platformWindowFromId(e->window)) \
- platformWindow->handler(e); \
+ if (QXcbWindow *platformWindow = platformWindowFromId(e->window)) { \
+ QObjectPrivate *d = QObjectPrivate::get(platformWindow->widget()); \
+ if (!d->wasDeleted) \
+ platformWindow->handler(e); \
+ } \
} \
break;
@@ -166,9 +175,9 @@ break;
void printXcbEvent(const char *message, xcb_generic_event_t *event)
{
#ifdef XCB_EVENT_DEBUG
-#define PRINT_XCB_EVENT(event) \
- case event: \
- printf("%s: %d - %s\n", message, event, #event); \
+#define PRINT_XCB_EVENT(ev) \
+ case ev: \
+ printf("%s: %d - %s - sequence: %d\n", message, int(ev), #ev, event->sequence); \
break;
switch (event->response_type & ~0x80) {
@@ -205,7 +214,7 @@ void printXcbEvent(const char *message, xcb_generic_event_t *event)
PRINT_XCB_EVENT(XCB_CLIENT_MESSAGE);
PRINT_XCB_EVENT(XCB_MAPPING_NOTIFY);
default:
- printf("%s: %d - %s\n", message, event->response_type, "unknown");
+ printf("%s: unknown event - response_type: %d - sequence: %d\n", message, int(event->response_type & ~0x80), int(event->sequence));
}
#else
Q_UNUSED(message);
@@ -213,11 +222,216 @@ void printXcbEvent(const char *message, xcb_generic_event_t *event)
#endif
}
-void QXcbConnection::eventDispatcher()
+const char *xcb_errors[] =
+{
+ "Success",
+ "BadRequest",
+ "BadValue",
+ "BadWindow",
+ "BadPixmap",
+ "BadAtom",
+ "BadCursor",
+ "BadFont",
+ "BadMatch",
+ "BadDrawable",
+ "BadAccess",
+ "BadAlloc",
+ "BadColor",
+ "BadGC",
+ "BadIDChoice",
+ "BadName",
+ "BadLength",
+ "BadImplementation",
+ "Unknown"
+};
+
+const char *xcb_protocol_request_codes[] =
+{
+ "Null",
+ "CreateWindow",
+ "ChangeWindowAttributes",
+ "GetWindowAttributes",
+ "DestroyWindow",
+ "DestroySubwindows",
+ "ChangeSaveSet",
+ "ReparentWindow",
+ "MapWindow",
+ "MapSubwindows",
+ "UnmapWindow",
+ "UnmapSubwindows",
+ "ConfigureWindow",
+ "CirculateWindow",
+ "GetGeometry",
+ "QueryTree",
+ "InternAtom",
+ "GetAtomName",
+ "ChangeProperty",
+ "DeleteProperty",
+ "GetProperty",
+ "ListProperties",
+ "SetSelectionOwner",
+ "GetSelectionOwner",
+ "ConvertSelection",
+ "SendEvent",
+ "GrabPointer",
+ "UngrabPointer",
+ "GrabButton",
+ "UngrabButton",
+ "ChangeActivePointerGrab",
+ "GrabKeyboard",
+ "UngrabKeyboard",
+ "GrabKey",
+ "UngrabKey",
+ "AllowEvents",
+ "GrabServer",
+ "UngrabServer",
+ "QueryPointer",
+ "GetMotionEvents",
+ "TranslateCoords",
+ "WarpPointer",
+ "SetInputFocus",
+ "GetInputFocus",
+ "QueryKeymap",
+ "OpenFont",
+ "CloseFont",
+ "QueryFont",
+ "QueryTextExtents",
+ "ListFonts",
+ "ListFontsWithInfo",
+ "SetFontPath",
+ "GetFontPath",
+ "CreatePixmap",
+ "FreePixmap",
+ "CreateGC",
+ "ChangeGC",
+ "CopyGC",
+ "SetDashes",
+ "SetClipRectangles",
+ "FreeGC",
+ "ClearArea",
+ "CopyArea",
+ "CopyPlane",
+ "PolyPoint",
+ "PolyLine",
+ "PolySegment",
+ "PolyRectangle",
+ "PolyArc",
+ "FillPoly",
+ "PolyFillRectangle",
+ "PolyFillArc",
+ "PutImage",
+ "GetImage",
+ "PolyText8",
+ "PolyText16",
+ "ImageText8",
+ "ImageText16",
+ "CreateColormap",
+ "FreeColormap",
+ "CopyColormapAndFree",
+ "InstallColormap",
+ "UninstallColormap",
+ "ListInstalledColormaps",
+ "AllocColor",
+ "AllocNamedColor",
+ "AllocColorCells",
+ "AllocColorPlanes",
+ "FreeColors",
+ "StoreColors",
+ "StoreNamedColor",
+ "QueryColors",
+ "LookupColor",
+ "CreateCursor",
+ "CreateGlyphCursor",
+ "FreeCursor",
+ "RecolorCursor",
+ "QueryBestSize",
+ "QueryExtension",
+ "ListExtensions",
+ "ChangeKeyboardMapping",
+ "GetKeyboardMapping",
+ "ChangeKeyboardControl",
+ "GetKeyboardControl",
+ "Bell",
+ "ChangePointerControl",
+ "GetPointerControl",
+ "SetScreenSaver",
+ "GetScreenSaver",
+ "ChangeHosts",
+ "ListHosts",
+ "SetAccessControl",
+ "SetCloseDownMode",
+ "KillClient",
+ "RotateProperties",
+ "ForceScreenSaver",
+ "SetPointerMapping",
+ "GetPointerMapping",
+ "SetModifierMapping",
+ "GetModifierMapping",
+ "Unknown"
+};
+
+#ifdef Q_XCB_DEBUG
+void QXcbConnection::log(const char *file, int line, int sequence)
+{
+ CallInfo info;
+ info.sequence = sequence;
+ info.file = file;
+ info.line = line;
+ m_callLog << info;
+}
+#endif
+
+void QXcbConnection::handleXcbError(xcb_generic_error_t *error)
+{
+ uint clamped_error_code = qMin<uint>(error->error_code, (sizeof(xcb_errors) / sizeof(xcb_errors[0])) - 1);
+ uint clamped_major_code = qMin<uint>(error->major_code, (sizeof(xcb_protocol_request_codes) / sizeof(xcb_protocol_request_codes[0])) - 1);
+
+ printf("XCB error: %d (%s), sequence: %d, resource id: %d, major code: %d (%s), minor code: %d\n",
+ int(error->error_code), xcb_errors[clamped_error_code],
+ int(error->sequence), int(error->resource_id),
+ int(error->major_code), xcb_protocol_request_codes[clamped_major_code],
+ int(error->minor_code));
+#ifdef Q_XCB_DEBUG
+ int i = 0;
+ for (; i < m_callLog.size(); ++i) {
+ if (m_callLog.at(i).sequence == error->sequence) {
+ printf("Caused by: %s:%d\n", qPrintable(m_callLog.at(i).file), m_callLog.at(i).line);
+ break;
+ } else if (m_callLog.at(i).sequence > error->sequence) {
+ printf("Caused some time before: %s:%d\n", qPrintable(m_callLog.at(i).file), m_callLog.at(i).line);
+ if (i > 0)
+ printf("and after: %s:%d\n", qPrintable(m_callLog.at(i-1).file), m_callLog.at(i-1).line);
+ break;
+ }
+ }
+ if (i == m_callLog.size() && !m_callLog.isEmpty())
+ printf("Caused some time after: %s:%d\n", qPrintable(m_callLog.first().file), m_callLog.first().line);
+#endif
+}
+
+void QXcbConnection::processXcbEvents()
{
while (xcb_generic_event_t *event = xcb_poll_for_event(xcb_connection())) {
bool handled = true;
- switch (event->response_type & ~0x80) {
+
+ uint response_type = event->response_type & ~0x80;
+
+ if (!response_type) {
+ handleXcbError((xcb_generic_error_t *)event);
+ continue;
+ }
+
+#ifdef Q_XCB_DEBUG
+ {
+ int i = 0;
+ for (; i < m_callLog.size(); ++i)
+ if (m_callLog.at(i).sequence >= event->sequence)
+ break;
+ m_callLog.remove(0, i);
+ }
+#endif
+
+ switch (response_type) {
case XCB_EXPOSE:
HANDLE_PLATFORM_WINDOW_EVENT(xcb_expose_event_t, window, handleExposeEvent);
case XCB_BUTTON_PRESS:
@@ -247,13 +461,15 @@ void QXcbConnection::eventDispatcher()
break;
default:
handled = false;
- return;
+ break;
}
if (handled)
printXcbEvent("Handled XCB event", event);
else
printXcbEvent("Unhandled XCB event", event);
}
+
+ xcb_flush(xcb_connection());
}
static const char * xcb_atomnames = {
@@ -447,6 +663,13 @@ void QXcbConnection::initializeAllAtoms() {
m_allAtoms[i] = xcb_intern_atom_reply(xcb_connection(), cookies[i], 0)->atom;
}
+void QXcbConnection::sync()
+{
+ // from xcb_aux_sync
+ xcb_get_input_focus_cookie_t cookie = Q_XCB_CALL(xcb_get_input_focus(xcb_connection()));
+ free(xcb_get_input_focus_reply(xcb_connection(), cookie, 0));
+}
+
#if defined(XCB_USE_EGL)
bool QXcbConnection::hasEgl() const
{
diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h
index e00fbb1..6b5f810 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.h
+++ b/src/plugins/platforms/xcb/qxcbconnection.h
@@ -46,6 +46,9 @@
#include <QList>
#include <QObject>
+#include <QVector>
+
+#define Q_XCB_DEBUG
class QXcbScreen;
@@ -221,6 +224,8 @@ public:
QXcbConnection(const char *displayName = 0);
~QXcbConnection();
+ QXcbConnection *connection() const { return const_cast<QXcbConnection *>(this); }
+
QList<QXcbScreen *> screens() const { return m_screens; }
int primaryScreen() const { return m_primaryScreen; }
@@ -247,11 +252,15 @@ public:
void *egl_display() const { return m_egl_display; }
#endif
+ void sync();
+ void handleXcbError(xcb_generic_error_t *error);
+
private slots:
- void eventDispatcher();
+ void processXcbEvents();
private:
void initializeAllAtoms();
+ void sendConnectionEvent(QXcbAtom::Atom atom, uint id = 0);
#ifdef XCB_USE_DRI2
void initializeDri2();
#endif
@@ -283,10 +292,38 @@ private:
void *m_egl_display;
bool m_has_egl;
#endif
+#ifdef Q_XCB_DEBUG
+ struct CallInfo {
+ int sequence;
+ QByteArray file;
+ int line;
+ };
+ QVector<CallInfo> m_callLog;
+ void log(const char *file, int line, int sequence);
+ template <typename cookie_t>
+ friend cookie_t q_xcb_call_template(const cookie_t &cookie, QXcbConnection *connection, const char *file, int line);
+#endif
};
#define DISPLAY_FROM_XCB(object) ((Display *)(object->connection()->xlib_display()))
+#ifdef Q_XCB_DEBUG
+template <typename cookie_t>
+cookie_t q_xcb_call_template(const cookie_t &cookie, QXcbConnection *connection, const char *file, int line)
+{
+ connection->log(file, line, cookie.sequence);
+ return cookie;
+}
+#define Q_XCB_CALL(x) q_xcb_call_template(x, connection(), __FILE__, __LINE__)
+#define Q_XCB_CALL2(x, connection) q_xcb_call_template(x, connection, __FILE__, __LINE__)
+#define Q_XCB_NOOP(c) q_xcb_call_template(xcb_no_operation(c->xcb_connection()), c, __FILE__, __LINE__);
+#else
+#define Q_XCB_CALL(x) x
+#define Q_XCB_CALL2(x, connection) x
+#define Q_XCB_NOOP(c)
+#endif
+
+
#if defined(XCB_USE_DRI2) || defined(XCB_USE_EGL)
#define EGL_DISPLAY_FROM_XCB(object) ((EGLDisplay)(object->connection()->egl_display()))
#endif //endifXCB_USE_DRI2
diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp
index 63c26a1..9df5f14 100644
--- a/src/plugins/platforms/xcb/qxcbintegration.cpp
+++ b/src/plugins/platforms/xcb/qxcbintegration.cpp
@@ -73,6 +73,15 @@ QXcbIntegration::~QXcbIntegration()
delete m_connection;
}
+bool QXcbIntegration::hasCapability(QPlatformIntegration::Capability cap) const
+{
+ switch (cap) {
+ case ThreadedPixmaps: return true;
+ case OpenGL: return hasOpenGL();
+ default: return QPlatformIntegration::hasCapability(cap);
+ }
+}
+
QPixmapData *QXcbIntegration::createPixmapData(QPixmapData::PixelType type) const
{
return new QRasterPixmapData(type);
diff --git a/src/plugins/platforms/xcb/qxcbintegration.h b/src/plugins/platforms/xcb/qxcbintegration.h
index 6c9634e..d27fd71 100644
--- a/src/plugins/platforms/xcb/qxcbintegration.h
+++ b/src/plugins/platforms/xcb/qxcbintegration.h
@@ -55,6 +55,7 @@ public:
QXcbIntegration();
~QXcbIntegration();
+ bool hasCapability(Capability cap) const;
QPixmapData *createPixmapData(QPixmapData::PixelType type) const;
QPlatformWindow *createPlatformWindow(QWidget *widget, WId winId) const;
QWindowSurface *createWindowSurface(QWidget *widget, WId winId) const;
@@ -65,11 +66,11 @@ public:
QPixmap grabWindow(WId window, int x, int y, int width, int height) const;
QPlatformFontDatabase *fontDatabase() const;
- bool hasOpenGL() const;
QPlatformNativeInterface *nativeInterface()const;
private:
+ bool hasOpenGL() const;
QList<QPlatformScreen *> m_screens;
QXcbConnection *m_connection;
diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
index ec9a009..f501c00 100644
--- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp
+++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
@@ -921,6 +921,8 @@ void QXcbKeyboard::handleKeyEvent(QWidget *widget, QEvent::Type type, xcb_keycod
if (state & 128)
col += altGrOffset;
+ Q_XCB_NOOP(connection());
+
#ifdef XCB_KEYBOARD_DEBUG
printf("key code: %d, state: %d, syms: ", code, state);
for (int i = 0; i <= 5; ++i) {
@@ -929,6 +931,8 @@ void QXcbKeyboard::handleKeyEvent(QWidget *widget, QEvent::Type type, xcb_keycod
printf("\n");
#endif
+ Q_XCB_NOOP(connection());
+
xcb_keysym_t sym = xcb_key_symbols_get_keysym(m_key_symbols, code, col);
if (sym == XCB_NO_SYMBOL)
sym = xcb_key_symbols_get_keysym(m_key_symbols, code, col ^ 0x1);
@@ -940,6 +944,8 @@ void QXcbKeyboard::handleKeyEvent(QWidget *widget, QEvent::Type type, xcb_keycod
sym = toupper(sym);
}
+ Q_XCB_NOOP(connection());
+
QByteArray chars;
Qt::KeyboardModifiers modifiers;
diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp
index fffeb2e..1c12ee3 100644
--- a/src/plugins/platforms/xcb/qxcbscreen.cpp
+++ b/src/plugins/platforms/xcb/qxcbscreen.cpp
@@ -60,13 +60,48 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, xcb_screen_t *screen, int num
const quint32 mask = XCB_CW_EVENT_MASK;
const quint32 values[] = {
// XCB_CW_EVENT_MASK
- XCB_EVENT_MASK_KEYMAP_STATE
- | XCB_EVENT_MASK_ENTER_WINDOW
+ XCB_EVENT_MASK_ENTER_WINDOW
| XCB_EVENT_MASK_LEAVE_WINDOW
| XCB_EVENT_MASK_PROPERTY_CHANGE
};
xcb_change_window_attributes(xcb_connection(), screen->root, mask, values);
+
+ xcb_generic_error_t *error;
+
+ xcb_get_property_reply_t *reply =
+ xcb_get_property_reply(xcb_connection(),
+ xcb_get_property(xcb_connection(), false, screen->root,
+ atom(QXcbAtom::_NET_SUPPORTING_WM_CHECK),
+ XCB_ATOM_WINDOW, 0, 1024), &error);
+
+ if (reply && reply->format == 32 && reply->type == XCB_ATOM_WINDOW) {
+ xcb_window_t windowManager = *((xcb_window_t *)xcb_get_property_value(reply));
+
+ if (windowManager != XCB_WINDOW_NONE) {
+ xcb_get_property_reply_t *windowManagerReply =
+ xcb_get_property_reply(xcb_connection(),
+ xcb_get_property(xcb_connection(), false, windowManager,
+ atom(QXcbAtom::_NET_WM_NAME),
+ atom(QXcbAtom::UTF8_STRING), 0, 1024), &error);
+ if (windowManagerReply && windowManagerReply->format == 8 && windowManagerReply->type == atom(QXcbAtom::UTF8_STRING)) {
+ m_windowManagerName = QString::fromUtf8((const char *)xcb_get_property_value(windowManagerReply), xcb_get_property_value_length(windowManagerReply));
+ printf("Running window manager: %s\n", qPrintable(m_windowManagerName));
+ } else if (error) {
+ connection->handleXcbError(error);
+ free(error);
+ }
+
+ free(windowManagerReply);
+ }
+ } else if (error) {
+ connection->handleXcbError(error);
+ free(error);
+ }
+
+ free(reply);
+
+ m_syncRequestSupported = m_windowManagerName != QLatin1String("KWin");
}
QXcbScreen::~QXcbScreen()
diff --git a/src/plugins/platforms/xcb/qxcbscreen.h b/src/plugins/platforms/xcb/qxcbscreen.h
index 6f69fc7..9547d01 100644
--- a/src/plugins/platforms/xcb/qxcbscreen.h
+++ b/src/plugins/platforms/xcb/qxcbscreen.h
@@ -43,6 +43,7 @@
#define QXCBSCREEN_H
#include <QtGui/QPlatformScreen>
+#include <QtCore/QString>
#include <xcb/xcb.h>
@@ -66,9 +67,14 @@ public:
xcb_screen_t *screen() const { return m_screen; }
xcb_window_t root() const { return m_screen->root; }
+ QString windowManagerName() const { return m_windowManagerName; }
+ bool syncRequestSupported() const { return m_syncRequestSupported; }
+
private:
xcb_screen_t *m_screen;
int m_number;
+ QString m_windowManagerName;
+ bool m_syncRequestSupported;
};
#endif
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index cbf50f7..0456638 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -41,6 +41,8 @@
#include "qxcbwindow.h"
+#include <QtDebug>
+
#include "qxcbconnection.h"
#include "qxcbscreen.h"
#ifdef XCB_USE_DRI2
@@ -63,6 +65,7 @@
#if defined(XCB_USE_GLX)
#include "qglxintegration.h"
+#include "qglxconvenience.h"
#elif defined(XCB_USE_EGL)
#include "../eglconvenience/qeglplatformcontext.h"
#include "../eglconvenience/qeglconvenience.h"
@@ -110,13 +113,14 @@ QXcbWindow::QXcbWindow(QWidget *tlw)
#if defined(XCB_USE_GLX) || defined(XCB_USE_EGL)
if (tlw->platformWindowFormat().windowApi() == QPlatformWindowFormat::OpenGL
- && QApplicationPrivate::platformIntegration()->hasOpenGL() ) {
+ && QApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL))
+ {
#if defined(XCB_USE_GLX)
- XVisualInfo *visualInfo = QGLXContext::findVisualInfo(m_screen, tlw->platformWindowFormat());
+ XVisualInfo *visualInfo = qglx_findVisualInfo(DISPLAY_FROM_XCB(m_screen),m_screen->screenNumber(), tlw->platformWindowFormat());
#elif defined(XCB_USE_EGL)
- EGLDisplay eglDisplay = eglGetDisplay(DISPLAY_FROM_XCB(this));
+ EGLDisplay eglDisplay = connection()->egl_display();
EGLConfig eglConfig = q_configFromQPlatformWindowFormat(eglDisplay,tlw->platformWindowFormat(),true);
- VisualID id = QXlibEglIntegration::getCompatibleVisualId(DISPLAY_FROM_XCB(this),eglConfig);
+ VisualID id = QXlibEglIntegration::getCompatibleVisualId(DISPLAY_FROM_XCB(this), eglDisplay, eglConfig);
XVisualInfo visualInfoTemplate;
memset(&visualInfoTemplate, 0, sizeof(XVisualInfo));
@@ -126,42 +130,42 @@ QXcbWindow::QXcbWindow(QWidget *tlw)
int matchingCount = 0;
visualInfo = XGetVisualInfo(DISPLAY_FROM_XCB(this), VisualIDMask, &visualInfoTemplate, &matchingCount);
#endif //XCB_USE_GLX
- if (visualInfo) {
- Colormap cmap = XCreateColormap(DISPLAY_FROM_XCB(this), m_screen->root(), visualInfo->visual, AllocNone);
-
- XSetWindowAttributes a;
- 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);
-
- printf("created GL window: %d\n", m_window);
- } else {
- qFatal("no window!");
- }
+ if (visualInfo) {
+ Colormap cmap = XCreateColormap(DISPLAY_FROM_XCB(this), m_screen->root(), visualInfo->visual, AllocNone);
+
+ XSetWindowAttributes a;
+ 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);
+
+ printf("created GL window: %d\n", m_window);
+ } else {
+ qFatal("no window!");
+ }
} else
#endif //defined(XCB_USE_GLX) || defined(XCB_USE_EGL)
{
m_window = xcb_generate_id(xcb_connection());
- xcb_create_window(xcb_connection(),
- XCB_COPY_FROM_PARENT, // depth -- same as root
- m_window, // window id
- m_screen->root(), // parent window id
- tlw->x(),
- tlw->y(),
- tlw->width(),
- tlw->height(),
- 0, // border width
- XCB_WINDOW_CLASS_INPUT_OUTPUT, // window class
- m_screen->screen()->root_visual, // visual
- 0, // value mask
- 0); // value list
+ Q_XCB_CALL(xcb_create_window(xcb_connection(),
+ XCB_COPY_FROM_PARENT, // depth -- same as root
+ m_window, // window id
+ m_screen->root(), // parent window id
+ tlw->x(),
+ tlw->y(),
+ tlw->width(),
+ tlw->height(),
+ 0, // border width
+ XCB_WINDOW_CLASS_INPUT_OUTPUT, // window class
+ m_screen->screen()->root_visual, // visual
+ 0, // value mask
+ 0)); // value list
printf("created regular window: %d\n", m_window);
}
- xcb_change_window_attributes(xcb_connection(), m_window, mask, values);
+ Q_XCB_CALL(xcb_change_window_attributes(xcb_connection(), m_window, mask, values));
xcb_atom_t properties[4];
int propertyCount = 0;
@@ -169,32 +173,60 @@ QXcbWindow::QXcbWindow(QWidget *tlw)
properties[propertyCount++] = atom(QXcbAtom::WM_TAKE_FOCUS);
properties[propertyCount++] = atom(QXcbAtom::_NET_WM_PING);
+ if (m_screen->syncRequestSupported())
+ properties[propertyCount++] = atom(QXcbAtom::_NET_WM_SYNC_REQUEST);
+
if (tlw->windowFlags() & Qt::WindowContextHelpButtonHint)
properties[propertyCount++] = atom(QXcbAtom::_NET_WM_CONTEXT_HELP);
- xcb_change_property(xcb_connection(),
- XCB_PROP_MODE_REPLACE,
- m_window,
- atom(QXcbAtom::WM_PROTOCOLS),
- 4,
- 32,
- propertyCount,
- properties);
+ Q_XCB_CALL(xcb_change_property(xcb_connection(),
+ XCB_PROP_MODE_REPLACE,
+ m_window,
+ atom(QXcbAtom::WM_PROTOCOLS),
+ XCB_ATOM_ATOM,
+ 32,
+ propertyCount,
+ properties));
+ m_syncValue.hi = 0;
+ m_syncValue.lo = 0;
+
+ if (m_screen->syncRequestSupported()) {
+ m_syncCounter = xcb_generate_id(xcb_connection());
+ Q_XCB_CALL(xcb_sync_create_counter(xcb_connection(), m_syncCounter, m_syncValue));
+
+ Q_XCB_CALL(xcb_change_property(xcb_connection(),
+ XCB_PROP_MODE_REPLACE,
+ m_window,
+ atom(QXcbAtom::_NET_WM_SYNC_REQUEST_COUNTER),
+ XCB_ATOM_CARDINAL,
+ 32,
+ 1,
+ &m_syncCounter));
+ }
if (isTransient(tlw) && tlw->parentWidget()) {
// ICCCM 4.1.2.6
QWidget *p = tlw->parentWidget()->window();
xcb_window_t parentWindow = p->winId();
- xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window,
- XCB_ATOM_WM_TRANSIENT_FOR, XCB_ATOM_WINDOW, 32,
- 1, &parentWindow);
+ Q_XCB_CALL(xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window,
+ XCB_ATOM_WM_TRANSIENT_FOR, XCB_ATOM_WINDOW, 32,
+ 1, &parentWindow));
}
+
+ // set the PID to let the WM kill the application if unresponsive
+ long pid = getpid();
+ Q_XCB_CALL(xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window,
+ atom(QXcbAtom::_NET_WM_PID), XCB_ATOM_CARDINAL, 32,
+ 1, &pid));
}
QXcbWindow::~QXcbWindow()
{
- xcb_destroy_window(xcb_connection(), m_window);
+ delete m_context;
+ if (m_screen->syncRequestSupported())
+ Q_XCB_CALL(xcb_sync_destroy_counter(xcb_connection(), m_syncCounter));
+ Q_XCB_CALL(xcb_destroy_window(xcb_connection(), m_window));
}
void QXcbWindow::setGeometry(const QRect &rect)
@@ -204,7 +236,7 @@ void QXcbWindow::setGeometry(const QRect &rect)
const quint32 mask = XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT;
const quint32 values[] = { rect.x(), rect.y(), rect.width(), rect.height() };
- xcb_configure_window(xcb_connection(), m_window, mask, values);
+ Q_XCB_CALL(xcb_configure_window(xcb_connection(), m_window, mask, values));
}
void QXcbWindow::setVisible(bool visible)
@@ -216,9 +248,10 @@ void QXcbWindow::setVisible(bool visible)
else
xcb_wm_hints_set_normal(&hints);
xcb_set_wm_hints(xcb_connection(), m_window, &hints);
- xcb_map_window(xcb_connection(), m_window);
+ Q_XCB_CALL(xcb_map_window(xcb_connection(), m_window));
+ connection()->sync();
} else {
- xcb_unmap_window(xcb_connection(), m_window);
+ Q_XCB_CALL(xcb_unmap_window(xcb_connection(), m_window));
// send synthetic UnmapNotify event according to icccm 4.1.4
xcb_unmap_notify_event_t event;
@@ -227,8 +260,8 @@ void QXcbWindow::setVisible(bool visible)
event.event = m_screen->root();
event.window = m_window;
event.from_configure = false;
- xcb_send_event(xcb_connection(), false, m_screen->root(),
- XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *)&event);
+ Q_XCB_CALL(xcb_send_event(xcb_connection(), false, m_screen->root(),
+ XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *)&event));
xcb_flush(xcb_connection());
}
@@ -271,6 +304,8 @@ Qt::WindowFlags QXcbWindow::setWindowFlags(Qt::WindowFlags flags)
{
Qt::WindowType type = static_cast<Qt::WindowType>(int(flags & Qt::WindowType_Mask));
+ setNetWmWindowTypes(flags);
+
if (type == Qt::ToolTip)
flags |= Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint;
if (type == Qt::Popup)
@@ -352,28 +387,64 @@ Qt::WindowFlags QXcbWindow::setWindowFlags(Qt::WindowFlags flags)
}
if (mwmhints.flags != 0l) {
- xcb_change_property(xcb_connection(),
- XCB_PROP_MODE_REPLACE,
- m_window,
- atom(QXcbAtom::_MOTIF_WM_HINTS),
- atom(QXcbAtom::_MOTIF_WM_HINTS),
- 32,
- 5,
- &mwmhints);
+ Q_XCB_CALL(xcb_change_property(xcb_connection(),
+ XCB_PROP_MODE_REPLACE,
+ m_window,
+ atom(QXcbAtom::_MOTIF_WM_HINTS),
+ atom(QXcbAtom::_MOTIF_WM_HINTS),
+ 32,
+ 5,
+ &mwmhints));
} else {
- xcb_delete_property(xcb_connection(), m_window, atom(QXcbAtom::_MOTIF_WM_HINTS));
+ Q_XCB_CALL(xcb_delete_property(xcb_connection(), m_window, atom(QXcbAtom::_MOTIF_WM_HINTS)));
}
if (popup || tooltip) {
const quint32 mask = XCB_CW_OVERRIDE_REDIRECT | XCB_CW_SAVE_UNDER;
const quint32 values[] = { true, true };
- xcb_change_window_attributes(xcb_connection(), m_window, mask, values);
+ Q_XCB_CALL(xcb_change_window_attributes(xcb_connection(), m_window, mask, values));
}
return QPlatformWindow::setWindowFlags(flags);
}
+void QXcbWindow::setNetWmWindowTypes(Qt::WindowFlags flags)
+{
+ // in order of decreasing priority
+ QVector<uint> windowTypes;
+
+ Qt::WindowType type = static_cast<Qt::WindowType>(int(flags & Qt::WindowType_Mask));
+
+ switch (type) {
+ case Qt::Dialog:
+ case Qt::Sheet:
+ windowTypes.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_DIALOG));
+ break;
+ case Qt::Tool:
+ case Qt::Drawer:
+ windowTypes.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_UTILITY));
+ break;
+ case Qt::ToolTip:
+ windowTypes.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_TOOLTIP));
+ break;
+ case Qt::SplashScreen:
+ windowTypes.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_SPLASH));
+ break;
+ default:
+ break;
+ }
+
+ if (flags & Qt::FramelessWindowHint)
+ windowTypes.append(atom(QXcbAtom::_KDE_NET_WM_WINDOW_TYPE_OVERRIDE));
+
+ windowTypes.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_NORMAL));
+
+ Q_XCB_CALL(xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window,
+ atom(QXcbAtom::_NET_WM_WINDOW_TYPE), XCB_ATOM_ATOM, 32,
+ windowTypes.count(), windowTypes.constData()));
+}
+
WId QXcbWindow::winId() const
{
return m_window;
@@ -382,56 +453,54 @@ WId QXcbWindow::winId() const
void QXcbWindow::setParent(const QPlatformWindow *parent)
{
QPoint topLeft = geometry().topLeft();
- xcb_reparent_window(xcb_connection(), window(), static_cast<const QXcbWindow *>(parent)->window(), topLeft.x(), topLeft.y());
+ Q_XCB_CALL(xcb_reparent_window(xcb_connection(), window(), static_cast<const QXcbWindow *>(parent)->window(), topLeft.x(), topLeft.y()));
}
void QXcbWindow::setWindowTitle(const QString &title)
{
QByteArray ba = title.toUtf8();
- xcb_change_property (xcb_connection(),
- XCB_PROP_MODE_REPLACE,
- m_window,
- atom(QXcbAtom::_NET_WM_NAME),
- atom(QXcbAtom::UTF8_STRING),
- 8,
- ba.length(),
- ba.constData());
+ Q_XCB_CALL(xcb_change_property(xcb_connection(),
+ XCB_PROP_MODE_REPLACE,
+ m_window,
+ atom(QXcbAtom::_NET_WM_NAME),
+ atom(QXcbAtom::UTF8_STRING),
+ 8,
+ ba.length(),
+ ba.constData()));
}
void QXcbWindow::raise()
{
const quint32 mask = XCB_CONFIG_WINDOW_STACK_MODE;
const quint32 values[] = { XCB_STACK_MODE_ABOVE };
- xcb_configure_window(xcb_connection(), m_window, mask, values);
+ Q_XCB_CALL(xcb_configure_window(xcb_connection(), m_window, mask, values));
}
void QXcbWindow::lower()
{
const quint32 mask = XCB_CONFIG_WINDOW_STACK_MODE;
const quint32 values[] = { XCB_STACK_MODE_BELOW };
- xcb_configure_window(xcb_connection(), m_window, mask, values);
+ Q_XCB_CALL(xcb_configure_window(xcb_connection(), m_window, mask, values));
}
void QXcbWindow::requestActivateWindow()
{
- xcb_set_input_focus(xcb_connection(), m_window, XCB_INPUT_FOCUS_PARENT, XCB_TIME_CURRENT_TIME);
+ Q_XCB_CALL(xcb_set_input_focus(xcb_connection(), XCB_INPUT_FOCUS_PARENT, m_window, XCB_TIME_CURRENT_TIME));
+ connection()->sync();
}
QPlatformGLContext *QXcbWindow::glContext() const
{
- if (!QApplicationPrivate::platformIntegration()->hasOpenGL()) {
+ if (!QApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL)) {
printf("no opengl\n");
return 0;
}
-#if defined(XCB_USE_GLX)
if (!m_context) {
+#if defined(XCB_USE_GLX)
QXcbWindow *that = const_cast<QXcbWindow *>(this);
that->m_context = new QGLXContext(m_window, m_screen, widget()->platformWindowFormat());
- }
#elif defined(XCB_USE_EGL)
- if (!m_context) {
- EGLDisplay display = eglGetDisplay(DISPLAY_FROM_XCB(this));
-
+ EGLDisplay display = connection()->egl_display();
EGLConfig config = q_configFromQPlatformWindowFormat(display,widget()->platformWindowFormat(),true);
QVector<EGLint> eglContextAttrs;
eglContextAttrs.append(EGL_CONTEXT_CLIENT_VERSION);
@@ -441,14 +510,11 @@ QPlatformGLContext *QXcbWindow::glContext() const
EGLSurface eglSurface = eglCreateWindowSurface(display,config,(EGLNativeWindowType)m_window,0);
QXcbWindow *that = const_cast<QXcbWindow *>(this);
that->m_context = new QEGLPlatformContext(display, config, eglContextAttrs.data(), eglSurface, EGL_OPENGL_ES_API);
- }
#elif defined(XCB_USE_DRI2)
- if (!m_context) {
QXcbWindow *that = const_cast<QXcbWindow *>(this);
that->m_context = new QDri2Context(that);
- }
-
#endif
+ }
return m_context;
}
@@ -467,6 +533,21 @@ void QXcbWindow::handleClientMessageEvent(const xcb_client_message_event_t *even
if (event->format == 32 && event->type == atom(QXcbAtom::WM_PROTOCOLS)) {
if (event->data.data32[0] == atom(QXcbAtom::WM_DELETE_WINDOW)) {
QWindowSystemInterface::handleCloseEvent(widget());
+ } else if (event->data.data32[0] == atom(QXcbAtom::_NET_WM_PING)) {
+ xcb_client_message_event_t reply = *event;
+
+ reply.response_type = XCB_CLIENT_MESSAGE;
+ reply.window = m_screen->root();
+
+ xcb_send_event(xcb_connection(), 0, m_screen->root(), XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *)&reply);
+ xcb_flush(xcb_connection());
+ } else if (event->data.data32[0] == atom(QXcbAtom::_NET_WM_SYNC_REQUEST)) {
+ if (!m_hasReceivedSyncRequest) {
+ m_hasReceivedSyncRequest = true;
+ printf("Window manager supports _NET_WM_SYNC_REQUEST, syncing resizes\n");
+ }
+ m_syncValue.lo = event->data.data32[2];
+ m_syncValue.hi = event->data.data32[3];
}
}
}
@@ -482,8 +563,11 @@ void QXcbWindow::handleConfigureNotifyEvent(const xcb_configure_notify_event_t *
}
QRect rect(xpos, ypos, event->width, event->height);
- QPlatformWindow::setGeometry(rect);
+ if (rect == geometry())
+ return;
+
+ QPlatformWindow::setGeometry(rect);
QWindowSystemInterface::handleGeometryChange(widget(), rect);
#if XCB_USE_DRI2
@@ -586,3 +670,14 @@ void QXcbWindow::handleFocusOutEvent(const xcb_focus_out_event_t *)
QWindowSystemInterface::handleWindowActivated(0);
}
+void QXcbWindow::updateSyncRequestCounter()
+{
+ if (m_screen->syncRequestSupported() && (m_syncValue.lo != 0 || m_syncValue.hi != 0)) {
+ Q_XCB_CALL(xcb_sync_set_counter(xcb_connection(), m_syncCounter, m_syncValue));
+ xcb_flush(xcb_connection());
+ connection()->sync();
+
+ m_syncValue.lo = 0;
+ m_syncValue.hi = 0;
+ }
+}
diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h
index 1e9930d..e049837 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.h
+++ b/src/plugins/platforms/xcb/qxcbwindow.h
@@ -46,6 +46,7 @@
#include <QtGui/QPlatformWindowFormat>
#include <xcb/xcb.h>
+#include <xcb/sync.h>
#include "qxcbobject.h"
@@ -88,11 +89,20 @@ public:
void handleMouseEvent(xcb_button_t detail, uint16_t state, xcb_timestamp_t time, const QPoint &local, const QPoint &global);
+ void updateSyncRequestCounter();
+
private:
+ void setNetWmWindowTypes(Qt::WindowFlags flags);
+
QXcbScreen *m_screen;
xcb_window_t m_window;
QPlatformGLContext *m_context;
+
+ xcb_sync_int64_t m_syncValue;
+ xcb_sync_counter_t m_syncCounter;
+
+ bool m_hasReceivedSyncRequest;
};
#endif
diff --git a/src/plugins/platforms/xcb/qxcbwindowsurface.cpp b/src/plugins/platforms/xcb/qxcbwindowsurface.cpp
index 7fed230..718f093 100644
--- a/src/plugins/platforms/xcb/qxcbwindowsurface.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindowsurface.cpp
@@ -53,6 +53,8 @@
#include <stdio.h>
+#include <qdebug.h>
+
class QXcbShmImage : public QXcbObject
{
public:
@@ -84,6 +86,7 @@ QXcbShmImage::QXcbShmImage(QXcbScreen *screen, const QSize &size)
, m_gc(0)
, m_gc_window(0)
{
+ Q_XCB_NOOP(connection());
m_xcb_image = xcb_image_create_native(xcb_connection(),
size.width(),
size.height(),
@@ -92,38 +95,49 @@ QXcbShmImage::QXcbShmImage(QXcbScreen *screen, const QSize &size)
0,
~0,
0);
+
m_shm_info.shmid = shmget (IPC_PRIVATE,
m_xcb_image->stride * m_xcb_image->height, IPC_CREAT|0777);
m_shm_info.shmaddr = m_xcb_image->data = (quint8 *)shmat (m_shm_info.shmid, 0, 0);
m_shm_info.shmseg = xcb_generate_id(xcb_connection());
- xcb_shm_attach(xcb_connection(), m_shm_info.shmseg, m_shm_info.shmid, false);
+ xcb_generic_error_t *error = xcb_request_check(xcb_connection(), xcb_shm_attach_checked(xcb_connection(), m_shm_info.shmseg, m_shm_info.shmid, false));
+ if (error) {
+ qWarning() << "QXcbWindowSurface: Unable to attach to shared memory segment";
+ free(error);
+ }
+
+ 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());
}
void QXcbShmImage::destroy()
{
- xcb_shm_detach(xcb_connection(), m_shm_info.shmseg);
+ Q_XCB_CALL(xcb_shm_detach(xcb_connection(), m_shm_info.shmseg));
xcb_image_destroy(m_xcb_image);
shmdt(m_shm_info.shmaddr);
shmctl(m_shm_info.shmid, IPC_RMID, 0);
-
- xcb_free_gc(xcb_connection(), m_gc);
+ if (m_gc)
+ Q_XCB_CALL(xcb_free_gc(xcb_connection(), m_gc));
}
void QXcbShmImage::put(xcb_window_t window, const QPoint &target, const QRect &source)
{
+ Q_XCB_NOOP(connection());
if (m_gc_window != window) {
- xcb_free_gc(xcb_connection(), m_gc);
+ if (m_gc)
+ Q_XCB_CALL(xcb_free_gc(xcb_connection(), m_gc));
m_gc = xcb_generate_id(xcb_connection());
- xcb_create_gc(xcb_connection(), m_gc, window, 0, 0);
+ Q_XCB_CALL(xcb_create_gc(xcb_connection(), m_gc, window, 0, 0));
m_gc_window = window;
}
+ Q_XCB_NOOP(connection());
xcb_image_shm_put(xcb_connection(),
window,
m_gc,
@@ -136,18 +150,19 @@ void QXcbShmImage::put(xcb_window_t window, const QPoint &target, const QRect &s
source.width(),
source.height(),
false);
+ Q_XCB_NOOP(connection());
m_dirty = m_dirty | source;
xcb_flush(xcb_connection());
+ Q_XCB_NOOP(connection());
}
void QXcbShmImage::preparePaint(const QRegion &region)
{
// to prevent X from reading from the image region while we're writing to it
if (m_dirty.intersects(region)) {
- // from xcb_aux_sync
- free(xcb_get_input_focus_reply(xcb_connection(), xcb_get_input_focus(xcb_connection()), 0));
+ connection()->sync();
m_dirty = QRegion();
}
}
@@ -155,16 +170,15 @@ void QXcbShmImage::preparePaint(const QRegion &region)
QXcbWindowSurface::QXcbWindowSurface(QWidget *widget, bool setDefaultSurface)
: QWindowSurface(widget, setDefaultSurface)
, m_image(0)
+ , m_syncingResize(false)
{
- setStaticContentsSupport(false);
- setPartialUpdateSupport(true);
-
QXcbScreen *screen = static_cast<QXcbScreen *>(QPlatformScreen::platformScreenForWidget(widget));
setConnection(screen->connection());
}
QXcbWindowSurface::~QXcbWindowSurface()
{
+ delete m_image;
}
QPaintDevice *QXcbWindowSurface::paintDevice()
@@ -177,10 +191,18 @@ void QXcbWindowSurface::beginPaint(const QRegion &region)
m_image->preparePaint(region);
}
+void QXcbWindowSurface::endPaint(const QRegion &)
+{
+}
+
void QXcbWindowSurface::flush(QWidget *widget, const QRegion &region, const QPoint &offset)
{
- Q_UNUSED(region);
- Q_UNUSED(offset);
+ QRect bounds = region.boundingRect();
+
+ if (size().isEmpty() || !geometry().contains(bounds))
+ return;
+
+ Q_XCB_NOOP(connection());
QXcbWindow *window = static_cast<QXcbWindow *>(widget->window()->platformWindow());
@@ -190,16 +212,32 @@ void QXcbWindowSurface::flush(QWidget *widget, const QRegion &region, const QPoi
QVector<QRect> rects = region.rects();
for (int i = 0; i < rects.size(); ++i)
m_image->put(window->window(), rects.at(i).topLeft() - widgetOffset, rects.at(i).translated(offset));
+
+ Q_XCB_NOOP(connection());
+
+ if (m_syncingResize) {
+ xcb_flush(xcb_connection());
+ connection()->sync();
+ m_syncingResize = false;
+ window->updateSyncRequestCounter();
+ }
}
void QXcbWindowSurface::resize(const QSize &size)
{
+ if (size == QWindowSurface::size())
+ return;
+
+ Q_XCB_NOOP(connection());
QWindowSurface::resize(size);
QXcbScreen *screen = static_cast<QXcbScreen *>(QPlatformScreen::platformScreenForWidget(window()));
delete m_image;
m_image = new QXcbShmImage(screen, size);
+ Q_XCB_NOOP(connection());
+
+ m_syncingResize = true;
}
extern void qt_scrollRectInImage(QImage &img, const QRect &rect, const QPoint &offset);
diff --git a/src/plugins/platforms/xcb/qxcbwindowsurface.h b/src/plugins/platforms/xcb/qxcbwindowsurface.h
index 61689b1..23d32ef 100644
--- a/src/plugins/platforms/xcb/qxcbwindowsurface.h
+++ b/src/plugins/platforms/xcb/qxcbwindowsurface.h
@@ -62,9 +62,11 @@ public:
bool scroll(const QRegion &area, int dx, int dy);
void beginPaint(const QRegion &);
+ void endPaint(const QRegion &);
private:
QXcbShmImage *m_image;
+ bool m_syncingResize;
};
#endif
diff --git a/src/plugins/platforms/xcb/xcb.pro b/src/plugins/platforms/xcb/xcb.pro
index fdbe2cd..101bdcd 100644
--- a/src/plugins/platforms/xcb/xcb.pro
+++ b/src/plugins/platforms/xcb/xcb.pro
@@ -55,13 +55,14 @@ contains(QT_CONFIG, opengl) {
LIBS += -lEGL
} else {
DEFINES += XCB_USE_GLX
+ include (../glxconvenience/glxconvenience.pri)
HEADERS += qglxintegration.h
SOURCES += qglxintegration.cpp
}
}
}
-LIBS += -lxcb -lxcb-image -lxcb-keysyms -lxcb-icccm
+LIBS += -lxcb -lxcb-image -lxcb-keysyms -lxcb-icccm -lxcb-sync
include (../fontdatabases/genericunix/genericunix.pri)
diff --git a/src/plugins/platforms/xlib/qglxintegration.cpp b/src/plugins/platforms/xlib/qglxintegration.cpp
index 80011d9..7a0f36d 100644
--- a/src/plugins/platforms/xlib/qglxintegration.cpp
+++ b/src/plugins/platforms/xlib/qglxintegration.cpp
@@ -51,6 +51,7 @@
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <GL/glx.h>
+#include "qglxconvenience.h"
#include "qglxintegration.h"
@@ -60,184 +61,6 @@
QT_BEGIN_NAMESPACE
-QMutex QGLXContext::m_defaultSharedContextMutex(QMutex::Recursive);
-
-QVector<int> QGLXContext::buildSpec(const QPlatformWindowFormat &format)
-{
- QVector<int> spec(48);
- int i = 0;
-
- spec[i++] = GLX_LEVEL;
- spec[i++] = 0;
- spec[i++] = GLX_DRAWABLE_TYPE; spec[i++] = GLX_WINDOW_BIT;
-
- if (format.rgba()) {
- spec[i++] = GLX_RENDER_TYPE; spec[i++] = GLX_RGBA_BIT;
- spec[i++] = GLX_RED_SIZE; spec[i++] = (format.redBufferSize() == -1) ? 1 : format.redBufferSize();
- spec[i++] = GLX_GREEN_SIZE; spec[i++] = (format.greenBufferSize() == -1) ? 1 : format.greenBufferSize();
- spec[i++] = GLX_BLUE_SIZE; spec[i++] = (format.blueBufferSize() == -1) ? 1 : format.blueBufferSize();
- if (format.alpha()) {
- 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.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;
- }
-
- spec[i++] = GLX_DOUBLEBUFFER; spec[i++] = format.doubleBuffer() ? True : False;
- spec[i++] = GLX_STEREO; spec[i++] = format.stereo() ? True : False;
-
- if (format.depth()) {
- spec[i++] = GLX_DEPTH_SIZE; spec[i++] = (format.depthBufferSize() == -1) ? 1 : format.depthBufferSize();
- }
-
- if (format.stencil()) {
- spec[i++] = GLX_STENCIL_SIZE; spec[i++] = (format.stencilBufferSize() == -1) ? 1 : format.stencilBufferSize();
- }
- if (format.sampleBuffers()) {
- spec[i++] = GLX_SAMPLE_BUFFERS_ARB;
- spec[i++] = 1;
- spec[i++] = GLX_SAMPLES_ARB;
- spec[i++] = format.samples() == -1 ? 4 : format.samples();
- }
-
- spec[i++] = XNone;
- return spec;
-}
-
-GLXFBConfig QGLXContext::findConfig(const QXlibScreen *screen, const QPlatformWindowFormat &format)
-{
- bool reduced = true;
- GLXFBConfig chosenConfig = 0;
- QPlatformWindowFormat reducedFormat = format;
- while (!chosenConfig && reduced) {
- QVector<int> spec = buildSpec(reducedFormat);
- int confcount = 0;
- GLXFBConfig *configs;
- configs = glXChooseFBConfig(screen->display()->nativeDisplay(),screen->xScreenNumber(),spec.constData(),&confcount);
- if (confcount)
- {
- for (int i = 0; i < confcount; i++) {
- chosenConfig = configs[i];
- // Make sure we try to get an ARGB visual if the format asked for an alpha:
- if (reducedFormat.alpha()) {
- int alphaSize;
- glXGetFBConfigAttrib(screen->display()->nativeDisplay(),configs[i],GLX_ALPHA_SIZE,&alphaSize);
- if (alphaSize > 0)
- break;
- } else {
- break; // Just choose the first in the list if there's no alpha requested
- }
- }
-
- XFree(configs);
- }
- reducedFormat = reducePlatformWindowFormat(reducedFormat,&reduced);
- }
-
- if (!chosenConfig)
- qWarning("Warning no context created");
-
- return chosenConfig;
-}
-
-XVisualInfo *QGLXContext::findVisualInfo(const QXlibScreen *screen, const QPlatformWindowFormat &format)
-{
- GLXFBConfig config = QGLXContext::findConfig(screen,format);
- XVisualInfo *visualInfo = glXGetVisualFromFBConfig(screen->display()->nativeDisplay(),config);
- return visualInfo;
-}
-
-QPlatformWindowFormat QGLXContext::platformWindowFromGLXFBConfig(Display *display, GLXFBConfig config, GLXContext ctx)
-{
- QPlatformWindowFormat format;
- int redSize = 0;
- int greenSize = 0;
- int blueSize = 0;
- int alphaSize = 0;
- int depthSize = 0;
- int stencilSize = 0;
- int sampleBuffers = 0;
- int sampleCount = 0;
- int level = 0;
- int rgba = 0;
- int stereo = 0;
- int accumSizeA = 0;
- int accumSizeR = 0;
- int accumSizeG = 0;
- int accumSizeB = 0;
-
- XVisualInfo *vi = glXGetVisualFromFBConfig(display,config);
- glXGetConfig(display,vi,GLX_RGBA,&rgba);
- XFree(vi);
- glXGetFBConfigAttrib(display, config, GLX_RED_SIZE, &redSize);
- glXGetFBConfigAttrib(display, config, GLX_GREEN_SIZE, &greenSize);
- glXGetFBConfigAttrib(display, config, GLX_BLUE_SIZE, &blueSize);
- glXGetFBConfigAttrib(display, config, GLX_ALPHA_SIZE, &alphaSize);
- glXGetFBConfigAttrib(display, config, GLX_DEPTH_SIZE, &depthSize);
- glXGetFBConfigAttrib(display, config, GLX_STENCIL_SIZE, &stencilSize);
- glXGetFBConfigAttrib(display, config, GLX_SAMPLES, &sampleBuffers);
- glXGetFBConfigAttrib(display, config, GLX_LEVEL, &level);
- glXGetFBConfigAttrib(display, config, GLX_STEREO, &stereo);
- glXGetFBConfigAttrib(display, config, GLX_ACCUM_ALPHA_SIZE, &accumSizeA);
- glXGetFBConfigAttrib(display, config, GLX_ACCUM_RED_SIZE, &accumSizeR);
- glXGetFBConfigAttrib(display, config, GLX_ACCUM_GREEN_SIZE, &accumSizeG);
- glXGetFBConfigAttrib(display, config, GLX_ACCUM_BLUE_SIZE, &accumSizeB);
-
- format.setRedBufferSize(redSize);
- format.setGreenBufferSize(greenSize);
- format.setBlueBufferSize(blueSize);
- format.setAlphaBufferSize(alphaSize);
- format.setDepthBufferSize(depthSize);
- format.setStencilBufferSize(stencilSize);
- format.setSampleBuffers(sampleBuffers);
- if (format.sampleBuffers()) {
- glXGetFBConfigAttrib(display, config, GLX_SAMPLES_ARB, &sampleCount);
- format.setSamples(sampleCount);
- }
-
- format.setDirectRendering(glXIsDirect(display, ctx));
- format.setRgba(rgba);
- format.setStereo(stereo);
- format.setAccumBufferSize(accumSizeB);
-
- return format;
-}
-
-QPlatformWindowFormat QGLXContext::reducePlatformWindowFormat(const QPlatformWindowFormat &format, bool *reduced)
-{
- QPlatformWindowFormat retFormat = format;
- *reduced = true;
-
- if (retFormat.sampleBuffers()) {
- retFormat.setSampleBuffers(false);
- } else if (retFormat.stereo()) {
- retFormat.setStereo(false);
- } else if (retFormat.accum()) {
- retFormat.setAccum(false);
- }else if (retFormat.stencil()) {
- retFormat.setStencil(false);
- }else if (retFormat.alpha()) {
- retFormat.setAlpha(false);
- }else if (retFormat.depth()) {
- retFormat.setDepth(false);
- }else if (retFormat.doubleBuffer()) {
- retFormat.setDoubleBuffer(false);
- }else{
- *reduced = false;
- }
- return retFormat;
-}
-
QGLXContext::QGLXContext(Window window, QXlibScreen *screen, const QPlatformWindowFormat &format)
: QPlatformGLContext()
, m_screen(screen)
@@ -246,27 +69,14 @@ QGLXContext::QGLXContext(Window window, QXlibScreen *screen, const QPlatformWind
{
const QPlatformGLContext *sharePlatformContext;
- if (format.useDefaultSharedContext()) {
- if (!QPlatformGLContext::defaultSharedContext()) {
- if (m_defaultSharedContextMutex.tryLock()){
- createDefaultSharedContex(screen);
- m_defaultSharedContextMutex.unlock();
- } else {
- m_defaultSharedContextMutex.lock(); //wait to the the shared context is created
- m_defaultSharedContextMutex.unlock();
- }
- }
- sharePlatformContext = QPlatformGLContext::defaultSharedContext();
- } else {
- sharePlatformContext = format.sharedGLContext();
- }
+ sharePlatformContext = format.sharedGLContext();
GLXContext shareGlxContext = 0;
if (sharePlatformContext)
shareGlxContext = static_cast<const QGLXContext*>(sharePlatformContext)->glxContext();
- GLXFBConfig config = findConfig(screen,format);
+ GLXFBConfig config = qglx_findConfig(screen->display()->nativeDisplay(),screen->xScreenNumber(),format);
m_context = glXCreateNewContext(screen->display()->nativeDisplay(),config,GLX_RGBA_TYPE,shareGlxContext,TRUE);
- m_windowFormat = QGLXContext::platformWindowFromGLXFBConfig(screen->display()->nativeDisplay(),config,m_context);
+ m_windowFormat = qglx_platformWindowFromGLXFBConfig(screen->display()->nativeDisplay(),config,m_context);
#ifdef MYX11_DEBUG
qDebug() << "QGLXGLContext::create context" << m_context;
@@ -287,33 +97,6 @@ QGLXContext::~QGLXContext()
}
}
-void QGLXContext::createDefaultSharedContex(QXlibScreen *screen)
-{
- int x = 0;
- int y = 0;
- int w = 3;
- int h = 3;
-
- QPlatformWindowFormat format = QPlatformWindowFormat::defaultFormat();
- GLXContext context;
- GLXFBConfig config = findConfig(screen,format);
- if (config) {
- XVisualInfo *visualInfo = glXGetVisualFromFBConfig(screen->display()->nativeDisplay(),config);
- Colormap cmap = XCreateColormap(screen->display()->nativeDisplay(),screen->rootWindow(),visualInfo->visual,AllocNone);
- XSetWindowAttributes a;
- a.colormap = cmap;
- Window sharedWindow = XCreateWindow(screen->display()->nativeDisplay(), screen->rootWindow(),x, y, w, h,
- 0, visualInfo->depth, InputOutput, visualInfo->visual,
- CWColormap, &a);
-
- context = glXCreateNewContext(screen->display()->nativeDisplay(),config,GLX_RGBA_TYPE,0,TRUE);
- QPlatformGLContext *sharedContext = new QGLXContext(screen,sharedWindow,context);
- QPlatformGLContext::setDefaultSharedContext(sharedContext);
- } else {
- qWarning("Warning no shared context created");
- }
-}
-
void QGLXContext::makeCurrent()
{
QPlatformGLContext::makeCurrent();
diff --git a/src/plugins/platforms/xlib/qglxintegration.h b/src/plugins/platforms/xlib/qglxintegration.h
index dbb5c2e..57c716b 100644
--- a/src/plugins/platforms/xlib/qglxintegration.h
+++ b/src/plugins/platforms/xlib/qglxintegration.h
@@ -69,22 +69,13 @@ public:
QPlatformWindowFormat platformWindowFormat() const;
- static XVisualInfo *findVisualInfo(const QXlibScreen *xd, const QPlatformWindowFormat &format);
private:
- static GLXFBConfig findConfig(const QXlibScreen *xd,const QPlatformWindowFormat &format);
- static QVector<int> buildSpec(const QPlatformWindowFormat &format);
- static QPlatformWindowFormat platformWindowFromGLXFBConfig(Display *display, GLXFBConfig config, GLXContext context);
- static QPlatformWindowFormat reducePlatformWindowFormat(const QPlatformWindowFormat &format, bool *reduced);
-
-
QXlibScreen *m_screen;
Drawable m_drawable;
GLXContext m_context;
QPlatformWindowFormat m_windowFormat;
QGLXContext (QXlibScreen *screen, Drawable drawable, GLXContext context);
- static QMutex m_defaultSharedContextMutex;
- static void createDefaultSharedContex(QXlibScreen *xd);
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xlib/qxlibintegration.cpp b/src/plugins/platforms/xlib/qxlibintegration.cpp
index 6733ed1..78f907a 100644
--- a/src/plugins/platforms/xlib/qxlibintegration.cpp
+++ b/src/plugins/platforms/xlib/qxlibintegration.cpp
@@ -49,6 +49,7 @@
#include "qxlibscreen.h"
#include "qxlibclipboard.h"
#include "qxlibdisplay.h"
+#include "qxlibnativeinterface.h"
#if !defined(QT_NO_OPENGL)
#if !defined(QT_OPENGL_ES_2)
@@ -66,11 +67,21 @@ QXlibIntegration::QXlibIntegration(bool useOpenGL)
: mUseOpenGL(useOpenGL)
, mFontDb(new QGenericUnixFontDatabase())
, mClipboard(0)
+ , mNativeInterface(new QXlibNativeInterface)
{
mPrimaryScreen = new QXlibScreen();
mScreens.append(mPrimaryScreen);
}
+bool QXlibIntegration::hasCapability(QPlatformIntegration::Capability cap) const
+{
+ switch (cap) {
+ case ThreadedPixmaps: return true;
+ case OpenGL: return hasOpenGL();
+ default: return QPlatformIntegration::hasCapability(cap);
+ }
+}
+
QPixmapData *QXlibIntegration::createPixmapData(QPixmapData::PixelType type) const
{
#ifndef QT_NO_OPENGL
@@ -130,6 +141,11 @@ QPlatformClipboard * QXlibIntegration::clipboard() const
return mClipboard;
}
+QPlatformNativeInterface * QXlibIntegration::nativeInterface() const
+{
+ return mNativeInterface;
+}
+
bool QXlibIntegration::hasOpenGL() const
{
#if !defined(QT_NO_OPENGL)
@@ -141,11 +157,12 @@ bool QXlibIntegration::hasOpenGL() const
static bool wasEglInitialized = false;
if (!eglHasbeenInitialized) {
eglHasbeenInitialized = true;
- const QXlibScreen *screen = static_cast<const QXlibScreen *>(mScreens.at(0));
+ QXlibScreen *screen = static_cast<QXlibScreen *>(mScreens.at(0));
EGLint major, minor;
eglBindAPI(EGL_OPENGL_ES_API);
EGLDisplay disp = eglGetDisplay(screen->display()->nativeDisplay());
wasEglInitialized = eglInitialize(disp,&major,&minor);
+ screen->setEglDisplay(disp);
}
return wasEglInitialized;
#endif
@@ -153,5 +170,4 @@ bool QXlibIntegration::hasOpenGL() const
return false;
}
-
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xlib/qxlibintegration.h b/src/plugins/platforms/xlib/qxlibintegration.h
index 3bbf897..1a2515a 100644
--- a/src/plugins/platforms/xlib/qxlibintegration.h
+++ b/src/plugins/platforms/xlib/qxlibintegration.h
@@ -47,6 +47,7 @@
#include <QtGui/QPlatformIntegration>
#include <QtGui/QPlatformScreen>
+#include <QtGui/QPlatformNativeInterface>
#include "qxlibstatic.h"
@@ -59,6 +60,7 @@ class QXlibIntegration : public QPlatformIntegration
public:
QXlibIntegration(bool useOpenGL = false);
+ bool hasCapability(Capability cap) const;
QPixmapData *createPixmapData(QPixmapData::PixelType type) const;
QPlatformWindow *createPlatformWindow(QWidget *widget, WId winId) const;
QWindowSurface *createWindowSurface(QWidget *widget, WId winId) const;
@@ -70,14 +72,17 @@ public:
QPlatformFontDatabase *fontDatabase() const;
QPlatformClipboard *clipboard() const;
- bool hasOpenGL() const;
+ QPlatformNativeInterface *nativeInterface() const;
private:
+ bool hasOpenGL() const;
+
bool mUseOpenGL;
QXlibScreen *mPrimaryScreen;
QList<QPlatformScreen *> mScreens;
QPlatformFontDatabase *mFontDb;
QPlatformClipboard *mClipboard;
+ QPlatformNativeInterface *mNativeInterface;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xlib/qxlibnativeinterface.cpp b/src/plugins/platforms/xlib/qxlibnativeinterface.cpp
new file mode 100644
index 0000000..4e950ff
--- /dev/null
+++ b/src/plugins/platforms/xlib/qxlibnativeinterface.cpp
@@ -0,0 +1,133 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxlibnativeinterface.h"
+
+#include "qxlibdisplay.h"
+#include <QtGui/private/qapplication_p.h>
+
+class QXlibResourceMap : public QMap<QByteArray, QXlibNativeInterface::ResourceType>
+{
+public:
+ QXlibResourceMap()
+ :QMap<QByteArray, QXlibNativeInterface::ResourceType>()
+ {
+ insert("display",QXlibNativeInterface::Display);
+ insert("egldisplay",QXlibNativeInterface::EglDisplay);
+ insert("connection",QXlibNativeInterface::Connection);
+ insert("screen",QXlibNativeInterface::Screen);
+ insert("graphicsdevice",QXlibNativeInterface::GraphicsDevice);
+ insert("eglcontext",QXlibNativeInterface::EglContext);
+ }
+};
+
+Q_GLOBAL_STATIC(QXlibResourceMap, qXlibResourceMap)
+
+
+void * QXlibNativeInterface::nativeResourceForWidget(const QByteArray &resourceString, QWidget *widget)
+{
+ QByteArray lowerCaseResource = resourceString.toLower();
+ ResourceType resource = qXlibResourceMap()->value(lowerCaseResource);
+ void *result = 0;
+ switch(resource) {
+ case Display:
+ result = displayForWidget(widget);
+ break;
+ case EglDisplay:
+ result = eglDisplayForWidget(widget);
+ break;
+ case Connection:
+ result = connectionForWidget(widget);
+ break;
+ case Screen:
+ result = reinterpret_cast<void *>(qPlatformScreenForWidget(widget)->xScreenNumber());
+ break;
+ case GraphicsDevice:
+ result = graphicsDeviceForWidget(widget);
+ break;
+ case EglContext:
+ result = eglContextForWidget(widget);
+ break;
+ default:
+ result = 0;
+ }
+ return result;
+}
+
+void * QXlibNativeInterface::displayForWidget(QWidget *widget)
+{
+ return qPlatformScreenForWidget(widget)->display()->nativeDisplay();
+}
+
+void * QXlibNativeInterface::eglDisplayForWidget(QWidget *widget)
+{
+ Q_UNUSED(widget);
+ return 0;
+}
+
+void * QXlibNativeInterface::screenForWidget(QWidget *widget)
+{
+ Q_UNUSED(widget);
+ return 0;
+}
+
+void * QXlibNativeInterface::graphicsDeviceForWidget(QWidget *widget)
+{
+ Q_UNUSED(widget);
+ return 0;
+}
+
+void * QXlibNativeInterface::eglContextForWidget(QWidget *widget)
+{
+ Q_UNUSED(widget);
+ return 0;
+}
+
+QXlibScreen * QXlibNativeInterface::qPlatformScreenForWidget(QWidget *widget)
+{
+ QXlibScreen *screen;
+ if (widget) {
+ screen = static_cast<QXlibScreen *>(QPlatformScreen::platformScreenForWidget(widget));
+ }else {
+ screen = static_cast<QXlibScreen *>(QApplicationPrivate::platformIntegration()->screens()[0]);
+ }
+ return screen;
+}
diff --git a/src/plugins/platforms/xlib/qxlibnativeinterface.h b/src/plugins/platforms/xlib/qxlibnativeinterface.h
new file mode 100644
index 0000000..5ba0768
--- /dev/null
+++ b/src/plugins/platforms/xlib/qxlibnativeinterface.h
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QXLIBNATIVEINTERFACE_H
+#define QXLIBNATIVEINTERFACE_H
+
+#include "qxlibscreen.h"
+
+#include <QtGui/QPlatformNativeInterface>
+
+class QXlibNativeInterface : public QPlatformNativeInterface
+{
+public:
+ enum ResourceType {
+ Display,
+ EglDisplay,
+ Connection,
+ Screen,
+ GraphicsDevice,
+ EglContext
+ };
+
+ void *nativeResourceForWidget(const QByteArray &resourceString, QWidget *widget);
+
+ void *displayForWidget(QWidget *widget);
+ void *eglDisplayForWidget(QWidget *widget);
+ void *connectionForWidget(QWidget *widget);
+ void *screenForWidget(QWidget *widget);
+ void *graphicsDeviceForWidget(QWidget *widget);
+ void *eglContextForWidget(QWidget *widget);
+
+private:
+ static QXlibScreen *qPlatformScreenForWidget(QWidget *widget);
+};
+
+
+#endif // QXLIBNATIVEINTERFACE_H
diff --git a/src/plugins/platforms/xlib/qxlibscreen.cpp b/src/plugins/platforms/xlib/qxlibscreen.cpp
index 23a2d07..7c8a367 100644
--- a/src/plugins/platforms/xlib/qxlibscreen.cpp
+++ b/src/plugins/platforms/xlib/qxlibscreen.cpp
@@ -191,6 +191,9 @@ qDebug() << "qt_x_errhandler" << err->error_code;
QXlibScreen::QXlibScreen()
: mFormat(QImage::Format_RGB32)
+#if !defined(QT_NO_OPENGL) && defined(QT_OPENGL_ES_2)
+ , mEGLDisplay(0)
+#endif
{
char *display_name = getenv("DISPLAY");
Display *display = XOpenDisplay(display_name);
@@ -467,7 +470,7 @@ int QXlibScreen::xScreenNumber() const
Visual * QXlibScreen::defaultVisual() const
{
- DefaultVisual(display()->nativeDisplay(), xScreenNumber());
+ return DefaultVisual(display()->nativeDisplay(), xScreenNumber());
}
QXlibKeyboard * QXlibScreen::keyboard() const
diff --git a/src/plugins/platforms/xlib/qxlibscreen.h b/src/plugins/platforms/xlib/qxlibscreen.h
index 35c0141..8c04c0f 100644
--- a/src/plugins/platforms/xlib/qxlibscreen.h
+++ b/src/plugins/platforms/xlib/qxlibscreen.h
@@ -82,6 +82,11 @@ public:
QXlibKeyboard *keyboard() const;
+#if !defined(QT_NO_OPENGL) && defined(QT_OPENGL_ES_2)
+ void *eglDisplay() const { return mEGLDisplay; }
+ void setEglDisplay(void *display) { mEGLDisplay = display; }
+#endif
+
public slots:
void eventDispatcher();
@@ -96,6 +101,9 @@ private:
QXlibKeyboard *mKeyboard;
QXlibDisplay * mDisplay;
+#if !defined(QT_NO_OPENGL) && defined(QT_OPENGL_ES_2)
+ void *mEGLDisplay;
+#endif
int mScreen;
};
diff --git a/src/plugins/platforms/xlib/qxlibwindow.cpp b/src/plugins/platforms/xlib/qxlibwindow.cpp
index a7bc53c..9a05fc6 100644
--- a/src/plugins/platforms/xlib/qxlibwindow.cpp
+++ b/src/plugins/platforms/xlib/qxlibwindow.cpp
@@ -58,6 +58,7 @@
#if !defined(QT_NO_OPENGL)
#if !defined(QT_OPENGL_ES_2)
#include "qglxintegration.h"
+#include "qglxconvenience.h"
#else
#include "../eglconvenience/qeglconvenience.h"
#include "../eglconvenience/qeglplatformcontext.h"
@@ -80,16 +81,16 @@ QXlibWindow::QXlibWindow(QWidget *window)
int h = window->height();
if(window->platformWindowFormat().windowApi() == QPlatformWindowFormat::OpenGL
- && QApplicationPrivate::platformIntegration()->hasOpenGL() ) {
+ && QApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL) ) {
#if !defined(QT_NO_OPENGL)
#if !defined(QT_OPENGL_ES_2)
- XVisualInfo *visualInfo = QGLXContext::findVisualInfo(mScreen,window->platformWindowFormat());
+ XVisualInfo *visualInfo = qglx_findVisualInfo(mScreen->display()->nativeDisplay(),mScreen->xScreenNumber(),window->platformWindowFormat());
#else
QPlatformWindowFormat windowFormat = correctColorBuffers(window->platformWindowFormat());
- EGLDisplay eglDisplay = eglGetDisplay(mScreen->display()->nativeDisplay());
+ EGLDisplay eglDisplay = mScreen->eglDisplay();
EGLConfig eglConfig = q_configFromQPlatformWindowFormat(eglDisplay,windowFormat);
- VisualID id = QXlibEglIntegration::getCompatibleVisualId(mScreen->display()->nativeDisplay(),eglConfig);
+ VisualID id = QXlibEglIntegration::getCompatibleVisualId(mScreen->display()->nativeDisplay(), eglDisplay, eglConfig);
XVisualInfo visualInfoTemplate;
memset(&visualInfoTemplate, 0, sizeof(XVisualInfo));
@@ -136,7 +137,7 @@ QXlibWindow::QXlibWindow(QWidget *window)
int n = 0;
protocols[n++] = QXlibStatic::atom(QXlibStatic::WM_DELETE_WINDOW); // support del window protocol
protocols[n++] = QXlibStatic::atom(QXlibStatic::WM_TAKE_FOCUS); // support take focus window protocol
- protocols[n++] = QXlibStatic::atom(QXlibStatic::_NET_WM_PING); // support _NET_WM_PING protocol
+// protocols[n++] = QXlibStatic::atom(QXlibStatic::_NET_WM_PING); // support _NET_WM_PING protocol
#ifndef QT_NO_XSYNC
protocols[n++] = QXlibStatic::atom(QXlibStatic::_NET_WM_SYNC_REQUEST); // support _NET_WM_SYNC_REQUEST protocol
#endif // QT_NO_XSYNC
@@ -655,7 +656,7 @@ void QXlibWindow::setCursor(const Cursor &cursor)
QPlatformGLContext *QXlibWindow::glContext() const
{
- if (!QApplicationPrivate::platformIntegration()->hasOpenGL())
+ if (!QApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL))
return 0;
if (!mGLContext) {
QXlibWindow *that = const_cast<QXlibWindow *>(this);
@@ -663,7 +664,7 @@ QPlatformGLContext *QXlibWindow::glContext() const
#if !defined(QT_OPENGL_ES_2)
that->mGLContext = new QGLXContext(x_window, mScreen,widget()->platformWindowFormat());
#else
- EGLDisplay display = eglGetDisplay(mScreen->display()->nativeDisplay());
+ EGLDisplay display = mScreen->eglDisplay();
QPlatformWindowFormat windowFormat = correctColorBuffers(widget()->platformWindowFormat());
diff --git a/src/plugins/platforms/xlib/xlib.pro b/src/plugins/platforms/xlib/xlib.pro
index 159fdbe..ea77a29 100644
--- a/src/plugins/platforms/xlib/xlib.pro
+++ b/src/plugins/platforms/xlib/xlib.pro
@@ -14,7 +14,8 @@ SOURCES = \
qxlibclipboard.cpp \
qxlibmime.cpp \
qxlibstatic.cpp \
- qxlibdisplay.cpp
+ qxlibdisplay.cpp \
+ qxlibnativeinterface.cpp
HEADERS = \
qxlibintegration.h \
@@ -26,7 +27,8 @@ HEADERS = \
qxlibclipboard.h \
qxlibmime.h \
qxlibstatic.h \
- qxlibdisplay.h
+ qxlibdisplay.h \
+ qxlibnativeinterface.h
LIBS += -lX11 -lXext
@@ -39,6 +41,7 @@ include (../fontdatabases/genericunix/genericunix.pri)
contains(QT_CONFIG, opengl) {
QT += opengl
!contains(QT_CONFIG, opengles2) {
+ include (../glxconvenience/glxconvenience.pri)
HEADERS += qglxintegration.h
SOURCES += qglxintegration.cpp
} else { # There is no easy way to detect if we'r suppose to use glx or not
diff --git a/src/plugins/qpluginbase.pri b/src/plugins/qpluginbase.pri
index 45e3976..bcf473f 100644
--- a/src/plugins/qpluginbase.pri
+++ b/src/plugins/qpluginbase.pri
@@ -19,4 +19,23 @@ symbian: {
TARGET.CAPABILITY = All -Tcb
TARGET = $${TARGET}$${QT_LIBINFIX}
load(armcc_warnings)
+
+ # Make partial upgrade SIS file for Qt plugin dll's
+ # Partial upgrade SIS file
+ vendorinfo = \
+ "; Localised Vendor name" \
+ "%{\"Nokia\"}" \
+ " " \
+ "; Unique Vendor name" \
+ ":\"Nokia, Qt\"" \
+ " "
+ isEmpty(QT_LIBINFIX): PARTIAL_UPGRADE_UID = 0x2001E61C
+ else: PARTIAL_UPGRADE_UID = 0xE001E61C
+
+ pu_header = "; Partial upgrade package for testing $${TARGET} changes without reinstalling everything" \
+ "$${LITERAL_HASH}{\"$${TARGET}\"}, ($$PARTIAL_UPGRADE_UID), $${QT_MAJOR_VERSION},$${QT_MINOR_VERSION},$${QT_PATCH_VERSION}, TYPE=PU"
+ partial_upgrade.pkg_prerules = pu_header vendorinfo
+ partial_upgrade.files = $$QMAKE_LIBDIR_QT/$${TARGET}.dll
+ partial_upgrade.path = c:/sys/bin
+ DEPLOYMENT += partial_upgrade
}