/[svn]/qsampler/trunk/src/qsampler.cpp
ViewVC logotype

Diff of /qsampler/trunk/src/qsampler.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 3465 by capela, Mon Feb 11 16:51:26 2019 UTC revision 3493 by capela, Sat Mar 9 21:47:46 2019 UTC
# Line 20  Line 20 
20    
21  *****************************************************************************/  *****************************************************************************/
22    
23  #include "qsamplerAbout.h"  #include "qsampler.h"
24    
25  #include "qsamplerOptions.h"  #include "qsamplerOptions.h"
26  #include "qsamplerMainForm.h"  #include "qsamplerMainForm.h"
27    
 #include <QApplication>  
28  #include <QLibraryInfo>  #include <QLibraryInfo>
29  #include <QTranslator>  #include <QTranslator>
30  #include <QLocale>  #include <QLocale>
# Line 52  Line 52 
52  // Singleton application instance stuff (Qt/X11 only atm.)  // Singleton application instance stuff (Qt/X11 only atm.)
53  //  //
54    
 #if QT_VERSION < 0x050000  
 #if defined(Q_WS_X11)  
 #define CONFIG_X11  
 #endif  
 #else  
 #if defined(QT_X11EXTRAS_LIB)  
 #define CONFIG_X11  
 #endif  
 #endif  
   
   
55  #ifdef CONFIG_X11  #ifdef CONFIG_X11
56  #ifdef CONFIG_XUNIQUE  #ifdef CONFIG_XUNIQUE
57    
58  #include <QX11Info>  #include <unistd.h> /* for gethostname() */
59    
60  #include <X11/Xatom.h>  #include <X11/Xatom.h>
61  #include <X11/Xlib.h>  #include <X11/Xlib.h>
# Line 80  Line 69 
69    
70  #include <QAbstractNativeEventFilter>  #include <QAbstractNativeEventFilter>
71    
 class qsamplerApplication;  
   
