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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1740 - (show annotations) (download)
Fri May 23 23:35:55 2008 UTC (15 years, 11 months ago) by capela
File size: 7888 byte(s)
* Attempt to load Qt's own translation support and get rid of
  the ever warning startup message, unless built in debug mode.
  (transaction by Guido Scholz, while on qsynth-devel, thanks).

* Only one application instance is now allowed to be up and running,
  with immediate but graceful termination upon startup iif an already
  running instance is detected, which will see its main widget shown
  up automatically (Qt/X11 platform only).

1 // main.cpp
2 //
3 /****************************************************************************
4 Copyright (C) 2004-2008, 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 defined(Q_WS_X11)
36
37 //-------------------------------------------------------------------------
38 // Single application instance stuff (Qt/X11 only atm.)
39 //
40
41 #include <QX11Info>
42
43 #include <X11/Xatom.h>
44 #include <X11/Xlib.h>
45
46 #define QSAMPLER_XUNIQUE "qsamplerMainForm_xunique"
47
48 #endif
49
50 class qsamplerApplication : public QApplication
51 {
52 public:
53
54 // Constructor.
55 qsamplerApplication(int& argc, char **argv) : QApplication(argc, argv),
56 m_pQtTranslator(0), m_pMyTranslator(0), m_pWidget(0)
57 {
58 // Load translation support.
59 QLocale loc;
60 if (loc.language() != QLocale::C) {
61 // Try own Qt translation...
62 m_pQtTranslator = new QTranslator(this);
63 QString sLocName = "qt_" + loc.name();
64 QString sLocPath = QLibraryInfo::location(QLibraryInfo::TranslationsPath);
65 if (m_pQtTranslator->load(sLocName, sLocPath)) {
66 QApplication::installTranslator(m_pQtTranslator);
67 } else {
68 delete m_pQtTranslator;
69 m_pQtTranslator = 0;
70 #ifdef CONFIG_DEBUG
71 qWarning("Warning: no translation found for '%s' locale: %s/%s.qm",
72 loc.name().toUtf8().constData(),
73 sLocPath.toUtf8().constData(),
74 sLocName.toUtf8().constData());
75 #endif
76 }
77 // Try own application translation...
78 m_pMyTranslator = new QTranslator(this);
79 sLocName = "qsampler_" + loc.name();
80 if (m_pMyTranslator->load(sLocName, sLocPath)) {
81 QApplication::installTranslator(m_pMyTranslator);
82 } else {
83 sLocPath = CONFIG_PREFIX "/share/locale";
84 if (m_pMyTranslator->load(sLocName, sLocPath)) {
85 QApplication::installTranslator(m_pMyTranslator);
86 } else {
87 delete m_pMyTranslator;
88 m_pMyTranslator = 0;
89 #ifdef CONFIG_DEBUG
90 qWarning("Warning: no translation found for '%s' locale: %s/%s.qm",
91 loc.name().toUtf8().constData(),
92 sLocPath.toUtf8().constData(),
93 sLocName.toUtf8().constData());
94 #endif
95 }
96 }
97 }
98 #if defined(Q_WS_X11)
99 m_pDisplay = QX11Info::display();
100 m_aUnique = XInternAtom(m_pDisplay, QSAMPLER_XUNIQUE, false);
101 XGrabServer(m_pDisplay);
102 m_wOwner = XGetSelectionOwner(m_pDisplay, m_aUnique);
103 XUngrabServer(m_pDisplay);
104 #endif
105 }
106
107 // Destructor.
108 ~qsamplerApplication()
109 {
110 if (m_pMyTranslator) delete m_pMyTranslator;
111 if (m_pQtTranslator) delete m_pQtTranslator;
112 }
113
114 // Main application widget accessors.
115 void setMainWidget(QWidget *pWidget)
116 {
117 m_pWidget = pWidget;
118 #if defined(Q_WS_X11)
119 XGrabServer(m_pDisplay);
120 m_wOwner = m_pWidget->winId();
121 XSetSelectionOwner(m_pDisplay, m_aUnique, m_wOwner, CurrentTime);
122 XUngrabServer(m_pDisplay);
123 #endif
124 }
125
126 QWidget *mainWidget() const { return m_pWidget; }
127
128 // Check if another instance is running,
129 // and raise its proper main widget...
130 bool setup()
131 {
132 #if defined(Q_WS_X11)
133 if (m_wOwner != None) {
134 // First, notify any freedesktop.org WM
135 // that we're about to show the main widget...
136 Screen *pScreen = XDefaultScreenOfDisplay(m_pDisplay);
137 int iScreen = XScreenNumberOfScreen(pScreen);
138 XEvent ev;
139 memset(&ev, 0, sizeof(ev));
140 ev.xclient.type = ClientMessage;
141 ev.xclient.display = m_pDisplay;
142 ev.xclient.window = m_wOwner;
143 ev.xclient.message_type = XInternAtom(m_pDisplay, "_NET_ACTIVE_WINDOW", false);
144 ev.xclient.format = 32;
145 ev.xclient.data.l[0] = 0; // Source indication.
146 ev.xclient.data.l[1] = 0; // Timestamp.
147 ev.xclient.data.l[2] = 0; // Requestor's currently active window (none)
148 ev.xclient.data.l[3] = 0;
149 ev.xclient.data.l[4] = 0;
150 XSelectInput(m_pDisplay, m_wOwner, StructureNotifyMask);
151 XSendEvent(m_pDisplay, RootWindow(m_pDisplay, iScreen), false,
152 (SubstructureNotifyMask | SubstructureRedirectMask), &ev);
153 XSync(m_pDisplay, false);
154 XRaiseWindow(m_pDisplay, m_wOwner);
155 // And then, let it get caught on destination
156 // by QApplication::x11EventFilter...
157 QByteArray value = QSAMPLER_XUNIQUE;
158 XChangeProperty(
159 m_pDisplay,
160 m_wOwner,
161 m_aUnique,
162 m_aUnique, 8,
163 PropModeReplace,
164 (unsigned char *) value.data(),
165 value.length());
166 // Done.
167 return true;
168 }
169 #endif
170 return false;
171 }
172
173 #if defined(Q_WS_X11)
174 bool x11EventFilter(XEvent *pEv)
175 {
176 if (m_pWidget && m_wOwner != None
177 && pEv->type == PropertyNotify
178 && pEv->xproperty.window == m_wOwner
179 && pEv->xproperty.state == PropertyNewValue) {
180 // Always check whether our property-flag is still around...
181 Atom aType;
182 int iFormat = 0;
183 unsigned long iItems = 0;
184 unsigned long iAfter = 0;
185 unsigned char *pData = 0;
186 if (XGetWindowProperty(
187 m_pDisplay,
188 m_wOwner,
189 m_aUnique,
190 0, 1024,
191 false,
192 m_aUnique,
193 &aType,
194 &iFormat,
195 &iItems,
196 &iAfter,
197 &pData) == Success
198 && aType == m_aUnique && iItems > 0 && iAfter == 0) {
199 // Avoid repeating it-self...
200 XDeleteProperty(m_pDisplay, m_wOwner, m_aUnique);
201 // Just make it always shows up fine...
202 m_pWidget->show();
203 m_pWidget->raise();
204 m_pWidget->activateWindow();
205 }
206 // Free any left-overs...
207 if (iItems > 0 && pData)
208 XFree(pData);
209 }
210 return QApplication::x11EventFilter(pEv);
211 }
212 #endif
213
214 private:
215
216 // Translation support.
217 QTranslator *m_pQtTranslator;
218 QTranslator *m_pMyTranslator;
219
220 // Instance variables.
221 QWidget *m_pWidget;
222
223 #if defined(Q_WS_X11)
224 Display *m_pDisplay;
225 Atom m_aUnique;
226 Window m_wOwner;
227 #endif
228 };
229
230
231 //-------------------------------------------------------------------------
232 // main - The main program trunk.
233 //
234
235 int main ( int argc, char **argv )
236 {
237 Q_INIT_RESOURCE(qsampler);
238
239 qsamplerApplication app(argc, argv);
240
241 #if defined(__APPLE__) // Toshi Nagata 20080105
242 {
243 // Set the plugin path to @exetutable_path/../plugins
244 QDir dir(QApplication::applicationDirPath());
245 dir.cdUp(); // "Contents" directory
246 QApplication::setLibraryPaths(QStringList(dir.absolutePath() + "/plugins"));
247
248 // Set the PATH environment variable to include @executable_path/../../..
249 dir.cdUp();
250 dir.cdUp();
251 QString path(getenv("PATH"));
252 path = dir.absolutePath() + ":" + path;
253 setenv("PATH", path.toUtf8().constData(), 1);
254 }
255 #endif
256
257 // Construct default settings; override with command line arguments.
258 QSampler::Options options;
259 if (!options.parse_args(app.argc(), app.argv())) {
260 app.quit();
261 return 1;
262 }
263
264 // Have another instance running?
265 if (app.setup()) {
266 app.quit();
267 return 2;
268 }
269
270 // Construct, setup and show the main form.
271 QSampler::MainForm w;
272 w.setup(&options);
273 w.show();
274
275 // Settle this one as application main widget...
276 app.setMainWidget(&w);
277
278 // Register the quit signal/slot.
279 // app.connect(&app, SIGNAL(lastWindowClosed()), &app, SLOT(quit()));
280
281 return app.exec();
282 }
283
284
285 // end of main.cpp

  ViewVC Help
Powered by ViewVC