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

Annotation of /qsampler/trunk/src/qsampler.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2415 - (hide annotations) (download)
Thu Feb 14 14:57:43 2013 UTC (11 years, 1 month ago) by capela
File size: 11432 byte(s)
- Yet another Qt5 preparations fix.
1 capela 2074 // qsampler.cpp
2     //
3     /****************************************************************************
4 capela 2415 Copyright (C) 2004-2013, rncbc aka Rui Nuno Capela. All rights reserved.
5 capela 2074 Copyright (C) 2007, 2008 Christian Schoenebeck
6    
7     This program is free software; you can redistribute it and/or
8     modify it under the terms of the GNU General Public License
9     as published by the Free Software Foundation; either version 2
10     of the License, or (at your option) any later version.
11    
12     This program is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15     GNU General Public License for more details.
16    
17     You should have received a copy of the GNU General Public License along
18     with this program; if not, write to the Free Software Foundation, Inc.,
19     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20    
21     *****************************************************************************/
22    
23     #include "qsamplerAbout.h"
24     #include "qsamplerOptions.h"
25     #include "qsamplerMainForm.h"
26    
27     #include <QApplication>
28     #include <QLibraryInfo>
29     #include <QTranslator>
30     #include <QLocale>
31     #if defined(__APPLE__) // Toshi Nagata 20080105
32     #include <QDir>
33     #endif
34    
35     #if QT_VERSION < 0x040300
36     #define lighter(x) light(x)
37     #define darker(x) dark(x)
38     #endif
39    
40 capela 2282 #define CONFIG_QUOTE1(x) #x
41     #define CONFIG_QUOTED(x) CONFIG_QUOTE1(x)
42    
43     #if defined(DATADIR)
44     #define CONFIG_DATADIR CONFIG_QUOTED(DATADIR)
45     #else
46     #define CONFIG_DATADIR CONFIG_PREFIX "/share"
47     #endif
48    
49     #if defined(LOCALEDIR)
50     #define CONFIG_LOCALEDIR CONFIG_QUOTED(LOCALEDIR)
51     #else
52     #define CONFIG_LOCALEDIR CONFIG_DATADIR "/locale"
53     #endif
54    
55 persson 2210 #if WIN32
56     #define RELATIVE_LOCALE_DIR "/share/locale"
57     #elif defined(__APPLE__)
58     #define RELATIVE_LOCALE_DIR "/../Resources"
59     #endif
60 capela 2074
61 persson 2210
62 capela 2074 //-------------------------------------------------------------------------
63     // Singleton application instance stuff (Qt/X11 only atm.)
64     //
65    
66     #if defined(Q_WS_X11)
67    
68     #include <QX11Info>
69    
70     #include <X11/Xatom.h>
71     #include <X11/Xlib.h>
72    
73     #define QSAMPLER_XUNIQUE "qsamplerMainForm_xunique"
74    
75     #endif
76    
77     class qsamplerApplication : public QApplication
78     {
79     public:
80    
81     // Constructor.
82     qsamplerApplication(int& argc, char **argv) : QApplication(argc, argv),
83     m_pQtTranslator(0), m_pMyTranslator(0), m_pWidget(0)
84     {
85     // Load translation support.
86     QLocale loc;
87     if (loc.language() != QLocale::C) {
88     // Try own Qt translation...
89     m_pQtTranslator = new QTranslator(this);
90     QString sLocName = "qt_" + loc.name();
91     QString sLocPath = QLibraryInfo::location(QLibraryInfo::TranslationsPath);
92     if (m_pQtTranslator->load(sLocName, sLocPath)) {
93     QApplication::installTranslator(m_pQtTranslator);
94     } else {
95 persson 2210 #ifdef RELATIVE_LOCALE_DIR
96     sLocPath = QApplication::applicationDirPath() + RELATIVE_LOCALE_DIR;
97 persson 2144 if (m_pQtTranslator->load(sLocName, sLocPath)) {
98     QApplication::installTranslator(m_pQtTranslator);
99     } else {
100     #endif
101 capela 2074 delete m_pQtTranslator;
102     m_pQtTranslator = 0;
103     #ifdef CONFIG_DEBUG
104     qWarning("Warning: no translation found for '%s' locale: %s/%s.qm",
105     loc.name().toUtf8().constData(),
106     sLocPath.toUtf8().constData(),
107     sLocName.toUtf8().constData());
108     #endif
109 persson 2210 #ifdef RELATIVE_LOCALE_DIR
110 persson 2144 }
111     #endif
112 capela 2074 }
113     // Try own application translation...
114     m_pMyTranslator = new QTranslator(this);
115     sLocName = "qsampler_" + loc.name();
116     if (m_pMyTranslator->load(sLocName, sLocPath)) {
117     QApplication::installTranslator(m_pMyTranslator);
118     } else {
119 persson 2210 #ifdef RELATIVE_LOCALE_DIR
120     sLocPath = QApplication::applicationDirPath() + RELATIVE_LOCALE_DIR;
121 persson 2144 #else
122 capela 2282 sLocPath = CONFIG_LOCALEDIR;
123 persson 2144 #endif
124 capela 2074 if (m_pMyTranslator->load(sLocName, sLocPath)) {
125     QApplication::installTranslator(m_pMyTranslator);
126     } else {
127     delete m_pMyTranslator;
128     m_pMyTranslator = 0;
129     #ifdef CONFIG_DEBUG
130     qWarning("Warning: no translation found for '%s' locale: %s/%s.qm",
131     loc.name().toUtf8().constData(),
132     sLocPath.toUtf8().constData(),
133     sLocName.toUtf8().constData());
134     #endif
135     }
136     }
137     }
138     #if defined(Q_WS_X11)
139     m_pDisplay = QX11Info::display();
140     m_aUnique = XInternAtom(m_pDisplay, QSAMPLER_XUNIQUE, false);
141     XGrabServer(m_pDisplay);
142     m_wOwner = XGetSelectionOwner(m_pDisplay, m_aUnique);
143     XUngrabServer(m_pDisplay);
144     #endif
145     }
146    
147     // Destructor.
148     ~qsamplerApplication()
149     {
150     if (m_pMyTranslator) delete m_pMyTranslator;
151     if (m_pQtTranslator) delete m_pQtTranslator;
152     }
153    
154     // Main application widget accessors.
155     void setMainWidget(QWidget *pWidget)
156     {
157     m_pWidget = pWidget;
158     #if defined(Q_WS_X11)
159     XGrabServer(m_pDisplay);
160     m_wOwner = m_pWidget->winId();
161     XSetSelectionOwner(m_pDisplay, m_aUnique, m_wOwner, CurrentTime);
162     XUngrabServer(m_pDisplay);
163     #endif
164     }
165    
166     QWidget *mainWidget() const { return m_pWidget; }
167    
168     // Check if another instance is running,
169     // and raise its proper main widget...
170     bool setup()
171     {
172     #if defined(Q_WS_X11)
173     if (m_wOwner != None) {
174     // First, notify any freedesktop.org WM
175     // that we're about to show the main widget...
176     Screen *pScreen = XDefaultScreenOfDisplay(m_pDisplay);
177     int iScreen = XScreenNumberOfScreen(pScreen);
178     XEvent ev;
179     memset(&ev, 0, sizeof(ev));
180     ev.xclient.type = ClientMessage;
181     ev.xclient.display = m_pDisplay;
182     ev.xclient.window = m_wOwner;
183     ev.xclient.message_type = XInternAtom(m_pDisplay, "_NET_ACTIVE_WINDOW", false);
184     ev.xclient.format = 32;
185     ev.xclient.data.l[0] = 0; // Source indication.
186     ev.xclient.data.l[1] = 0; // Timestamp.
187     ev.xclient.data.l[2] = 0; // Requestor's currently active window (none)
188     ev.xclient.data.l[3] = 0;
189     ev.xclient.data.l[4] = 0;
190     XSelectInput(m_pDisplay, m_wOwner, StructureNotifyMask);
191     XSendEvent(m_pDisplay, RootWindow(m_pDisplay, iScreen), false,
192     (SubstructureNotifyMask | SubstructureRedirectMask), &ev);
193     XSync(m_pDisplay, false);
194     XRaiseWindow(m_pDisplay, m_wOwner);
195     // And then, let it get caught on destination
196     // by QApplication::x11EventFilter...
197     QByteArray value = QSAMPLER_XUNIQUE;
198     XChangeProperty(
199     m_pDisplay,
200     m_wOwner,
201     m_aUnique,
202     m_aUnique, 8,
203     PropModeReplace,
204     (unsigned char *) value.data(),
205     value.length());
206     // Done.
207     return true;
208     }
209     #endif
210     return false;
211     }
212    
213     #if defined(Q_WS_X11)
214     bool x11EventFilter(XEvent *pEv)
215     {
216     if (m_pWidget && m_wOwner != None
217     && pEv->type == PropertyNotify
218     && pEv->xproperty.window == m_wOwner
219     && pEv->xproperty.state == PropertyNewValue) {
220     // Always check whether our property-flag is still around...
221     Atom aType;
222     int iFormat = 0;
223     unsigned long iItems = 0;
224     unsigned long iAfter = 0;
225     unsigned char *pData = 0;
226     if (XGetWindowProperty(
227     m_pDisplay,
228     m_wOwner,
229     m_aUnique,
230     0, 1024,
231     false,
232     m_aUnique,
233     &aType,
234     &iFormat,
235     &iItems,
236     &iAfter,
237     &pData) == Success
238     && aType == m_aUnique && iItems > 0 && iAfter == 0) {
239     // Avoid repeating it-self...
240     XDeleteProperty(m_pDisplay, m_wOwner, m_aUnique);
241     // Just make it always shows up fine...
242     m_pWidget->show();
243     m_pWidget->raise();
244     m_pWidget->activateWindow();
245     }
246     // Free any left-overs...
247     if (iItems > 0 && pData)
248     XFree(pData);
249     }
250     return QApplication::x11EventFilter(pEv);
251     }
252     #endif
253    
254     private:
255    
256     // Translation support.
257     QTranslator *m_pQtTranslator;
258     QTranslator *m_pMyTranslator;
259    
260     // Instance variables.
261     QWidget *m_pWidget;
262    
263     #if defined(Q_WS_X11)
264     Display *m_pDisplay;
265     Atom m_aUnique;
266     Window m_wOwner;
267     #endif
268     };
269    
270    
271     //-------------------------------------------------------------------------
272     // stacktrace - Signal crash handler.
273     //
274    
275     #ifdef CONFIG_STACKTRACE
276     #if defined(__GNUC__) && defined(Q_OS_LINUX)
277    
278     #include <stdio.h>
279     #include <errno.h>
280     #include <signal.h>
281 capela 2341 #include <unistd.h>
282 capela 2074 #include <sys/wait.h>
283    
284     void stacktrace ( int signo )
285     {
286     pid_t pid;
287     int rc;
288     int status = 0;
289     char cmd[80];
290    
291     // Reinstall default handler; prevent race conditions...
292     signal(signo, SIG_DFL);
293    
294     static const char *shell = "/bin/sh";
295 capela 2181 static const char *format = "gdb -q --batch --pid=%d"
296     " --eval-command='thread apply all bt'";
297 capela 2074
298     snprintf(cmd, sizeof(cmd), format, (int) getpid());
299    
300     pid = fork();
301    
302     // Fork failure!
303     if (pid < 0)
304     return;
305    
306     // Fork child...
307     if (pid == 0) {
308     execl(shell, shell, "-c", cmd, NULL);
309     _exit(1);
310     return;
311     }
312    
313     // Parent here: wait for child to terminate...
314     do { rc = waitpid(pid, &status, 0); }
315     while ((rc < 0) && (errno == EINTR));
316    
317     // Dispatch any logging, if any...
318     QApplication::processEvents(QEventLoop::AllEvents, 3000);
319    
320     // Make sure everyone terminates...
321     kill(pid, SIGTERM);
322     _exit(1);
323     }
324    
325     #endif
326     #endif
327    
328    
329     //-------------------------------------------------------------------------
330     // main - The main program trunk.
331     //
332    
333     int main ( int argc, char **argv )
334     {
335     Q_INIT_RESOURCE(qsampler);
336     #ifdef CONFIG_STACKTRACE
337     #if defined(__GNUC__) && defined(Q_OS_LINUX)
338     signal(SIGILL, stacktrace);
339     signal(SIGFPE, stacktrace);
340     signal(SIGSEGV, stacktrace);
341     signal(SIGABRT, stacktrace);
342     signal(SIGBUS, stacktrace);
343     #endif
344     #endif
345     qsamplerApplication app(argc, argv);
346    
347     #if defined(__APPLE__) // Toshi Nagata 20080105
348     {
349     // Set the plugin path to @exetutable_path/../plugins
350     QDir dir(QApplication::applicationDirPath());
351     dir.cdUp(); // "Contents" directory
352     QApplication::setLibraryPaths(QStringList(dir.absolutePath() + "/plugins"));
353    
354     // Set the PATH environment variable to include @executable_path/../../..
355     dir.cdUp();
356     dir.cdUp();
357     QString path(getenv("PATH"));
358     path = dir.absolutePath() + ":" + path;
359     setenv("PATH", path.toUtf8().constData(), 1);
360     }
361     #endif
362    
363     // Construct default settings; override with command line arguments.
364     QSampler::Options options;
365     if (!options.parse_args(app.arguments())) {
366     app.quit();
367     return 1;
368     }
369    
370     // Have another instance running?
371     if (app.setup()) {
372     app.quit();
373     return 2;
374     }
375    
376     // Dark themes grayed/disabled color group fix...
377     QPalette pal(app.palette());
378     if (pal.base().color().value() < 0x7f) {
379 capela 2415 #if QT_VERSION >= 0x050000
380     const QColor& color = pal.window().color();
381     const int iGroups = int(QPalette::Active | QPalette::Inactive) + 1;
382     for (int i = 0; i < iGroups; ++i) {
383     const QPalette::ColorGroup group = QPalette::ColorGroup(i);
384     pal.setBrush(group, QPalette::Light, color.lighter(150));
385     pal.setBrush(group, QPalette::Midlight, color.lighter(120));
386     pal.setBrush(group, QPalette::Dark, color.darker(150));
387     pal.setBrush(group, QPalette::Mid, color.darker(120));
388     pal.setBrush(group, QPalette::Shadow, color.darker(200));
389     }
390     // pal.setColor(QPalette::Disabled, QPalette::ButtonText, pal.mid().color());
391     #endif
392 capela 2074 pal.setColorGroup(QPalette::Disabled,
393     pal.windowText().color().darker(),
394     pal.button(),
395     pal.light(),
396     pal.dark(),
397     pal.mid(),
398     pal.text().color().darker(),
399     pal.text().color().lighter(),
400     pal.base(),
401     pal.window());
402     app.setPalette(pal);
403     }
404    
405     // Set default base font...
406     int iBaseFontSize = app.font().pointSize();
407     if (options.iBaseFontSize > 0)
408     iBaseFontSize = options.iBaseFontSize;
409     app.setFont(QFont(app.font().family(), iBaseFontSize));
410    
411     // Construct, setup and show the main form.
412     QSampler::MainForm w;
413     w.setup(&options);
414     w.show();
415    
416     // Settle this one as application main widget...
417     app.setMainWidget(&w);
418    
419     // Register the quit signal/slot.
420     // app.connect(&app, SIGNAL(lastWindowClosed()), &app, SLOT(quit()));
421    
422     return app.exec();
423     }
424    
425    
426     // end of qsampler.cpp

  ViewVC Help
Powered by ViewVC