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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2144 - (hide annotations) (download)
Wed Oct 6 18:49:54 2010 UTC (13 years, 5 months ago) by persson
File size: 10223 byte(s)
* Fixes for cross compiling and building for Windows with configure
  and make.
* Made lookup of translation files more robust on Windows

1 capela 2074 // qsampler.cpp
2     //
3     /****************************************************************************
4     Copyright (C) 2004-2010, rncbc aka Rui Nuno Capela. All rights reserved.
5     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    
41     //-------------------------------------------------------------------------
42     // Singleton application instance stuff (Qt/X11 only atm.)
43     //
44    
45     #if defined(Q_WS_X11)
46    
47     #include <QX11Info>
48    
49     #include <X11/Xatom.h>
50     #include <X11/Xlib.h>
51    
52     #define QSAMPLER_XUNIQUE "qsamplerMainForm_xunique"
53    
54     #endif
55    
56     class qsamplerApplication : public QApplication
57     {
58     public:
59    
60     // Constructor.
61     qsamplerApplication(int& argc, char **argv) : QApplication(argc, argv),
62     m_pQtTranslator(0), m_pMyTranslator(0), m_pWidget(0)
63     {
64     // Load translation support.
65     QLocale loc;
66     if (loc.language() != QLocale::C) {
67     // Try own Qt translation...
68     m_pQtTranslator = new QTranslator(this);
69     QString sLocName = "qt_" + loc.name();
70     QString sLocPath = QLibraryInfo::location(QLibraryInfo::TranslationsPath);
71     if (m_pQtTranslator->load(sLocName, sLocPath)) {
72     QApplication::installTranslator(m_pQtTranslator);
73     } else {
74 persson 2144 #if WIN32
75     sLocPath = QApplication::applicationDirPath() + "/share/locale";
76     if (m_pQtTranslator->load(sLocName, sLocPath)) {
77     QApplication::installTranslator(m_pQtTranslator);
78     } else {
79     #endif
80 capela 2074 delete m_pQtTranslator;
81     m_pQtTranslator = 0;
82     #ifdef CONFIG_DEBUG
83     qWarning("Warning: no translation found for '%s' locale: %s/%s.qm",
84     loc.name().toUtf8().constData(),
85     sLocPath.toUtf8().constData(),
86     sLocName.toUtf8().constData());
87     #endif
88 persson 2144 #if WIN32
89     }
90     #endif
91 capela 2074 }
92     // Try own application translation...
93     m_pMyTranslator = new QTranslator(this);
94     sLocName = "qsampler_" + loc.name();
95     if (m_pMyTranslator->load(sLocName, sLocPath)) {
96     QApplication::installTranslator(m_pMyTranslator);
97     } else {
98 persson 2144 #if WIN32
99     sLocPath = QApplication::applicationDirPath() + "/share/locale";
100     #else
101 capela 2074 sLocPath = CONFIG_PREFIX "/share/locale";
102 persson 2144 #endif
103 capela 2074 if (m_pMyTranslator->load(sLocName, sLocPath)) {
104     QApplication::installTranslator(m_pMyTranslator);
105     } else {
106     delete m_pMyTranslator;
107     m_pMyTranslator = 0;
108     #ifdef CONFIG_DEBUG
109     qWarning("Warning: no translation found for '%s' locale: %s/%s.qm",
110     loc.name().toUtf8().constData(),
111     sLocPath.toUtf8().constData(),
112     sLocName.toUtf8().constData());
113     #endif
114     }
115     }
116     }
117     #if defined(Q_WS_X11)
118     m_pDisplay = QX11Info::display();
119     m_aUnique = XInternAtom(m_pDisplay, QSAMPLER_XUNIQUE, false);
120     XGrabServer(m_pDisplay);
121     m_wOwner = XGetSelectionOwner(m_pDisplay, m_aUnique);
122     XUngrabServer(m_pDisplay);
123     #endif
124     }
125    
126     // Destructor.
127     ~qsamplerApplication()
128     {
129     if (m_pMyTranslator) delete m_pMyTranslator;
130     if (m_pQtTranslator) delete m_pQtTranslator;
131     }
132    
133     // Main application widget accessors.
134     void setMainWidget(QWidget *pWidget)
135     {
136     m_pWidget = pWidget;
137     #if defined(Q_WS_X11)
138     XGrabServer(m_pDisplay);
139     m_wOwner = m_pWidget->winId();
140     XSetSelectionOwner(m_pDisplay, m_aUnique, m_wOwner, CurrentTime);
141     XUngrabServer(m_pDisplay);
142     #endif
143     }
144    
145     QWidget *mainWidget() const { return m_pWidget; }
146    
147     // Check if another instance is running,
148     // and raise its proper main widget...
149     bool setup()
150     {
151     #if defined(Q_WS_X11)
152     if (m_wOwner != None) {
153     // First, notify any freedesktop.org WM
154     // that we're about to show the main widget...
155     Screen *pScreen = XDefaultScreenOfDisplay(m_pDisplay);
156     int iScreen = XScreenNumberOfScreen(pScreen);
157     XEvent ev;
158     memset(&ev, 0, sizeof(ev));
159     ev.xclient.type = ClientMessage;
160     ev.xclient.display = m_pDisplay;
161     ev.xclient.window = m_wOwner;
162     ev.xclient.message_type = XInternAtom(m_pDisplay, "_NET_ACTIVE_WINDOW", false);
163     ev.xclient.format = 32;
164     ev.xclient.data.l[0] = 0; // Source indication.
165     ev.xclient.data.l[1] = 0; // Timestamp.
166     ev.xclient.data.l[2] = 0; // Requestor's currently active window (none)
167     ev.xclient.data.l[3] = 0;
168     ev.xclient.data.l[4] = 0;
169     XSelectInput(m_pDisplay, m_wOwner, StructureNotifyMask);
170     XSendEvent(m_pDisplay, RootWindow(m_pDisplay, iScreen), false,
171     (SubstructureNotifyMask | SubstructureRedirectMask), &ev);
172     XSync(m_pDisplay, false);
173     XRaiseWindow(m_pDisplay, m_wOwner);
174     // And then, let it get caught on destination
175     // by QApplication::x11EventFilter...
176     QByteArray value = QSAMPLER_XUNIQUE;
177     XChangeProperty(
178     m_pDisplay,
179     m_wOwner,
180     m_aUnique,
181     m_aUnique, 8,
182     PropModeReplace,
183     (unsigned char *) value.data(),
184     value.length());
185     // Done.
186     return true;
187     }
188     #endif
189     return false;
190     }
191    
192     #if defined(Q_WS_X11)
193     bool x11EventFilter(XEvent *pEv)
194     {
195     if (m_pWidget && m_wOwner != None
196     && pEv->type == PropertyNotify
197     && pEv->xproperty.window == m_wOwner
198     && pEv->xproperty.state == PropertyNewValue) {
199     // Always check whether our property-flag is still around...
200     Atom aType;
201     int iFormat = 0;
202     unsigned long iItems = 0;
203     unsigned long iAfter = 0;
204     unsigned char *pData = 0;
205     if (XGetWindowProperty(
206     m_pDisplay,
207     m_wOwner,
208     m_aUnique,
209     0, 1024,
210     false,
211     m_aUnique,
212     &aType,
213     &iFormat,
214     &iItems,
215     &iAfter,
216     &pData) == Success
217     && aType == m_aUnique && iItems > 0 && iAfter == 0) {
218     // Avoid repeating it-self...
219     XDeleteProperty(m_pDisplay, m_wOwner, m_aUnique);
220     // Just make it always shows up fine...
221     m_pWidget->show();
222     m_pWidget->raise();
223     m_pWidget->activateWindow();
224     }
225     // Free any left-overs...
226     if (iItems > 0 && pData)
227     XFree(pData);
228     }
229     return QApplication::x11EventFilter(pEv);
230     }
231     #endif
232    
233     private:
234    
235     // Translation support.
236     QTranslator *m_pQtTranslator;
237     QTranslator *m_pMyTranslator;
238    
239     // Instance variables.
240     QWidget *m_pWidget;
241    
242     #if defined(Q_WS_X11)
243     Display *m_pDisplay;
244     Atom m_aUnique;
245     Window m_wOwner;
246     #endif
247     };
248    
249    
250     //-------------------------------------------------------------------------
251     // stacktrace - Signal crash handler.
252     //
253    
254     #ifdef CONFIG_STACKTRACE
255     #if defined(__GNUC__) && defined(Q_OS_LINUX)
256    
257     #include <stdio.h>
258     #include <errno.h>
259     #include <signal.h>
260     #include <sys/wait.h>
261    
262     void stacktrace ( int signo )
263     {
264     pid_t pid;
265     int rc;
266     int status = 0;
267     char cmd[80];
268    
269     // Reinstall default handler; prevent race conditions...
270     signal(signo, SIG_DFL);
271    
272     static const char *shell = "/bin/sh";
273     static const char *format = "gdb -q --batch --pid=%d --eval-command=bt";
274    
275     snprintf(cmd, sizeof(cmd), format, (int) getpid());
276    
277     pid = fork();
278    
279     // Fork failure!
280     if (pid < 0)
281     return;
282    
283     // Fork child...
284     if (pid == 0) {
285     execl(shell, shell, "-c", cmd, NULL);
286     _exit(1);
287     return;
288     }
289    
290     // Parent here: wait for child to terminate...
291     do { rc = waitpid(pid, &status, 0); }
292     while ((rc < 0) && (errno == EINTR));
293    
294     // Dispatch any logging, if any...
295     QApplication::processEvents(QEventLoop::AllEvents, 3000);
296    
297     // Make sure everyone terminates...
298     kill(pid, SIGTERM);
299     _exit(1);
300     }
301    
302     #endif
303     #endif
304    
305    
306     //-------------------------------------------------------------------------
307     // main - The main program trunk.
308     //
309    
310     int main ( int argc, char **argv )
311     {
312     Q_INIT_RESOURCE(qsampler);
313     #ifdef CONFIG_STACKTRACE
314     #if defined(__GNUC__) && defined(Q_OS_LINUX)
315     signal(SIGILL, stacktrace);
316     signal(SIGFPE, stacktrace);
317     signal(SIGSEGV, stacktrace);
318     signal(SIGABRT, stacktrace);
319     signal(SIGBUS, stacktrace);
320     #endif
321     #endif
322     qsamplerApplication app(argc, argv);
323    
324     #if defined(__APPLE__) // Toshi Nagata 20080105
325     {
326     // Set the plugin path to @exetutable_path/../plugins
327     QDir dir(QApplication::applicationDirPath());
328     dir.cdUp(); // "Contents" directory
329     QApplication::setLibraryPaths(QStringList(dir.absolutePath() + "/plugins"));
330    
331     // Set the PATH environment variable to include @executable_path/../../..
332     dir.cdUp();
333     dir.cdUp();
334     QString path(getenv("PATH"));
335     path = dir.absolutePath() + ":" + path;
336     setenv("PATH", path.toUtf8().constData(), 1);
337     }
338     #endif
339    
340     // Construct default settings; override with command line arguments.
341     QSampler::Options options;
342     if (!options.parse_args(app.arguments())) {
343     app.quit();
344     return 1;
345     }
346    
347     // Have another instance running?
348     if (app.setup()) {
349     app.quit();
350     return 2;
351     }
352    
353     // Dark themes grayed/disabled color group fix...
354     QPalette pal(app.palette());
355     if (pal.base().color().value() < 0x7f) {
356     pal.setColorGroup(QPalette::Disabled,
357     pal.windowText().color().darker(),
358     pal.button(),
359     pal.light(),
360     pal.dark(),
361     pal.mid(),
362     pal.text().color().darker(),
363     pal.text().color().lighter(),
364     pal.base(),
365     pal.window());
366     app.setPalette(pal);
367     }
368    
369     // Set default base font...
370     int iBaseFontSize = app.font().pointSize();
371     if (options.iBaseFontSize > 0)
372     iBaseFontSize = options.iBaseFontSize;
373     app.setFont(QFont(app.font().family(), iBaseFontSize));
374    
375     // Construct, setup and show the main form.
376     QSampler::MainForm w;
377     w.setup(&options);
378     w.show();
379    
380     // Settle this one as application main widget...
381     app.setMainWidget(&w);
382    
383     // Register the quit signal/slot.
384     // app.connect(&app, SIGNAL(lastWindowClosed()), &app, SLOT(quit()));
385    
386     return app.exec();
387     }
388    
389    
390     // end of qsampler.cpp

  ViewVC Help
Powered by ViewVC