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

Contents of /qsampler/trunk/src/qsampler.cpp

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC