--- qsampler/trunk/src/qsampler.cpp 2013/07/08 10:06:57 2459 +++ qsampler/trunk/src/qsampler.cpp 2017/01/02 12:11:50 3065 @@ -1,8 +1,8 @@ // qsampler.cpp // /**************************************************************************** - Copyright (C) 2004-2013, rncbc aka Rui Nuno Capela. All rights reserved. - Copyright (C) 2007, 2008 Christian Schoenebeck + Copyright (C) 2004-2017, rncbc aka Rui Nuno Capela. All rights reserved. + Copyright (C) 2007,2008,2015 Christian Schoenebeck This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -33,19 +33,12 @@ #include #endif -#define CONFIG_QUOTE1(x) #x -#define CONFIG_QUOTED(x) CONFIG_QUOTE1(x) - -#if defined(DATADIR) -#define CONFIG_DATADIR CONFIG_QUOTED(DATADIR) -#else -#define CONFIG_DATADIR CONFIG_PREFIX "/share" +#ifndef CONFIG_PREFIX +#define CONFIG_PREFIX "/usr/local" #endif -#if defined(LOCALEDIR) -#define CONFIG_LOCALEDIR CONFIG_QUOTED(LOCALEDIR) -#else -#define CONFIG_LOCALEDIR CONFIG_DATADIR "/locale" +#ifndef CONFIG_DATADIR +#define CONFIG_DATADIR CONFIG_PREFIX "/share" #endif #if WIN32 @@ -59,24 +52,66 @@ // Singleton application instance stuff (Qt/X11 only atm.) // +#if QT_VERSION < 0x050000 #if defined(Q_WS_X11) +#define CONFIG_X11 +#endif +#else +#if defined(QT_X11EXTRAS_LIB) +#define CONFIG_X11 +#endif +#endif + + +#ifdef CONFIG_X11 +#ifdef CONFIG_XUNIQUE #include #include #include -#define QSAMPLER_XUNIQUE "qsamplerMainForm_xunique" +#define QSAMPLER_XUNIQUE "qsamplerApplication" + +#if QT_VERSION >= 0x050100 + +#include +#include + +#include + +class qsamplerApplication; + +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 *); + +private: + + // Instance variable. + qsamplerApplication *m_pApp; +}; #endif +#endif // CONFIG_XUNIQUE +#endif // CONFIG_X11 + + class qsamplerApplication : public QApplication { public: // Constructor. qsamplerApplication(int& argc, char **argv) : QApplication(argc, argv), - m_pQtTranslator(0), m_pMyTranslator(0), m_pWidget(0) + m_pQtTranslator(0), m_pMyTranslator(0), m_pWidget(0) { // Load translation support. QLocale loc; @@ -88,23 +123,23 @@ if (m_pQtTranslator->load(sLocName, sLocPath)) { QApplication::installTranslator(m_pQtTranslator); } else { - #ifdef RELATIVE_LOCALE_DIR + #ifdef RELATIVE_LOCALE_DIR sLocPath = QApplication::applicationDirPath() + RELATIVE_LOCALE_DIR; if (m_pQtTranslator->load(sLocName, sLocPath)) { QApplication::installTranslator(m_pQtTranslator); } else { - #endif + #endif delete m_pQtTranslator; m_pQtTranslator = 0; - #ifdef CONFIG_DEBUG + #ifdef CONFIG_DEBUG qWarning("Warning: no translation found for '%s' locale: %s/%s.qm", loc.name().toUtf8().constData(), sLocPath.toUtf8().constData(), sLocName.toUtf8().constData()); - #endif - #ifdef RELATIVE_LOCALE_DIR + #endif + #ifdef RELATIVE_LOCALE_DIR } - #endif + #endif } // Try own application translation... m_pMyTranslator = new QTranslator(this); @@ -112,37 +147,52 @@ if (m_pMyTranslator->load(sLocName, sLocPath)) { QApplication::installTranslator(m_pMyTranslator); } else { - #ifdef RELATIVE_LOCALE_DIR + #ifdef RELATIVE_LOCALE_DIR sLocPath = QApplication::applicationDirPath() + RELATIVE_LOCALE_DIR; - #else - sLocPath = CONFIG_LOCALEDIR; - #endif + #else + sLocPath = CONFIG_DATADIR "/qsampler/translations"; + #endif if (m_pMyTranslator->load(sLocName, sLocPath)) { QApplication::installTranslator(m_pMyTranslator); } else { delete m_pMyTranslator; m_pMyTranslator = 0; - #ifdef CONFIG_DEBUG + #ifdef CONFIG_DEBUG qWarning("Warning: no translation found for '%s' locale: %s/%s.qm", loc.name().toUtf8().constData(), sLocPath.toUtf8().constData(), sLocName.toUtf8().constData()); - #endif + #endif } } } - #if defined(Q_WS_X11) + #ifdef CONFIG_X11 + #ifdef CONFIG_XUNIQUE + // Instance uniqueness initialization... m_pDisplay = QX11Info::display(); m_aUnique = XInternAtom(m_pDisplay, QSAMPLER_XUNIQUE, false); XGrabServer(m_pDisplay); m_wOwner = XGetSelectionOwner(m_pDisplay, m_aUnique); XUngrabServer(m_pDisplay); + #if QT_VERSION >= 0x050100 + m_pXcbEventFilter = new qsamplerXcbEventFilter(this); + installNativeEventFilter(m_pXcbEventFilter); #endif + #endif // CONFIG_XUNIQUE + #endif // CONFIG_X11 } // Destructor. ~qsamplerApplication() { + #ifdef CONFIG_X11 + #ifdef CONFIG_XUNIQUE + #if QT_VERSION >= 0x050100 + removeNativeEventFilter(m_pXcbEventFilter); + delete m_pXcbEventFilter; + #endif + #endif // CONFIG_XUNIQUE + #endif // CONFIG_X11 if (m_pMyTranslator) delete m_pMyTranslator; if (m_pQtTranslator) delete m_pQtTranslator; } @@ -151,12 +201,16 @@ void setMainWidget(QWidget *pWidget) { m_pWidget = pWidget; - #if defined(Q_WS_X11) - XGrabServer(m_pDisplay); + #ifdef CONFIG_X11 + #ifdef CONFIG_XUNIQUE m_wOwner = m_pWidget->winId(); - XSetSelectionOwner(m_pDisplay, m_aUnique, m_wOwner, CurrentTime); - XUngrabServer(m_pDisplay); - #endif + 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 } QWidget *mainWidget() const { return m_pWidget; } @@ -165,8 +219,9 @@ // and raise its proper main widget... bool setup() { - #if defined(Q_WS_X11) - if (m_wOwner != None) { + #ifdef CONFIG_X11 + #ifdef CONFIG_XUNIQUE + if (m_pDisplay && m_wOwner != None) { // First, notify any freedesktop.org WM // that we're about to show the main widget... Screen *pScreen = XDefaultScreenOfDisplay(m_pDisplay); @@ -189,8 +244,8 @@ XSync(m_pDisplay, false); XRaiseWindow(m_pDisplay, m_wOwner); // And then, let it get caught on destination - // by QApplication::x11EventFilter... - QByteArray value = QSAMPLER_XUNIQUE; + // by QApplication::native/x11EventFilter... + const QByteArray value = QSAMPLER_XUNIQUE; XChangeProperty( m_pDisplay, m_wOwner, @@ -202,17 +257,16 @@ // Done. return true; } - #endif + #endif // CONFIG_XUNIQUE + #endif // CONFIG_X11 return false; } -#if defined(Q_WS_X11) - bool x11EventFilter(XEvent *pEv) +#ifdef CONFIG_X11 +#ifdef CONFIG_XUNIQUE + void x11PropertyNotify(Window w) { - if (m_pWidget && m_wOwner != None - && pEv->type == PropertyNotify - && pEv->xproperty.window == m_wOwner - && pEv->xproperty.state == PropertyNewValue) { + if (m_pDisplay && m_pWidget && m_wOwner == w) { // Always check whether our property-flag is still around... Atom aType; int iFormat = 0; @@ -243,9 +297,18 @@ if (iItems > 0 && pData) XFree(pData); } + } +#if QT_VERSION < 0x050000 + bool x11EventFilter(XEvent *pEv) + { + if (pEv->type == PropertyNotify + && pEv->xproperty.state == PropertyNewValue) + x11PropertyNotify(pEv->xproperty.window); return QApplication::x11EventFilter(pEv); } #endif +#endif // CONFIG_XUNIQUE +#endif // CONFIG_X11 private: @@ -256,14 +319,40 @@ // Instance variables. QWidget *m_pWidget; -#if defined(Q_WS_X11) +#ifdef CONFIG_X11 +#ifdef CONFIG_XUNIQUE Display *m_pDisplay; Atom m_aUnique; Window m_wOwner; +#if QT_VERSION >= 0x050100 + qsamplerXcbEventFilter *m_pXcbEventFilter; #endif +#endif // CONFIG_XUNIQUE +#endif // CONFIG_X11 }; +#ifdef CONFIG_X11 +#ifdef CONFIG_XUNIQUE +#if QT_VERSION >= 0x050100 +// XCB Event filter (virtual processor). +bool qsamplerXcbEventFilter::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; +} +#endif +#endif // CONFIG_XUNIQUE +#endif // CONFIG_X11 + + //------------------------------------------------------------------------- // stacktrace - Signal crash handler. // @@ -399,10 +488,8 @@ } // Set default base font... - int iBaseFontSize = app.font().pointSize(); if (options.iBaseFontSize > 0) - iBaseFontSize = options.iBaseFontSize; - app.setFont(QFont(app.font().family(), iBaseFontSize)); + app.setFont(QFont(app.font().family(), options.iBaseFontSize)); // Construct, setup and show the main form. QSampler::MainForm w; @@ -420,3 +507,4 @@ // end of qsampler.cpp +