1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
|
/*
This is part of TeXworks, an environment for working with TeX documents
Copyright (C) 2007-08 Jonathan Kew
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
For links to further information, or to contact the author,
see <http://texworks.org/>.
*/
#include "TWApp.h"
#include "TWVersion.h"
#include <QTimer>
#include <QTextCodec>
#ifdef Q_WS_WIN
BOOL CALLBACK enumThreadWindowProc(HWND hWnd, LPARAM /*lParam*/)
{
if (IsWindowVisible(hWnd))
SetForegroundWindow(hWnd);
return true;
}
#endif
int main(int argc, char *argv[])
{
#ifdef Q_WS_WIN // single-instance code for Windows
#define TW_MUTEX_NAME "org.tug.texworks-" TEXWORKS_VERSION
HANDLE hMutex = CreateMutexA(NULL, FALSE, TW_MUTEX_NAME);
if (hMutex == NULL)
return 0; // failure
if (GetLastError() == ERROR_ALREADY_EXISTS) {
// this is a second instance: bring the original instance to the top
for (int retry = 0; retry < 100; ++retry) {
HWND hWnd = FindWindowExA(HWND_MESSAGE, NULL, TW_HIDDEN_WINDOW_CLASS, NULL);
if (hWnd) {
// pull the app's (visible) windows to the foreground
DWORD thread = GetWindowThreadProcessId(hWnd, NULL);
(void)EnumThreadWindows(thread, &enumThreadWindowProc, 0);
// send each cmd-line arg as a WM_COPYDATA message to load a file
for (int i = 1; i < argc; ++i) {
COPYDATASTRUCT cds;
cds.dwData = TW_OPEN_FILE_MSG;
cds.cbData = strlen(argv[i]);
cds.lpData = argv[i];
SendMessageA(hWnd, WM_COPYDATA, 0, (LPARAM)&cds);
}
break;
}
// couldn't find the other instance; not ready yet?
// sleep for 50ms and then retry
Sleep(50);
}
CloseHandle(hMutex); // close our handle to the mutex
return 0;
}
#endif
TWApp app(argc, argv);
#ifdef Q_WS_X11
if (QDBusConnection::sessionBus().registerService(TW_SERVICE_NAME) == false) {
QDBusInterface interface(TW_SERVICE_NAME, TW_APP_PATH, TW_INTERFACE_NAME);
if (interface.isValid()) {
interface.call("bringToFront");
for (int i = 1; i < argc; ++i)
interface.call("openFile", QString(argv[i]));
}
return 0;
}
new TWAdaptor(&app);
if (QDBusConnection::sessionBus().registerObject(TW_APP_PATH, &app) == false) {
// failed to register the application object, so unregister our service
// and continue as a multiple-instance app instead
(void)QDBusConnection::sessionBus().unregisterService(TW_SERVICE_NAME);
}
#endif
// first argument is the executable name, so we skip that
for (int i = 1; i < argc; ++i)
app.open(QTextCodec::codecForLocale()->toUnicode(argv[i]));
QTimer::singleShot(1, &app, SLOT(launchAction()));
int rval = app.exec();
#ifdef Q_WS_WIN
CloseHandle(hMutex);
#endif
return rval;
}
|