Some tweaks to VapourSynth detection code, which should fix detection of the "portabl...
[simple-x264-launcher.git] / src / global.cpp
blob52d1af3a618521ff2775b272297e6c267f6bd03c
1 ///////////////////////////////////////////////////////////////////////////////
2 // Simple x264 Launcher
3 // Copyright (C) 2004-2024 LoRd_MuldeR <MuldeR2@GMX.de>
4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 2 of the License, or
8 // (at your option) any later version.
9 //
10 // This program 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.
15 // You should have received a copy of the GNU General Public License along
16 // with this program; if not, write to the Free Software Foundation, Inc.,
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 // http://www.gnu.org/licenses/gpl-2.0.txt
20 ///////////////////////////////////////////////////////////////////////////////
22 //x264 includes
23 #include "global.h"
24 #include "targetver.h"
26 //Windows includes
27 #define NOMINMAX
28 #define WIN32_LEAN_AND_MEAN
29 #include <Windows.h>
30 #include <MMSystem.h>
31 #include <ShellAPI.h>
32 #include <Objbase.h>
33 #include <Psapi.h>
34 #include <SensAPI.h>
36 //C++ includes
37 #include <stdio.h>
38 #include <string.h>
39 #include <iostream>
40 #include <time.h>
42 //VLD
43 #include <vld.h>
45 //Version
46 #define ENABLE_X264_VERSION_INCLUDE
47 #include "version.h"
48 #undef ENABLE_X264_VERSION_INCLUDE
50 //MUtils includes
51 #include <MUtils/Global.h>
53 //Qt includes
54 #include <QApplication>
55 #include <QMessageBox>
56 #include <QDir>
57 #include <QUuid>
58 #include <QMap>
59 #include <QDate>
60 #include <QIcon>
61 #include <QPlastiqueStyle>
62 #include <QImageReader>
63 #include <QSharedMemory>
64 #include <QSysInfo>
65 #include <QStringList>
66 #include <QSystemSemaphore>
67 #include <QDesktopServices>
68 #include <QMutex>
69 #include <QTextCodec>
70 #include <QLibrary>
71 #include <QRegExp>
72 #include <QResource>
73 #include <QTranslator>
74 #include <QEventLoop>
75 #include <QTimer>
76 #include <QLibraryInfo>
77 #include <QEvent>
78 #include <QReadLocker>
79 #include <QWriteLocker>
80 #include <QProcess>
82 //CRT includes
83 #include <fstream>
84 #include <io.h>
85 #include <fcntl.h>
86 #include <intrin.h>
87 #include <process.h>
89 //Debug only includes
90 #if X264_DEBUG
91 #include <Psapi.h>
92 #endif
94 //Global types
95 typedef HRESULT (WINAPI *SHGetKnownFolderPath_t)(const GUID &rfid, DWORD dwFlags, HANDLE hToken, PWSTR *ppszPath);
96 typedef HRESULT (WINAPI *SHGetFolderPath_t)(HWND hwndOwner, int nFolder, HANDLE hToken, DWORD dwFlags, LPWSTR pszPath);
98 //Const
99 static const char *g_x264_months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
100 static const char *g_x264_imageformats[] = {"png", "jpg", "gif", "ico", "svg", NULL};
102 //Build version
103 static const struct
105 unsigned int ver_major;
106 unsigned int ver_minor;
107 unsigned int ver_patch;
108 unsigned int ver_build;
110 g_x264_version =
112 (VER_X264_MAJOR),
113 (VER_X264_MINOR),
114 (VER_X264_PATCH),
115 (VER_X264_BUILD),
118 //Portable mode
119 static QReadWriteLock g_portableModeLock;
120 static bool g_portableModeData = false;
121 static bool g_portableModeInit = false;
123 //Data path
124 static QString g_dataPathData;
125 static QReadWriteLock g_dataPathLock;
127 ///////////////////////////////////////////////////////////////////////////////
128 // MACROS
129 ///////////////////////////////////////////////////////////////////////////////
131 //String helper
132 #define CLEAN_OUTPUT_STRING(STR) do \
134 const char CTRL_CHARS[3] = { '\r', '\n', '\t' }; \
135 for(size_t i = 0; i < 3; i++) \
137 while(char *pos = strchr((STR), CTRL_CHARS[i])) *pos = char(0x20); \
140 while(0)
142 //String helper
143 #define TRIM_LEFT(STR) do \
145 const char WHITE_SPACE[4] = { char(0x20), '\r', '\n', '\t' }; \
146 for(size_t i = 0; i < 4; i++) \
148 while(*(STR) == WHITE_SPACE[i]) (STR)++; \
151 while(0)
153 //Check for CLI flag
154 static inline bool _CHECK_FLAG(const int argc, char **argv, const char *flag)
156 for(int i = 1; i < argc; i++)
158 if(_stricmp(argv[i], flag) == 0) return true;
160 return false;
163 #define CHECK_FLAG(FLAG) _CHECK_FLAG(argc, argv, "--" FLAG)
164 #define X264_ZERO_MEMORY(X) SecureZeroMemory(&X, sizeof(X))
166 ///////////////////////////////////////////////////////////////////////////////
167 // GLOBAL FUNCTIONS
168 ///////////////////////////////////////////////////////////////////////////////
171 * Version info
173 unsigned int x264_version_major(void)
175 return g_x264_version.ver_major;
178 unsigned int x264_version_minor(void)
180 return (g_x264_version.ver_minor * 10) + (g_x264_version.ver_patch % 10);
183 unsigned int x264_version_build(void)
185 return g_x264_version.ver_build;
189 * Check for portable mode
191 bool x264_is_portable(void)
193 QReadLocker readLock(&g_portableModeLock);
195 if(g_portableModeInit)
197 return g_portableModeData;
200 readLock.unlock();
201 QWriteLocker writeLock(&g_portableModeLock);
203 if(!g_portableModeInit)
205 if(VER_X264_PORTABLE_EDITION)
207 qWarning("Simple x264 Launcher portable edition!\n");
208 g_portableModeData = true;
210 else
212 QString baseName = QFileInfo(QApplication::applicationFilePath()).completeBaseName();
213 int idx1 = baseName.indexOf("x264", 0, Qt::CaseInsensitive);
214 int idx2 = baseName.lastIndexOf("portable", -1, Qt::CaseInsensitive);
215 g_portableModeData = (idx1 >= 0) && (idx2 >= 0) && (idx1 < idx2);
217 g_portableModeInit = true;
220 return g_portableModeData;
224 * Get data path (i.e. path to store config files)
226 const QString &x264_data_path(void)
228 QReadLocker readLock(&g_dataPathLock);
230 if(!g_dataPathData.isEmpty())
232 return g_dataPathData;
235 readLock.unlock();
236 QWriteLocker writeLock(&g_dataPathLock);
238 if(g_dataPathData.isEmpty())
240 g_dataPathData = QDesktopServices::storageLocation(QDesktopServices::DataLocation);
241 if(g_dataPathData.isEmpty() || x264_is_portable())
243 g_dataPathData = QApplication::applicationDirPath();
245 if(!QDir(g_dataPathData).mkpath("."))
247 qWarning("Data directory could not be created:\n%s\n", g_dataPathData.toUtf8().constData());
248 g_dataPathData = QDir::currentPath();
252 return g_dataPathData;
256 * Is pre-release version?
258 bool x264_is_prerelease(void)
260 return (VER_X264_PRE_RELEASE);
264 * Convert path to short/ANSI path
266 QString x264_path2ansi(const QString &longPath, bool makeLowercase)
268 QString shortPath = longPath;
270 const QString longPathNative = QDir::toNativeSeparators(longPath);
271 DWORD buffSize = GetShortPathNameW(MUTILS_WCHR(longPathNative), NULL, NULL);
273 if(buffSize > 0)
275 wchar_t *buffer = (wchar_t*) _malloca(sizeof(wchar_t) * buffSize);
276 DWORD result = GetShortPathNameW(MUTILS_WCHR(longPathNative), buffer, buffSize);
278 if((result > 0) && (result < buffSize))
280 shortPath = QDir::fromNativeSeparators(QString::fromUtf16(reinterpret_cast<const unsigned short*>(buffer), result));
282 if(makeLowercase)
284 QFileInfo info(shortPath);
285 shortPath = QString("%1/%2").arg(info.absolutePath(), info.fileName().toLower());
289 _freea(buffer);
290 buffer = NULL;
293 return shortPath;
297 * Inform the system that it is in use, thereby preventing the system from entering sleep
299 bool x264_set_thread_execution_state(const bool systemRequired)
301 EXECUTION_STATE state = NULL;
302 if(systemRequired)
304 state = SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED | ES_AWAYMODE_REQUIRED);
306 else
308 state = SetThreadExecutionState(ES_CONTINUOUS);
310 return (state != NULL);