72  class qsamplerXcbEventFilter : public QAbstractNativeEventFilter  class qsamplerXcbEventFilter : public QAbstractNativeEventFilter
73  {  {
74  public:  public:
# Line 91  public: Line 78  public:
78                  : QAbstractNativeEventFilter(), m_pApp(pApp) {}                  : QAbstractNativeEventFilter(), m_pApp(pApp) {}
79    
80          // XCB event filter (virtual processor).          // XCB event filter (virtual processor).
81          bool nativeEventFilter(const QByteArray& eventType, void *message, long *);          bool nativeEventFilter(const QByteArray& eventType, void *message, long *)
82            {
83                    if (eventType == "xcb_generic_event_t") {
84                            xcb_property_notify_event_t *pEv
85                                    = static_cast<xcb_property_notify_event_t *> (message);
86                            if ((pEv->response_type & ~0x80) == XCB_PROPERTY_NOTIFY
87                                    && pEv->state == XCB_PROPERTY_NEW_VALUE)
88                                    m_pApp->x11PropertyNotify(pEv->window);
89                    }
90                    return false;
91            }
92    
93  private:  private:
94    
# Line 105  private: Line 102  private:
102  #endif  // CONFIG_X11  #endif  // CONFIG_X11
103    
104    
105  class qsamplerApplication : public QApplication  // Constructor.
106    qsamplerApplication::qsamplerApplication ( int& argc, char **argv )
107            : QApplication(argc, argv),
108                    m_pQtTranslator(NULL), m_pMyTranslator(NULL), m_pWidget(NULL)
109  {  {
110  public:          // Load translation support.
111            QLocale loc;
112          // Constructor.          if (loc.language() != QLocale::C) {
113          qsamplerApplication(int& argc, char **argv) : QApplication(argc, argv),                  // Try own Qt translation...
114                  m_pQtTranslator(0), m_pMyTranslator(0), m_pWidget(0)                  m_pQtTranslator = new QTranslator(this);
115          {                  QString sLocName = "qt_" + loc.name();
116                  // Load translation support.                  QString sLocPath = QLibraryInfo::location(QLibraryInfo::TranslationsPath);
117                  QLocale loc;                  if (m_pQtTranslator->load(sLocName, sLocPath)) {
118                  if (loc.language() != QLocale::C) {                          QApplication::installTranslator(m_pQtTranslator);
119                          // Try own Qt translation...                  } else {
120                          m_pQtTranslator = new QTranslator(this);                  #ifdef RELATIVE_LOCALE_DIR
121                          QString sLocName = "qt_" + loc.name();                          sLocPath = QApplication::applicationDirPath() + RELATIVE_LOCALE_DIR;
                         QString sLocPath = QLibraryInfo::location(QLibraryInfo::TranslationsPath);  
122                          if (m_pQtTranslator->load(sLocName, sLocPath)) {                          if (m_pQtTranslator->load(sLocName, sLocPath)) {
123                                  QApplication::installTranslator(m_pQtTranslator);                                  QApplication::installTranslator(m_pQtTranslator);
124                          } else {                          } else {
125                          #ifdef RELATIVE_LOCALE_DIR                  #endif
126                                  sLocPath = QApplication::applicationDirPath() + RELATIVE_LOCALE_DIR;                          delete m_pQtTranslator;
127                                  if (m_pQtTranslator->load(sLocName, sLocPath)) {                          m_pQtTranslator = 0;
128                                          QApplication::installTranslator(m_pQtTranslator);                  #ifdef CONFIG_DEBUG
129                                  } else {                          qWarning("Warning: no translation found for '%s' locale: %s/%s.qm",
130                          #endif                                  loc.name().toUtf8().constData(),
131                                  delete m_pQtTranslator;                                  sLocPath.toUtf8().constData(),
132                                  m_pQtTranslator = 0;                                  sLocName.toUtf8().constData());
133                    #endif
134                    #ifdef RELATIVE_LOCALE_DIR
135                            }
136                    #endif
137                    }
138                    // Try own application translation...
139                    m_pMyTranslator = new QTranslator(this);
140                    sLocName = "qsampler_" + loc.name();
141                    if (m_pMyTranslator->load(sLocName, sLocPath)) {
142                            QApplication::installTranslator(m_pMyTranslator);
143                    } else {
144                    #ifdef RELATIVE_LOCALE_DIR
145                            sLocPath = QApplication::applicationDirPath() + RELATIVE_LOCALE_DIR;
146                    #else
147                            sLocPath = CONFIG_DATADIR "/qsampler/translations";
148                    #endif
149                            if (m_pMyTranslator->load(sLocName, sLocPath)) {
150                                    QApplication::installTranslator(m_pMyTranslator);
151                            } else {
152                                    delete m_pMyTranslator;
153                                    m_pMyTranslator = 0;
154                          #ifdef CONFIG_DEBUG                          #ifdef CONFIG_DEBUG
155                                  qWarning("Warning: no translation found for '%s' locale: %s/%s.qm",                                  qWarning("Warning: no translation found for '%s' locale: %s/%s.qm",
156                                          loc.name().toUtf8().constData(),                                          loc.name().toUtf8().constData(),
157                                          sLocPath.toUtf8().constData(),                                          sLocPath.toUtf8().constData(),
158                                          sLocName.toUtf8().constData());                                          sLocName.toUtf8().constData());
159                          #endif                          #endif
                         #ifdef RELATIVE_LOCALE_DIR  
                                 }  
                         #endif  
                         }  
                         // Try own application translation...  
                         m_pMyTranslator = new QTranslator(this);  
                         sLocName = "qsampler_" + loc.name();  
                         if (m_pMyTranslator->load(sLocName, sLocPath)) {  
                                 QApplication::installTranslator(m_pMyTranslator);  
                         } else {  
                         #ifdef RELATIVE_LOCALE_DIR  
                                 sLocPath = QApplication::applicationDirPath() + RELATIVE_LOCALE_DIR;  
                         #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  
                                         qWarning("Warning: no translation found for '%s' locale: %s/%s.qm",  
                                                 loc.name().toUtf8().constData(),  
                                                 sLocPath.toUtf8().constData(),  
                                                 sLocName.toUtf8().constData());  
                                 #endif  
                                 }  
160                          }                          }
161                  }                  }
         #ifdef CONFIG_X11  
         #ifdef CONFIG_XUNIQUE  
                 m_pDisplay = NULL;  
                 m_aUnique = 0;  
                 m_wOwner = 0;  
         #if QT_VERSION >= 0x050100  
                 m_pXcbEventFilter = new qsamplerXcbEventFilter(this);  
                 installNativeEventFilter(m_pXcbEventFilter);  
                 if (QX11Info::isPlatformX11()) {  
         #endif  
                         // 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  
                 }  
         #endif  
         #endif  // CONFIG_XUNIQUE  
         #endif  // CONFIG_X11  
162          }          }
163    #ifdef CONFIG_X11
164    #ifdef CONFIG_XUNIQUE
165            m_pDisplay = NULL;
166            m_aUnique = 0;
167            m_wOwner = 0;
168    #if QT_VERSION >= 0x050100
169            m_pXcbEventFilter = new qsamplerXcbEventFilter(this);
170            installNativeEventFilter(m_pXcbEventFilter);
171    #endif
172    #endif  // CONFIG_XUNIQUE
173    #endif  // CONFIG_X11
174    }
175    
         // 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;  
         }  
176    
177          // Main application widget accessors.  // Destructor.
178          void setMainWidget(QWidget *pWidget)  qsamplerApplication::~qsamplerApplication (void)
179          {  {
180                  m_pWidget = pWidget;  #ifdef CONFIG_X11
181          #ifdef CONFIG_X11  #ifdef CONFIG_XUNIQUE
182          #ifdef CONFIG_XUNIQUE  #if QT_VERSION >= 0x050100
183                  m_wOwner = m_pWidget->winId();          removeNativeEventFilter(m_pXcbEventFilter);
184                  if (m_pDisplay && m_wOwner) {          delete m_pXcbEventFilter;
185                          XGrabServer(m_pDisplay);  #endif
186                          XSetSelectionOwner(m_pDisplay, m_aUnique, m_wOwner, CurrentTime);  #endif  // CONFIG_XUNIQUE
187                          XUngrabServer(m_pDisplay);  #endif  // CONFIG_X11
188                  }          if (m_pMyTranslator) delete m_pMyTranslator;
189          #endif  // CONFIG_XUNIQUE          if (m_pQtTranslator) delete m_pQtTranslator;
190          #endif  // CONFIG_X11  }
191    
192    
193    // Main application widget accessors.
194    void qsamplerApplication::setMainWidget ( QWidget *pWidget )
195    {
196            m_pWidget = pWidget;
197    #ifdef CONFIG_X11
198    #ifdef CONFIG_XUNIQUE
199            m_wOwner = m_pWidget->winId();
200            if (m_pDisplay && m_wOwner) {
201                    XGrabServer(m_pDisplay);
202                    XSetSelectionOwner(m_pDisplay, m_aUnique, m_wOwner, CurrentTime);
203                    XUngrabServer(m_pDisplay);
204          }          }
205    #endif  // CONFIG_XUNIQUE
206    #endif  // CONFIG_X11
207    }
208    
         QWidget *mainWidget() const { return m_pWidget; }  
209    
210          // Check if another instance is running,  // Check if another instance is running,
211      // and raise its proper main widget...  // and raise its proper main widget...
212          bool setup()  bool qsamplerApplication::setup (void)
213          {  {
214          #ifdef CONFIG_X11  #ifdef CONFIG_X11
215          #ifdef CONFIG_XUNIQUE  #ifdef CONFIG_XUNIQUE
216                  if (m_pDisplay && m_wOwner != None) {  #if QT_VERSION >= 0x050100
217            if (!QX11Info::isPlatformX11())
218                    return false;
219    #endif
220            m_pDisplay = QX11Info::display();
221            if (m_pDisplay) {
222                    QString sUnique = QSAMPLER_XUNIQUE;
223                    char szHostName[255];
224                    if (::gethostname(szHostName, sizeof(szHostName)) == 0) {
225                            sUnique += '@';
226                            sUnique += szHostName;
227                    }
228                    m_aUnique = XInternAtom(m_pDisplay, sUnique.toUtf8().constData(), false);
229                    XGrabServer(m_pDisplay);
230                    m_wOwner = XGetSelectionOwner(m_pDisplay, m_aUnique);
231                    XUngrabServer(m_pDisplay);
232                    if (m_wOwner != None) {
233                          // First, notify any freedesktop.org WM                          // First, notify any freedesktop.org WM
234                          // that we're about to show the main widget...                          // that we're about to show the main widget...
235                          Screen *pScreen = XDefaultScreenOfDisplay(m_pDisplay);                          Screen *pScreen = XDefaultScreenOfDisplay(m_pDisplay);
# Line 264  public: Line 265  public:
265                          // Done.                          // Done.
266                          return true;                          return true;
267                  }                  }
         #endif  // CONFIG_XUNIQUE  
         #endif  // CONFIG_X11  
                 return false;  
         }  
   
 #ifdef CONFIG_X11  
 #ifdef CONFIG_XUNIQUE  
         void x11PropertyNotify(Window w)  
         {  
                 if (m_pDisplay && m_pWidget && m_wOwner == w) {  
                         // Always check whether our property-flag is still around...  
                         Atom aType;  
                         int iFormat = 0;  
                         unsigned long iItems = 0;  
                         unsigned long iAfter = 0;  
                         unsigned char *pData = 0;  
                         if (XGetWindowProperty(  
                                         m_pDisplay,  
                                         m_wOwner,  
                                         m_aUnique,  
                                         0, 1024,  
                                         false,  
                                         m_aUnique,  
                                         &aType,  
                                         &iFormat,  
                                         &iItems,  
                                         &iAfter,  
                                         &pData) == Success  
                                 && aType == m_aUnique && iItems > 0 && iAfter == 0) {  
                                 // Avoid repeating it-self...  
                                 XDeleteProperty(m_pDisplay, m_wOwner, m_aUnique);  
                                 // Just make it always shows up fine...  
                                 m_pWidget->show();  
                                 m_pWidget->raise();  
                                 m_pWidget->activateWindow();  
                         }  
                         // Free any left-overs...  
                         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);  
268          }          }
 #endif  
269  #endif  // CONFIG_XUNIQUE  #endif  // CONFIG_XUNIQUE
270  #endif  // CONFIG_X11  #endif  // CONFIG_X11
271                    return false;
272  private:  }
   
         // Translation support.  
         QTranslator *m_pQtTranslator;  
         QTranslator *m_pMyTranslator;  
273    
         // Instance variables.  
         QWidget *m_pWidget;  
274    
275  #ifdef CONFIG_X11  #ifdef CONFIG_X11
276  #ifdef CONFIG_XUNIQUE  #ifdef CONFIG_XUNIQUE
277          Display *m_pDisplay;  void qsamplerApplication::x11PropertyNotify ( Window w )
278          Atom     m_aUnique;  {
279          Window   m_wOwner;          if (m_pDisplay && m_pWidget && m_wOwner == w) {
280  #if QT_VERSION >= 0x050100                  // Always check whether our property-flag is still around...
281          qsamplerXcbEventFilter *m_pXcbEventFilter;                  Atom aType;
282  #endif                  int iFormat = 0;
283  #endif  // CONFIG_XUNIQUE                  unsigned long iItems = 0;
284  #endif  // CONFIG_X11                  unsigned long iAfter = 0;
285  };                  unsigned char *pData = 0;
286                    if (XGetWindowProperty(
287                                    m_pDisplay,
288                                    m_wOwner,
289                                    m_aUnique,
290                                    0, 1024,
291                                    false,
292                                    m_aUnique,
293                                    &aType,
294                                    &iFormat,
295                                    &iItems,
296                                    &iAfter,
297                                    &pData) == Success
298                            && aType == m_aUnique && iItems > 0 && iAfter == 0) {
299                            // Avoid repeating it-self...
300                            XDeleteProperty(m_pDisplay, m_wOwner, m_aUnique);
301                            // Just make it always shows up fine...
302                            m_pWidget->show();
303                            m_pWidget->raise();
304                            m_pWidget->activateWindow();
305                    }
306                    // Free any left-overs...
307                    if (iItems > 0 && pData)
308                            XFree(pData);
309            }
310    }
311    
312    
313  #ifdef CONFIG_X11  #if QT_VERSION < 0x050000
314  #ifdef CONFIG_XUNIQUE  bool qsamplerApplication::x11EventFilter ( XEvent *pEv )
 #if QT_VERSION >= 0x050100  
 // XCB Event filter (virtual processor).  
 bool qsamplerXcbEventFilter::nativeEventFilter (  
         const QByteArray& eventType, void *message, long * )  
315  {  {
316          if (eventType == "xcb_generic_event_t") {          if (pEv->type == PropertyNotify
317                  xcb_property_notify_event_t *pEv                  && pEv->xproperty.state == PropertyNewValue)
318                          = static_cast<xcb_property_notify_event_t *> (message);                  x11PropertyNotify(pEv->xproperty.window);
319                  if ((pEv->response_type & ~0x80) == XCB_PROPERTY_NOTIFY          return QApplication::x11EventFilter(pEv);
                         && pEv->state == XCB_PROPERTY_NEW_VALUE)  
                         m_pApp->x11PropertyNotify(pEv->window);  
         }  
         return false;  
320  }  }
321  #endif  #endif
322    
323  #endif  // CONFIG_XUNIQUE  #endif  // CONFIG_XUNIQUE
324  #endif  // CONFIG_X11  #endif  // CONFIG_X11
325    

Legend:
Removed from v.3465  
changed lines
  Added in v.3493

  ViewVC Help
Powered by ViewVC