summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndrew Knight <andrew.knight@intopalo.com>2015-08-05 08:15:06 +0300
committerAndrew Knight <andrew.knight@intopalo.com>2015-08-13 16:12:18 +0000
commitebc2b963aa9e8ce2e983ef08c9b503ccc1702fdb (patch)
tree30ad3f1000f92b8555fb4e6d10f2b24786e93137 /src
parent130083a7fc07fb8f98e4199832b6c20685a1ea70 (diff)
winrtmain: Start in XAML mode
This allows the platform plugin to start using XAML interfaces in the windowing system. Change-Id: Ifcd29b8b8d83b138af69786dfc6a1adec21be37e Reviewed-by: Maurice Kalinowski <maurice.kalinowski@theqtcompany.com>
Diffstat (limited to 'src')
-rw-r--r--src/winmain/qtmain_winrt.cpp263
1 files changed, 148 insertions, 115 deletions
diff --git a/src/winmain/qtmain_winrt.cpp b/src/winmain/qtmain_winrt.cpp
index 141e3ed135..d9f8c8f991 100644
--- a/src/winmain/qtmain_winrt.cpp
+++ b/src/winmain/qtmain_winrt.cpp
@@ -49,38 +49,44 @@
entry point within the newly created GUI thread.
*/
+#if _MSC_VER < 1900
#include <new.h>
typedef struct
{
int newmode;
} _startupinfo;
+#endif // _MSC_VER < 1900
extern "C" {
+#if _MSC_VER < 1900
int __getmainargs(int *argc, char ***argv, char ***env, int expandWildcards, _startupinfo *info);
+#endif
int main(int, char **);
}
#include <qbytearray.h>
#include <qstring.h>
-#include <qlist.h>
-#include <qvector.h>
#include <qdir.h>
#include <qstandardpaths.h>
+#include <qfunctions_winrt.h>
#include <wrl.h>
#include <Windows.ApplicationModel.core.h>
+#include <windows.ui.xaml.h>
+#include <windows.ui.xaml.controls.h>
using namespace ABI::Windows::ApplicationModel;
+using namespace ABI::Windows::ApplicationModel::Activation;
+using namespace ABI::Windows::ApplicationModel::Core;
using namespace ABI::Windows::Foundation;
+using namespace ABI::Windows::UI;
using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;
#define qHString(x) Wrappers::HString::MakeReference(x).Get()
#define CoreApplicationClass RuntimeClass_Windows_ApplicationModel_Core_CoreApplication
-typedef ITypedEventHandler<Core::CoreApplicationView *, Activation::IActivatedEventArgs *> ActivatedHandler;
-
-static int g_mainExitCode;
+typedef ITypedEventHandler<CoreApplicationView *, Activation::IActivatedEventArgs *> ActivatedHandler;
static QtMessageHandler defaultMessageHandler;
static void devMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &message)
@@ -103,53 +109,112 @@ static void devMessageHandler(QtMsgType type, const QMessageLogContext &context,
defaultMessageHandler(type, context, message);
}
-class AppContainer : public Microsoft::WRL::RuntimeClass<Core::IFrameworkView>
+class AppContainer : public RuntimeClass<Xaml::IApplicationOverrides>
{
public:
- AppContainer(int argc, char *argv[]) : m_argc(argc), m_deleteArgv0(false)
+ AppContainer()
{
- m_argv.reserve(argc);
- for (int i = 0; i < argc; ++i) {
- // Workaround for empty argv[0] which occurs when WMAppManifest's ImageParams is used
- // The second argument is taken to be the executable
- if (i == 0 && argc >= 2 && !qstrlen(argv[0])) {
- const QByteArray argv0 = QDir::current()
- .absoluteFilePath(QString::fromLatin1(argv[1])).toUtf8();
- m_argv.append(qstrdup(argv0.constData()));
- m_argc -= 1;
- m_deleteArgv0 = true;
- ++i;
- continue;
- }
- m_argv.append(argv[i]);
- }
+ ComPtr<Xaml::IApplicationFactory> applicationFactory;
+ HRESULT hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_Xaml_Application).Get(),
+ IID_PPV_ARGS(&applicationFactory));
+ Q_ASSERT_SUCCEEDED(hr);
+
+ hr = applicationFactory->CreateInstance(this, &base, &core);
+ RETURN_VOID_IF_FAILED("Failed to create application container instance");
}
~AppContainer()
{
- if (m_deleteArgv0)
- delete[] m_argv[0];
- for (int i = m_argc; i < m_argv.size(); ++i)
- delete[] m_argv[i];
}
- // IFrameworkView Methods
- HRESULT __stdcall Initialize(Core::ICoreApplicationView *view)
+ int exec(int argc, char **argv)
{
- view->add_Activated(Callback<ActivatedHandler>(this, &AppContainer::onActivated).Get(),
- &m_activationToken);
- return S_OK;
+ args.reserve(argc);
+ for (int i = 0; i < argc; ++i)
+ args.append(argv[i]);
+
+ mainThread = CreateThread(NULL, 0, [](void *param) -> DWORD {
+ AppContainer *app = reinterpret_cast<AppContainer *>(param);
+ int argc = app->args.count();
+ char **argv = app->args.data();
+ return main(argc, argv);
+ }, this, CREATE_SUSPENDED, nullptr);
+
+ HRESULT hr;
+ ComPtr<Xaml::IApplicationStatics> appStatics;
+ hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_Xaml_Application).Get(),
+ IID_PPV_ARGS(&appStatics));
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = appStatics->Start(Callback<Xaml::IApplicationInitializationCallback>([](Xaml::IApplicationInitializationCallbackParams *) {
+ return S_OK;
+ }).Get());
+ Q_ASSERT_SUCCEEDED(hr);
+
+ DWORD exitCode;
+ GetExitCodeThread(mainThread, &exitCode);
+ return exitCode;
+ }
+
+private:
+ HRESULT __stdcall OnActivated(IActivatedEventArgs *args) Q_DECL_OVERRIDE
+ {
+ return base->OnActivated(args);
}
- HRESULT __stdcall SetWindow(ABI::Windows::UI::Core::ICoreWindow *) { return S_OK; }
- HRESULT __stdcall Load(HSTRING) { return S_OK; }
- HRESULT __stdcall Run()
+
+ HRESULT __stdcall OnLaunched(ILaunchActivatedEventArgs *launchArgs) Q_DECL_OVERRIDE
{
+#if _MSC_VER >= 1900
+ commandLine = QString::fromWCharArray(GetCommandLine()).toUtf8();
+#endif
+ HString launchCommandLine;
+ launchArgs->get_Arguments(launchCommandLine.GetAddressOf());
+ if (launchCommandLine.IsValid()) {
+ quint32 launchCommandLineLength;
+ const wchar_t *launchCommandLineBuffer = launchCommandLine.GetRawBuffer(&launchCommandLineLength);
+ if (!commandLine.isEmpty() && launchCommandLineLength)
+ commandLine += ' ';
+ if (launchCommandLineLength)
+ commandLine += QString::fromWCharArray(launchCommandLineBuffer, launchCommandLineLength).toUtf8();
+ }
+ if (!commandLine.isEmpty())
+ args.append(commandLine.data());
+
+ bool quote = false;
+ bool escape = false;
+ for (int i = 0; i < commandLine.size(); ++i) {
+ switch (commandLine.at(i)) {
+ case '\\':
+ escape = true;
+ break;
+ case '"':
+ if (escape) {
+ escape = false;
+ break;
+ }
+ quote = !quote;
+ commandLine[i] = '\0';
+ break;
+ case ' ':
+ if (quote)
+ break;
+ commandLine[i] = '\0';
+ if (args.last()[0] != '\0')
+ args.append(commandLine.data() + i + 1);
+ // fall through
+ default:
+ if (args.last()[0] == '\0')
+ args.last() = commandLine.data() + i;
+ escape = false; // only quotes are escaped
+ break;
+ }
+ }
+
bool develMode = false;
bool debugWait = false;
- foreach (const QByteArray &arg, m_argv) {
- if (arg == "-qdevel")
+ foreach (const char *arg, args) {
+ if (strcmp(arg, "-qdevel") == 0)
develMode = true;
- if (arg == "-qdebug")
+ if (strcmp(arg, "-qdebug") == 0)
debugWait = true;
}
if (develMode) {
@@ -173,98 +238,70 @@ public:
while (!IsDebuggerPresent())
WaitForSingleObjectEx(GetCurrentThread(), 1, true);
}
- g_mainExitCode = main(m_argv.count(), m_argv.data());
+
+ ResumeThread(mainThread);
return S_OK;
}
- HRESULT __stdcall Uninitialize() { return S_OK; }
-private:
- // Activation handler
- HRESULT onActivated(Core::ICoreApplicationView *, Activation::IActivatedEventArgs *args)
+ HRESULT __stdcall OnFileActivated(IFileActivatedEventArgs *args) Q_DECL_OVERRIDE
{
- Activation::ILaunchActivatedEventArgs *launchArgs;
- if (SUCCEEDED(args->QueryInterface(&launchArgs))) {
- for (int i = m_argc; i < m_argv.size(); ++i)
- delete[] m_argv[i];
- m_argv.resize(m_argc);
- HString arguments;
- launchArgs->get_Arguments(arguments.GetAddressOf());
- if (arguments.IsValid()) {
- foreach (const QByteArray &arg, QString::fromWCharArray(
- arguments.GetRawBuffer(nullptr)).toLocal8Bit().split(' ')) {
- m_argv.append(qstrdup(arg.constData()));
- }
- }
- }
+ Q_UNUSED(args);
return S_OK;
}
- int m_argc;
- QVector<char *> m_argv;
- bool m_deleteArgv0;
- EventRegistrationToken m_activationToken;
-};
+ HRESULT __stdcall OnSearchActivated(ISearchActivatedEventArgs *args) Q_DECL_OVERRIDE
+ {
+ Q_UNUSED(args);
+ return S_OK;
+ }
-class AppViewSource : public Microsoft::WRL::RuntimeClass<Core::IFrameworkViewSource>
-{
-public:
- AppViewSource(int argc, char **argv) : m_argc(argc), m_argv(argv) { }
- HRESULT __stdcall CreateView(Core::IFrameworkView **frameworkView)
+ HRESULT __stdcall OnShareTargetActivated(IShareTargetActivatedEventArgs *args) Q_DECL_OVERRIDE
{
- return (*frameworkView = Make<AppContainer>(m_argc, m_argv).Detach()) ? S_OK : E_OUTOFMEMORY;
+ Q_UNUSED(args);
+ return S_OK;
}
-private:
- int m_argc;
- char **m_argv;
+
+ HRESULT __stdcall OnFileOpenPickerActivated(IFileOpenPickerActivatedEventArgs *args) Q_DECL_OVERRIDE
+ {
+ Q_UNUSED(args);
+ return S_OK;
+ }
+
+ HRESULT __stdcall OnFileSavePickerActivated(IFileSavePickerActivatedEventArgs *args) Q_DECL_OVERRIDE
+ {
+ Q_UNUSED(args);
+ return S_OK;
+ }
+
+ HRESULT __stdcall OnCachedFileUpdaterActivated(ICachedFileUpdaterActivatedEventArgs *args) Q_DECL_OVERRIDE
+ {
+ Q_UNUSED(args);
+ return S_OK;
+ }
+
+ HRESULT __stdcall OnWindowCreated(Xaml::IWindowCreatedEventArgs *args) Q_DECL_OVERRIDE
+ {
+ Q_UNUSED(args);
+ return S_OK;
+ }
+
+ ComPtr<Xaml::IApplicationOverrides> base;
+ ComPtr<Xaml::IApplication> core;
+ QByteArray commandLine;
+ QVarLengthArray<char *> args;
+ HANDLE mainThread;
};
// Main entry point for Appx containers
int __stdcall WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
-#if _MSC_VER < 1900
int argc = 0;
- char **argv, **env;
+ char **argv = 0, **env = 0;
+#if _MSC_VER < 1900
_startupinfo info = { _query_new_mode() };
if (int init = __getmainargs(&argc, &argv, &env, false, &info))
return init;
-#else
- QByteArray commandLine = QString::fromWCharArray(GetCommandLine()).toUtf8();
- QVarLengthArray<char *> args;
- args.append(commandLine.data());
- bool quote = false;
- bool escape = false;
- for (int i = 0; i < commandLine.size(); ++i) {
- switch (commandLine.at(i)) {
- case '\\':
- escape = true;
- break;
- case '"':
- if (escape) {
- escape = false;
- break;
- }
- quote = !quote;
- commandLine[i] = '\0';
- break;
- case ' ':
- if (quote)
- break;
- commandLine[i] = '\0';
- if (args.last()[0] != '\0')
- args.append(commandLine.data() + i + 1);
- // fall through
- default:
- if (args.last()[0] == '\0')
- args.last() = commandLine.data() + i;
- escape = false; // only quotes are escaped
- break;
- }
- }
- int argc = args.size();
- char **argv = args.data();
- char **env = Q_NULLPTR;
#endif // _MSC_VER >= 1900
-
for (int i = 0; env && env[i]; ++i) {
QByteArray var(env[i]);
int split = var.indexOf('=');
@@ -275,10 +312,6 @@ int __stdcall WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
if (FAILED(RoInitialize(RO_INIT_MULTITHREADED)))
return 1;
- Core::ICoreApplication *appFactory;
- if (FAILED(RoGetActivationFactory(qHString(CoreApplicationClass), IID_PPV_ARGS(&appFactory))))
- return 2;
-
- appFactory->Run(Make<AppViewSource>(argc, argv).Get());
- return g_mainExitCode;
+ ComPtr<AppContainer> app = Make<AppContainer>();
+ return app->exec(argc, argv);
}