summaryrefslogtreecommitdiffstats
path: root/src/winmain/qtmain_winrt.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/winmain/qtmain_winrt.cpp')
-rw-r--r--src/winmain/qtmain_winrt.cpp95
1 files changed, 75 insertions, 20 deletions
diff --git a/src/winmain/qtmain_winrt.cpp b/src/winmain/qtmain_winrt.cpp
index d0f138269f..151294d2c4 100644
--- a/src/winmain/qtmain_winrt.cpp
+++ b/src/winmain/qtmain_winrt.cpp
@@ -44,16 +44,29 @@
linking to the Qt DLL.
When a Windows application starts, the WinMain function is
- invoked. WinMain creates the WinRT application which in turn
- calls the main entry point.
+ invoked. This WinMain creates the WinRT application
+ container, which in turn calls the application's main()
+ entry point within the newly created GUI thread.
*/
-extern "C" int main(int, char **);
+#include <new.h>
+
+typedef struct
+{
+ int newmode;
+} _startupinfo;
+
+extern "C" {
+ int __getmainargs(int *argc, char ***argv, char ***env, int expandWildcards, _startupinfo *info);
+ int main(int, char **);
+}
#include <qbytearray.h>
#include <qstring.h>
#include <qlist.h>
#include <qvector.h>
+#include <qdir.h>
+#include <qstandardpaths.h>
#include <wrl.h>
#include <Windows.ApplicationModel.core.h>
@@ -66,22 +79,22 @@ using namespace Microsoft::WRL;
#define CoreApplicationClass RuntimeClass_Windows_ApplicationModel_Core_CoreApplication
typedef ITypedEventHandler<Core::CoreApplicationView *, Activation::IActivatedEventArgs *> ActivatedHandler;
+static int g_mainExitCode;
+
class AppContainer : public Microsoft::WRL::RuntimeClass<Core::IFrameworkView>
{
public:
- AppContainer(int argc, wchar_t **argv) : m_argc(argc)
+ AppContainer(int argc, char *argv[]) : m_argc(argc)
{
m_argv.reserve(argc);
- for (int i = 0; i < argc; ++i) {
- QByteArray arg = QString::fromWCharArray(argv[i]).toLocal8Bit();
- m_argv.append(qstrdup(arg.constData()));
- }
+ for (int i = 0; i < argc; ++i)
+ m_argv.append(argv[i]);
}
~AppContainer()
{
- foreach (const char *arg, m_argv)
- delete[] arg;
+ for (int i = m_argc; i < m_argv.size(); ++i)
+ delete[] m_argv[i];
}
// IFrameworkView Methods
@@ -95,7 +108,33 @@ public:
HRESULT __stdcall Load(HSTRING) { return S_OK; }
HRESULT __stdcall Run()
{
- return main(m_argv.count(), m_argv.data());
+ bool develMode = false;
+ bool debugWait = false;
+ foreach (const QByteArray &arg, m_argv) {
+ if (arg == "-qdevel")
+ develMode = true;
+ if (arg == "-qdebug")
+ debugWait = true;
+ }
+ if (develMode) {
+ // Write a PID file to help runner
+ const QString pidFileName = QDir(QStandardPaths::writableLocation(QStandardPaths::DataLocation))
+ .absoluteFilePath(QString::number(uint(GetCurrentProcessId())) + QStringLiteral(".pid"));
+ CREATEFILE2_EXTENDED_PARAMETERS params = {
+ sizeof(CREATEFILE2_EXTENDED_PARAMETERS),
+ FILE_ATTRIBUTE_NORMAL, FILE_FLAG_DELETE_ON_CLOSE
+ };
+ // (Unused) handle will automatically be closed when the app exits
+ CreateFile2(reinterpret_cast<LPCWSTR>(pidFileName.utf16()),
+ 0, FILE_SHARE_READ|FILE_SHARE_DELETE, CREATE_ALWAYS, &params);
+ }
+ // Wait for debugger before continuing
+ if (debugWait) {
+ while (!IsDebuggerPresent())
+ WaitForSingleObjectEx(GetCurrentThread(), 1, true);
+ }
+ g_mainExitCode = main(m_argv.count(), m_argv.data());
+ return S_OK;
}
HRESULT __stdcall Uninitialize() { return S_OK; }
@@ -110,9 +149,11 @@ private:
m_argv.resize(m_argc);
HSTRING arguments;
launchArgs->get_Arguments(&arguments);
- foreach (const QByteArray &arg, QString::fromWCharArray(
- WindowsGetStringRawBuffer(arguments, nullptr)).toLocal8Bit().split(' ')) {
- m_argv.append(qstrdup(arg.constData()));
+ if (arguments) {
+ foreach (const QByteArray &arg, QString::fromWCharArray(
+ WindowsGetStringRawBuffer(arguments, nullptr)).toLocal8Bit().split(' ')) {
+ m_argv.append(qstrdup(arg.constData()));
+ }
}
}
return S_OK;
@@ -126,19 +167,32 @@ private:
class AppViewSource : public Microsoft::WRL::RuntimeClass<Core::IFrameworkViewSource>
{
public:
- AppViewSource(int argc, wchar_t *argv[]) : argc(argc), argv(argv) { }
+ AppViewSource(int argc, char **argv) : m_argc(argc), m_argv(argv) { }
HRESULT __stdcall CreateView(Core::IFrameworkView **frameworkView)
{
- return (*frameworkView = Make<AppContainer>(argc, argv).Detach()) ? S_OK : E_OUTOFMEMORY;
+ return (*frameworkView = Make<AppContainer>(m_argc, m_argv).Detach()) ? S_OK : E_OUTOFMEMORY;
}
private:
- int argc;
- wchar_t **argv;
+ int m_argc;
+ char **m_argv;
};
// Main entry point for Appx containers
-int wmain(int argc, wchar_t *argv[])
+int __stdcall WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
+ int argc = 0;
+ char **argv, **env;
+ _startupinfo info = { _query_new_mode() };
+ if (int init = __getmainargs(&argc, &argv, &env, false, &info))
+ return init;
+
+ for (int i = 0; env && env[i]; ++i) {
+ QByteArray var(env[i]);
+ int split = var.indexOf('=');
+ if (split > 0)
+ qputenv(var.mid(0, split), var.mid(split + 1));
+ }
+
if (FAILED(RoInitialize(RO_INIT_MULTITHREADED)))
return 1;
@@ -146,5 +200,6 @@ int wmain(int argc, wchar_t *argv[])
if (FAILED(RoGetActivationFactory(qHString(CoreApplicationClass), IID_PPV_ARGS(&appFactory))))
return 2;
- return appFactory->Run(Make<AppViewSource>(argc, argv).Get());
+ appFactory->Run(Make<AppViewSource>(argc, argv).Get());
+ return g_mainExitCode;
}