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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2074 - (hide annotations) (download)
Mon Mar 29 17:00:30 2010 UTC (14 years ago) by capela
File size: 9887 byte(s)
* General source tree layout and build configuration change.

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

  ViewVC Help
Powered by ViewVC