1 // Copyright 2005-2019 The Mumble Developers. All rights reserved.
2 // Use of this source code is governed by a BSD-style license
3 // that can be found in the LICENSE file at the root of the
4 // Mumble source tree or at <https://www.mumble.info/LICENSE>.
5
6 #include "mumble_pch.hpp"
7
8 #include "Global.h"
9
10 Global *Global::g_global_struct;
11
12 #ifndef Q_OS_WIN
migrateDataDir()13 static void migrateDataDir() {
14 #ifdef Q_OS_MAC
15 QString olddir = QDir::homePath() + QLatin1String("/Library/Preferences/Mumble");
16 #if QT_VERSION >= 0x050000
17 QString newdir = QStandardPaths::writableLocation(QStandardPaths::DataLocation);
18 #else
19 QString newdir = QDesktopServices::storageLocation(QDesktopServices::DataLocation);
20 #endif // QT_VERSION
21 QString linksTo = QFile::readLink(olddir);
22 if (!QFile::exists(newdir) && QFile::exists(olddir) && linksTo.isEmpty()) {
23 QDir d;
24 d.mkpath(newdir + QLatin1String("/.."));
25 if (d.rename(olddir, newdir)) {
26 if (d.cd(QDir::homePath() + QLatin1String("/Library/Preferences"))) {
27 if (QFile::link(d.relativeFilePath(newdir), olddir)) {
28 qWarning("Migrated application data directory from '%s' to '%s'",
29 qPrintable(olddir), qPrintable(newdir));
30 return;
31 }
32 }
33 }
34 } else {
35 /* Data dir has already been migrated. */
36 return;
37 }
38
39 qWarning("Application data migration failed.");
40 #endif // Q_OS_MAC
41
42 // Qt4 used another data directory on Unix-like systems, to ensure a seamless
43 // transition we must first move the users data to the new directory.
44 #if defined(Q_OS_UNIX) && ! defined(Q_OS_MAC)
45 #if QT_VERSION >= 0x050000
46 QString olddir = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1String("/data/Mumble");
47 QString newdir = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1String("/Mumble");
48
49 if (!QFile::exists(newdir) && QFile::exists(olddir)) {
50 QDir d;
51 if (d.rename(olddir, newdir)) {
52 qWarning("Migrated application data directory from '%s' to '%s'",
53 qPrintable(olddir), qPrintable(newdir));
54 return;
55 }
56 } else {
57 /* Data dir has already been migrated. */
58 return;
59 }
60
61 qWarning("Application data migration failed.");
62 #endif // QT_VERSION
63 #endif // defined(Q_OS_UNIX) && ! defined(Q_OS_MAC)
64 }
65 #endif // Q_OS_WIN
66
Global()67 Global::Global() {
68 mw = 0;
69 db = 0;
70 p = 0;
71 nam = 0;
72 c = 0;
73 uiSession = 0;
74 uiDoublePush = 1000000;
75 iPushToTalk = 0;
76 iTarget = 0;
77 iPrevTarget = 0;
78 bPushToMute = false;
79 bCenterPosition = false;
80 bPosTest = false;
81 bInAudioWizard = false;
82 iAudioPathTime = 0;
83 iAudioBandwidth = -1;
84 iMaxBandwidth = -1;
85
86 iCodecAlpha = 0;
87 iCodecBeta = 0;
88 bPreferAlpha = true;
89 #ifdef USE_OPUS
90 bOpus = true;
91 #else
92 bOpus = false;
93 #endif
94
95 bAttenuateOthers = false;
96 prioritySpeakerActiveOverride = false;
97
98 bAllowHTML = true;
99 uiMessageLength = 5000;
100 uiImageLength = 131072;
101 uiMaxUsers = 0;
102
103 qs = NULL;
104
105 ocIntercept = NULL;
106 bc = NULL;
107 lcd = NULL;
108 o = NULL;
109 l = NULL;
110
111 bHappyEaster = false;
112
113 bQuit = false;
114
115 QStringList qsl;
116 qsl << QCoreApplication::instance()->applicationDirPath();
117 #if QT_VERSION >= 0x050000
118 qsl << QStandardPaths::writableLocation(QStandardPaths::DataLocation);
119 #else
120 qsl << QDesktopServices::storageLocation(QDesktopServices::DataLocation);
121 #endif
122 #if defined(Q_OS_WIN)
123 QString appdata;
124 wchar_t appData[MAX_PATH];
125 if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, appData))) {
126 appdata = QDir::fromNativeSeparators(QString::fromWCharArray(appData));
127
128 if (!appdata.isEmpty()) {
129 appdata.append(QLatin1String("/Mumble"));
130 qsl << appdata;
131 }
132 }
133 #endif
134
135 foreach(const QString &dir, qsl) {
136 QFile inifile(QString::fromLatin1("%1/mumble.ini").arg(dir));
137 if (inifile.exists() && inifile.permissions().testFlag(QFile::WriteUser)) {
138 qdBasePath = dir;
139 qs = new QSettings(inifile.fileName(), QSettings::IniFormat);
140 break;
141 }
142 }
143
144 if (!qs) {
145 qs = new QSettings();
146 #if defined(Q_OS_WIN)
147 if (! appdata.isEmpty())
148 qdBasePath.setPath(appdata);
149 #else
150 migrateDataDir();
151 #if QT_VERSION >= 0x050000
152 qdBasePath = QStandardPaths::writableLocation(QStandardPaths::DataLocation);
153 #else
154 qdBasePath = QDesktopServices::storageLocation(QDesktopServices::DataLocation);
155 #endif
156 #endif
157 if (! qdBasePath.exists()) {
158 QDir::root().mkpath(qdBasePath.absolutePath());
159 if (! qdBasePath.exists())
160 qdBasePath = QDir::home();
161 }
162 }
163
164 if (! qdBasePath.exists(QLatin1String("Plugins")))
165 qdBasePath.mkpath(QLatin1String("Plugins"));
166 if (! qdBasePath.exists(QLatin1String("Overlay")))
167 qdBasePath.mkpath(QLatin1String("Overlay"));
168 if (! qdBasePath.exists(QLatin1String("Themes")))
169 qdBasePath.mkpath(QLatin1String("Themes"));
170
171 qs->setIniCodec("UTF-8");
172 }
173
~Global()174 Global::~Global() {
175 delete qs;
176 }
177
178 const char Global::ccHappyEaster[] = {072, 057, 0162, 0145, 0143, 056, 0163, 0166, 0147, 0, 0117, 0160, 0145, 0156, 040, 0164, 0150, 0145, 040, 0160, 0157, 0144, 040, 0142, 0141, 0171, 040, 0144, 0157, 0157, 0162, 0163, 054, 040, 0110, 0101, 0114, 056, 0, 0111, 047, 0155, 040, 0163, 0157, 0162, 0162, 0171, 054, 040, 045, 061, 056, 040, 0111, 047, 0155, 040, 0141, 0146, 0162, 0141, 0151, 0144, 040, 0111, 040, 0143, 0141, 0156, 047, 0164, 040, 0144, 0157, 040, 0164, 0150, 0141, 0164, 056, 0, 0121,0127,0151,0144,0147,0145,0164,0173,0142,0141,0143,0153,0147,0162,0157,0165,0156,0144,055,0143,0157,0154,0157,0162,072,0142,0154,0141,0143,0153,073,0141,0154,0164,0145,0162,0156,0141,0164,0145,055,0142,0141,0143,0153,0147,0162,0157,0165,0156,0144,055,0143,0157,0154,0157,0162,072,043,063,063,060,060,060,060,073,0143,0157,0154,0157,0162,072,0167,0150,0151,0164,0145,073,0175,0121,0124,0145,0170,0164,0102,0162,0157,0167,0163,0145,0162,0173,0142,0141,0143,0153,0147,0162,0157,0165,0156,0144,055,0151,0155,0141,0147,0145,072,0165,0162,0154,050,072,057,0162,0145,0143,056,0163,0166,0147,051,073,0142,0141,0143,0153,0147,0162,0157,0165,0156,0144,055,0160,0157,0163,0151,0164,0151,0157,0156,072,0143,0145,0156,0164,0145,0162,0143,0145,0156,0164,0145,0162,073,0142,0141,0143,0153,0147,0162,0157,0165,0156,0144,055,0143,0154,0151,0160,072,0160,0141,0144,0144,0151,0156,0147,073,0142,0141,0143,0153,0147,0162,0157,0165,0156,0144,055,0157,0162,0151,0147,0151,0156,072,0160,0141,0144,0144,0151,0156,0147,073,0142,0141,0143,0153,0147,0162,0157,0165,0156,0144,055,0162,0145,0160,0145,0141,0164,072,0156,0157,055,0162,0145,0160,0145,0141,0164,073,0142,0141,0143,0153,0147,0162,0157,0165,0156,0144,055,0141,0164,0164,0141,0143,0150,0155,0145,0156,0164,072,0146,0151,0170,0145,0144,073,0175,0121,0115,0145,0156,0165,0102,0141,0162,072,072,0151,0164,0145,0155,0173,0142,0141,0143,0153,0147,0162,0157,0165,0156,0144,072,0164,0162,0141,0156,0163,0160,0141,0162,0145,0156,0164,073,0175,0121,0110,0145,0141,0144,0145,0162,0126,0151,0145,0167,072,072,0163,0145,0143,0164,0151,0157,0156,0173,0142,0141,0143,0153,0147,0162,0157,0165,0156,0144,072,0164,0162,0141,0156,0163,0160,0141,0162,0145,0156,0164,073,0175,0121,0124,0141,0142,0102,0141,0162,072,072,0164,0141,0142,0173,0142,0141,0143,0153,0147,0162,0157,0165,0156,0144,072,0164,0162,0141,0156,0163,0160,0141,0162,0145,0156,0164,073,0175,0};
179
180 QMultiMap<int, DeferInit *> *DeferInit::qmDeferers = NULL;
181
add(int priority)182 void DeferInit::add(int priority) {
183 if (qmDeferers == NULL) {
184 qmDeferers = new QMultiMap<int, DeferInit *>();
185 }
186 qmDeferers->insert(priority, this);
187 }
188
~DeferInit()189 DeferInit::~DeferInit() {
190 }
191
run_initializers()192 void DeferInit::run_initializers() {
193 if (! qmDeferers)
194 return;
195 foreach(DeferInit *d, *qmDeferers) {
196 d->initialize();
197 }
198 }
199
run_destroyers()200 void DeferInit::run_destroyers() {
201 if (! qmDeferers)
202 return;
203 foreach(DeferInit *d, *qmDeferers) {
204 d->destroy();
205 }
206 delete qmDeferers;
207 qmDeferers = NULL;
208 }
209