--- qsampler/trunk/src/qsampler.cpp 2019/03/09 21:47:46 3493 +++ qsampler/trunk/src/qsampler.cpp 2019/03/10 11:06:53 3496 @@ -52,54 +52,27 @@ // Singleton application instance stuff (Qt/X11 only atm.) // -#ifdef CONFIG_X11 #ifdef CONFIG_XUNIQUE -#include /* for gethostname() */ - -#include -#include - #define QSAMPLER_XUNIQUE "qsamplerApplication" -#if QT_VERSION >= 0x050100 - -#include -#include - -#include - -class qsamplerXcbEventFilter : public QAbstractNativeEventFilter -{ -public: - - // Constructor. - qsamplerXcbEventFilter(qsamplerApplication *pApp) - : QAbstractNativeEventFilter(), m_pApp(pApp) {} - - // XCB event filter (virtual processor). - bool nativeEventFilter(const QByteArray& eventType, void *message, long *) - { - if (eventType == "xcb_generic_event_t") { - xcb_property_notify_event_t *pEv - = static_cast (message); - if ((pEv->response_type & ~0x80) == XCB_PROPERTY_NOTIFY - && pEv->state == XCB_PROPERTY_NEW_VALUE) - m_pApp->x11PropertyNotify(pEv->window); - } - return false; - } +#if QT_VERSION < 0x050000 +#ifdef CONFIG_X11 -private: +#include /* for gethostname() */ - // Instance variable. - qsamplerApplication *m_pApp; -}; +#include +#include +#endif // CONFIG_X11 +#else +#include +#include +#include +#include #endif #endif // CONFIG_XUNIQUE -#endif // CONFIG_X11 // Constructor. @@ -160,31 +133,37 @@ } } } -#ifdef CONFIG_X11 #ifdef CONFIG_XUNIQUE +#if QT_VERSION < 0x050000 +#ifdef CONFIG_X11 m_pDisplay = NULL; m_aUnique = 0; m_wOwner = 0; -#if QT_VERSION >= 0x050100 - m_pXcbEventFilter = new qsamplerXcbEventFilter(this); - installNativeEventFilter(m_pXcbEventFilter); +#endif // CONFIG_X11 +#else + m_pMemory = NULL; + m_pServer = NULL; #endif #endif // CONFIG_XUNIQUE -#endif // CONFIG_X11 } // Destructor. qsamplerApplication::~qsamplerApplication (void) { -#ifdef CONFIG_X11 #ifdef CONFIG_XUNIQUE -#if QT_VERSION >= 0x050100 - removeNativeEventFilter(m_pXcbEventFilter); - delete m_pXcbEventFilter; +#if QT_VERSION >= 0x050000 + if (m_pServer) { + m_pServer->close(); + delete m_pServer; + m_pServer = NULL; + } + if (m_pMemory) { + delete m_pMemory; + m_pMemory = NULL; +} #endif #endif // CONFIG_XUNIQUE -#endif // CONFIG_X11 if (m_pMyTranslator) delete m_pMyTranslator; if (m_pQtTranslator) delete m_pQtTranslator; } @@ -194,16 +173,18 @@ void qsamplerApplication::setMainWidget ( QWidget *pWidget ) { m_pWidget = pWidget; -#ifdef CONFIG_X11 #ifdef CONFIG_XUNIQUE +#if QT_VERSION < 0x050000 +#ifdef CONFIG_X11 m_wOwner = m_pWidget->winId(); if (m_pDisplay && m_wOwner) { XGrabServer(m_pDisplay); XSetSelectionOwner(m_pDisplay, m_aUnique, m_wOwner, CurrentTime); XUngrabServer(m_pDisplay); } -#endif // CONFIG_XUNIQUE #endif // CONFIG_X11 +#endif +#endif // CONFIG_XUNIQUE } @@ -211,12 +192,9 @@ // and raise its proper main widget... bool qsamplerApplication::setup (void) { -#ifdef CONFIG_X11 #ifdef CONFIG_XUNIQUE -#if QT_VERSION >= 0x050100 - if (!QX11Info::isPlatformX11()) - return false; -#endif +#if QT_VERSION < 0x050000 +#ifdef CONFIG_X11 m_pDisplay = QX11Info::display(); if (m_pDisplay) { QString sUnique = QSAMPLER_XUNIQUE; @@ -266,14 +244,69 @@ return true; } } -#endif // CONFIG_XUNIQUE #endif // CONFIG_X11 return false; +#else + m_sUnique = QCoreApplication::applicationName(); + m_sUnique += '@'; + m_sUnique += QHostInfo::localHostName(); +#ifdef Q_OS_UNIX + m_pMemory = new QSharedMemory(m_sUnique); + m_pMemory->attach(); + delete m_pMemory; +#endif + m_pMemory = new QSharedMemory(m_sUnique); + bool bServer = false; + const qint64 pid = QCoreApplication::applicationPid(); + struct Data { qint64 pid; }; + if (m_pMemory->create(sizeof(Data))) { + m_pMemory->lock(); + Data *pData = static_cast (m_pMemory->data()); + if (pData) { + pData->pid = pid; + bServer = true; + } + m_pMemory->unlock(); + } + else + if (m_pMemory->attach()) { + m_pMemory->lock(); // maybe not necessary? + Data *pData = static_cast (m_pMemory->data()); + if (pData) + bServer = (pData->pid == pid); + m_pMemory->unlock(); + } + if (bServer) { + QLocalServer::removeServer(m_sUnique); + m_pServer = new QLocalServer(); + m_pServer->setSocketOptions(QLocalServer::UserAccessOption); + m_pServer->listen(m_sUnique); + QObject::connect(m_pServer, + SIGNAL(newConnection()), + SLOT(newConnectionSlot())); + } else { + QLocalSocket socket; + socket.connectToServer(m_sUnique); + if (socket.state() == QLocalSocket::ConnectingState) + socket.waitForConnected(200); + if (socket.state() == QLocalSocket::ConnectedState) { + socket.write(QCoreApplication::arguments().join(' ').toUtf8()); + socket.flush(); + socket.waitForBytesWritten(200); + } + } + return !bServer; +#endif +#else + return false; +#endif // !CONFIG_XUNIQUE } -#ifdef CONFIG_X11 #ifdef CONFIG_XUNIQUE +#if QT_VERSION < 0x050000 +#ifdef CONFIG_X11 + void qsamplerApplication::x11PropertyNotify ( Window w ) { if (m_pDisplay && m_pWidget && m_wOwner == w) { @@ -310,7 +343,6 @@ } -#if QT_VERSION < 0x050000 bool qsamplerApplication::x11EventFilter ( XEvent *pEv ) { if (pEv->type == PropertyNotify @@ -318,10 +350,38 @@ x11PropertyNotify(pEv->xproperty.window); return QApplication::x11EventFilter(pEv); } -#endif -#endif // CONFIG_XUNIQUE #endif // CONFIG_X11 +#else + +// Local server conection slot. +void qsamplerApplication::newConnectionSlot (void) +{ + QLocalSocket *pSocket = m_pServer->nextPendingConnection(); + QObject::connect(pSocket, + SIGNAL(readyRead()), + SLOT(readyReadSlot())); +} + +// Local server data-ready slot. +void qsamplerApplication::readyReadSlot (void) +{ + QLocalSocket *pSocket = qobject_cast (sender()); + if (pSocket) { + const qint64 nread = pSocket->bytesAvailable(); + if (nread > 0) { + QByteArray data = pSocket->read(nread); + // Just make it always shows up fine... + m_pWidget->hide(); + m_pWidget->show(); + m_pWidget->raise(); + m_pWidget->activateWindow(); + } + } +} + +#endif +#endif // CONFIG_XUNIQUE //-------------------------------------------------------------------------