1 /*
2 * synergy -- mouse and keyboard sharing utility
3 * Copyright (C) 2012-2016 Symless Ltd.
4 * Copyright (C) 2008 Volker Lanz (vl@fidra.de)
5 *
6 * This package is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * found in the file LICENSE that should have accompanied this file.
9 *
10 * This package is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #include "QSynergyApplication.h"
20 #include "LicenseManager.h"
21 #include "MainWindow.h"
22 #include "AppConfig.h"
23 #include "SetupWizard.h"
24 #include "SetupWizardBlocker.h"
25
26 #include <QtCore>
27 #include <QtGui>
28 #include <QMessageBox>
29
30 #if defined(Q_OS_MAC)
31 #include <Carbon/Carbon.h>
32 #endif
33
34 #ifdef Q_OS_DARWIN
35 #include <cstdlib>
36 #endif
37
38 class QThreadImpl : public QThread
39 {
40 public:
msleep(unsigned long msecs)41 static void msleep(unsigned long msecs)
42 {
43 QThread::msleep(msecs);
44 }
45 };
46
47 QString getSystemSettingPath();
48
49 #if defined(Q_OS_MAC)
50 bool checkMacAssistiveDevices();
51 #endif
52
main(int argc,char * argv[])53 int main(int argc, char* argv[])
54 {
55 #ifdef Q_OS_DARWIN
56 /* Workaround for QTBUG-40332 - "High ping when QNetworkAccessManager is instantiated" */
57 ::setenv ("QT_BEARER_POLL_TIMEOUT", "-1", 1);
58 #endif
59
60 #if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)
61 QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
62 #endif
63
64 QCoreApplication::setOrganizationName("Synergy");
65 QCoreApplication::setOrganizationDomain("http://symless.com/");
66 QCoreApplication::setApplicationName("Synergy");
67
68 QSynergyApplication app(argc, argv);
69
70 #if defined(Q_OS_MAC)
71
72 if (app.applicationDirPath().startsWith("/Volumes/")) {
73 QMessageBox::information(
74 NULL, "Synergy",
75 "Please drag Synergy to the Applications folder, and open it from there.");
76 return 1;
77 }
78
79 if (!checkMacAssistiveDevices())
80 {
81 return 1;
82 }
83 #endif
84
85 #ifndef Q_OS_WIN
86 QApplication::setQuitOnLastWindowClosed(false);
87 #endif
88
89 AppConfig appConfig;
90 qRegisterMetaType<Edition>("Edition");
91 #ifndef SYNERGY_ENTERPRISE
92 LicenseManager licenseManager (&appConfig);
93 #endif
94
95 app.switchTranslator(appConfig.language());
96
97 #ifdef SYNERGY_ENTERPRISE
98 MainWindow mainWindow(appConfig);
99 #else
100 MainWindow mainWindow(appConfig, licenseManager);
101 #endif
102
103 QObject::connect(dynamic_cast<QObject*>(&app), SIGNAL(aboutToQuit()),
104 &mainWindow, SLOT(saveSettings()));
105
106 std::unique_ptr<SetupWizardBlocker> setupBlocker;
107 if (qgetenv("XDG_SESSION_TYPE") == "wayland")
108 {
109 setupBlocker.reset(new SetupWizardBlocker(mainWindow, SetupWizardBlocker::qBlockerType::waylandDetected));
110 setupBlocker->show();
111 return QApplication::exec();
112 }
113
114 std::unique_ptr<SetupWizard> setupWizard;
115 if (appConfig.wizardShouldRun())
116 {
117 setupWizard.reset(new SetupWizard(mainWindow));
118 setupWizard->show();
119 }
120 else
121 {
122 mainWindow.open();
123 }
124
125 return app.exec();
126 }
127
128
129 #if defined(Q_OS_MAC)
checkMacAssistiveDevices()130 bool checkMacAssistiveDevices()
131 {
132 #if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090 // mavericks
133
134 // new in mavericks, applications are trusted individually
135 // with use of the accessibility api. this call will show a
136 // prompt which can show the security/privacy/accessibility
137 // tab, with a list of allowed applications. synergy should
138 // show up there automatically, but will be unchecked.
139
140 if (AXIsProcessTrusted()) {
141 return true;
142 }
143
144 const void* keys[] = { kAXTrustedCheckOptionPrompt };
145 const void* trueValue[] = { kCFBooleanTrue };
146 CFDictionaryRef options = CFDictionaryCreate(NULL, keys, trueValue, 1, NULL, NULL);
147
148 bool result = AXIsProcessTrustedWithOptions(options);
149 CFRelease(options);
150 return result;
151
152 #else
153
154 // now deprecated in mavericks.
155 bool result = AXAPIEnabled();
156 if (!result) {
157 QMessageBox::information(
158 NULL, "Synergy",
159 "Please enable access to assistive devices "
160 "System Preferences -> Security & Privacy -> "
161 "Privacy -> Accessibility, then re-open Synergy.");
162 }
163 return result;
164
165 #endif
166 }
167 #endif
168