This was an experimental feature which is no longer required or maintained.
Change-Id: I6b4541f402eeb30e8619876ce7293bff79f1b8c4
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com>
+++ /dev/null
-/****************************************************************************
-**
-** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the tools applications of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "d3dservice.h"
-
-#include <QtCore/QDateTime>
-#include <QtCore/QDir>
-#include <QtCore/QDirIterator>
-#include <QtCore/QStandardPaths>
-#include <QtCore/QStringList>
-
-#include <windows.applicationmodel.core.h>
-#include <windows.management.deployment.h>
-#include <windows.storage.h>
-#include <comdef.h>
-#include <wrl.h>
-using namespace Microsoft::WRL;
-using namespace Microsoft::WRL::Wrappers;
-using namespace ABI::Windows::Management::Deployment;
-using namespace ABI::Windows::ApplicationModel;
-using namespace ABI::Windows::Storage;
-using namespace ABI::Windows::Foundation::Collections;
-
-struct ComInitializer
-{
- ComInitializer()
- {
- m_hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
- if (FAILED(m_hr))
- qCWarning(lcD3DService) << "Unable to initialize COM.";
- }
- ~ComInitializer()
- {
- if (isValid())
- CoUninitialize();
- }
- bool isValid() const
- {
- return SUCCEEDED(m_hr);
- }
-private:
- HRESULT m_hr;
-};
-
-extern int appxAppNames(int deviceIndex, QSet<QString> &apps)
-{
- if (deviceIndex) {
- qCWarning(lcD3DService) << "Unsupported device index:" << deviceIndex;
- return 1;
- }
-
- ComInitializer com;
- if (!com.isValid())
- return 1;
-
- ComPtr<IPackageManager> packageManager;
- HRESULT hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Management_Deployment_PackageManager).Get(),
- &packageManager);
- if (FAILED(hr)) {
- qCWarning(lcD3DService) << "Unable to instantiate package manager:"
- << qt_error_string(hr);
- return 1;
- }
-
- ComPtr<IIterable<Package *>> packageCollection;
- hr = packageManager->FindPackagesByUserSecurityId(NULL, &packageCollection);
- if (FAILED(hr)) {
- qCWarning(lcD3DService) << "Failed to find Appx packages:"
- << qt_error_string(hr);
- return 1;
- }
- ComPtr<IIterator<Package *>> iterator;
- hr = packageCollection->First(&iterator);
- if (FAILED(hr)) {
- qCWarning(lcD3DService) << "Failed to get package iterator:"
- << qt_error_string(hr);
- return 1;
- }
- boolean hasCurrent;
- hr = iterator->get_HasCurrent(&hasCurrent);
- while (SUCCEEDED(hr) && hasCurrent) {
- ComPtr<IPackage> package;
- hr = iterator->get_Current(&package);
- if (FAILED(hr)) {
- qCWarning(lcD3DService) << qt_error_string(hr);
- return 1;
- }
-
-#if _MSC_VER >= 1800
- ComPtr<IPackage2> package2;
- hr = package.As(&package2);
- if (FAILED(hr)) {
- qCWarning(lcD3DService) << qt_error_string(hr);
- return 1;
- }
-
- boolean isDevelopmentMode;
- hr = package2->get_IsDevelopmentMode(&isDevelopmentMode);
- if (FAILED(hr)) {
- qCWarning(lcD3DService) << qt_error_string(hr);
- return 1;
- }
- if (!isDevelopmentMode) {
- hr = iterator->MoveNext(&hasCurrent);
- continue;
- }
-#endif // _MSC_VER >= 1800
-
- ComPtr<IPackageId> id;
- hr = package->get_Id(&id);
- if (FAILED(hr)) {
- qCWarning(lcD3DService) << qt_error_string(hr);
- return 1;
- }
-
- HString fullName;
- hr = id->get_FullName(fullName.GetAddressOf());
- if (FAILED(hr)) {
- qCWarning(lcD3DService) << qt_error_string(hr);
- return 1;
- }
- apps.insert(QString::fromWCharArray(fullName.GetRawBuffer(NULL)));
- hr = iterator->MoveNext(&hasCurrent);
- }
- return 0;
-}
-
-/* This function handles a worker thread servicing an Appx application */
-extern int handleAppxDevice(int deviceIndex, const QString &app, const QString &localBase, HANDLE runLock)
-{
- if (deviceIndex) {
- qCWarning(lcD3DService) << "Unsupported device index:" << deviceIndex;
- return 1;
- }
-
- ComInitializer com;
- if (!com.isValid())
- return 1;
-
- ComPtr<IPackageManager> packageManager;
- HRESULT hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Management_Deployment_PackageManager).Get(),
- &packageManager);
- if (FAILED(hr)) {
- qCWarning(lcD3DService) << "Unable to instantiate package manager:" << qt_error_string(hr);
- return 1;
- }
-
- HStringReference packageFullName(reinterpret_cast<LPCWSTR>(app.utf16()));
- ComPtr<IPackage> package;
- hr = packageManager->FindPackageByUserSecurityIdPackageFullName(NULL, packageFullName.Get(), &package);
- if (FAILED(hr)) {
- qCWarning(lcD3DService) << "Unable to query package:" << qt_error_string(hr);
- return 1;
- }
- if (!package) {
- qCWarning(lcD3DService) << "Package is not installed.";
- return 1;
- }
- ComPtr<IPackageId> packageId;
- hr = package->get_Id(&packageId);
- if (FAILED(hr)) {
- qCWarning(lcD3DService) << "Unable to get package ID:" << qt_error_string(hr);
- return 1;
- }
- HString packageFamilyName;
- hr = packageId->get_FamilyName(packageFamilyName.GetAddressOf());
- if (FAILED(hr)) {
- qCWarning(lcD3DService) << "Unable to get package name:" << qt_error_string(hr);
- return 1;
- }
-
- const QString localSourcePath = localBase + QStringLiteral("\\source\\");
- const QString localBinaryPath = localBase + QStringLiteral("\\binary\\");
-
- const QString remoteBase =
- QDir::toNativeSeparators(QStandardPaths::writableLocation(QStandardPaths::DataLocation))
- + QStringLiteral("\\Packages\\")
- + QString::fromWCharArray(packageFamilyName.GetRawBuffer(NULL))
- + QStringLiteral("\\LocalState\\d3dcompiler");
- const QString remoteSourcePath = remoteBase + QStringLiteral("\\source\\");
- const QString remoteBinaryPath = remoteBase + QStringLiteral("\\binary\\");
-
- bool checkDirectories = true;
- forever {
- // If the run lock is signaled, it's time to quit
- if (WaitForSingleObject(runLock, 0) == WAIT_OBJECT_0)
- return 0;
-
- // Run certain setup steps once per connection
- if (checkDirectories) {
- // Check remote directory
- QDir dir(remoteBase);
- if (!dir.exists()) {
- dir.cdUp();
- if (!dir.mkpath(QStringLiteral("d3dcompiler"))) {
- qCWarning(lcD3DService) << "Could not create d3dcompiler directory.";
- Sleep(1000);
- continue;
- }
- dir.cd(QStringLiteral("d3dcompiler"));
- }
-
- if (!QFile::exists(remoteSourcePath)) {
- if (!dir.mkpath(QStringLiteral("source"))) {
- qCWarning(lcD3DService) << "Could not create source directory.";
- Sleep(1000);
- continue;
- }
- }
-
- if (!QFile::exists(remoteBinaryPath)) {
- if (!dir.mkpath(QStringLiteral("binary"))) {
- qCWarning(lcD3DService) << "Could not create binary directory.";
- Sleep(1000);
- continue;
- }
- }
-
- checkDirectories = false;
- }
-
- // Ok, ready to check for shaders
- QDirIterator it(remoteSourcePath);
- while (it.hasNext()) {
- const QString remoteSource = it.next();
- if (!it.fileInfo().isFile())
- continue;
- const QString shaderFileName = it.fileName();
- const QString localSource = localSourcePath + shaderFileName;
- const QString localBinary = localBinaryPath + shaderFileName;
-
- // Copy remote source to local
- if (QFile::exists(localSource))
- QFile::remove(localSource);
- QFile remoteSourceFile(remoteSource);
- if (!remoteSourceFile.copy(localSource)) {
- qCWarning(lcD3DService) << "Unable to copy shader source:" << remoteSource;
- qCWarning(lcD3DService) << remoteSourceFile.errorString();
- continue;
- }
-
- // Remove the remote file
- if (!remoteSourceFile.remove()) {
- qCWarning(lcD3DService) << "Unable to remove shader source:" << remoteSource;
- qCWarning(lcD3DService) << remoteSourceFile.errorString();
- continue;
- }
-
- // Compile shader
- hr = D3DService::compileShader(localSource, localBinary);
- if (FAILED(hr)) {
- qCWarning(lcD3DService) << "Unable to compile shader:" << localSource;
- qCWarning(lcD3DService) << qt_error_string(hr);
- continue;
- }
-
- // All went well, copy the blob to the device
- const QString remoteBinary = remoteBinaryPath + shaderFileName;
- if (QFile::exists(remoteBinary))
- QFile::remove(remoteBinary);
- QFile localBinaryFile(localBinary);
- if (!localBinaryFile.copy(remoteBinary)) {
- qCWarning(lcD3DService) << "Unable to copy to remote: " << localBinary;
- qCWarning(lcD3DService) << localBinaryFile.errorString();
- continue;
- }
-
- qCDebug(lcD3DService) << "Compiled local shader to:" << localBinary
- << "and uploaded to:" << remoteBinary;
- }
-
- HANDLE notification = FindFirstChangeNotification(
- reinterpret_cast<LPCWSTR>(remoteSourcePath.utf16()),
- FALSE, FILE_NOTIFY_CHANGE_FILE_NAME);
- if (!notification) {
- qCCritical(lcD3DService) << "Failed to set up shader directory notification:"
- << qt_error_string(GetLastError());
- return 1;
- }
-
- // Sleep for up to 30 seconds; wake if a new shader appears
- HANDLE waitHandles[] = { notification, runLock };
- DWORD event = WaitForMultipleObjects(2, waitHandles, FALSE, 30000);
- FindCloseChangeNotification(notification);
- // Timeout or directory change; loop and update
- if (event == WAIT_TIMEOUT || event == WAIT_OBJECT_0)
- continue;
- // runLock set; exit
- if (event == WAIT_OBJECT_0 + 1)
- return 0;
-
- hr = GetLastError();
- // If the app was uninstalled, this is expected
- if (hr == ERROR_INVALID_HANDLE) {
- qCDebug(lcD3DService) << "The wait handle was invalidated; worker exiting.";
- return 1;
- }
-
- qCWarning(lcD3DService) << "Appx handler wait failed:"
- << qt_error_string(hr);
- return 1;
- }
-}
+++ /dev/null
-/****************************************************************************
-**
-** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the tools applications of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "d3dservice.h"
-
-#include <QtCore/QDir>
-#include <QtCore/QFile>
-
-#include <d3dcommon.h>
-#include <wrl.h>
-using namespace Microsoft::WRL;
-
-typedef HRESULT (WINAPI *D3DCompileFunc)(
- const void *, SIZE_T, const char *, const D3D_SHADER_MACRO *, ID3DInclude *,
- const char *, const char *, UINT, UINT, ID3DBlob **, ID3DBlob **);
-
-HRESULT D3DService::compileShader(const QString &source, const QString &destination)
-{
- static D3DCompileFunc D3DCompile = 0;
- if (!D3DCompile) {
- HMODULE d3dcompiler = LoadLibrary(L"d3dcompiler_47");
- if (!d3dcompiler)
- return GetLastError();
-
- D3DCompile = reinterpret_cast<D3DCompileFunc>(GetProcAddress(d3dcompiler, "D3DCompile"));
- if (!D3DCompile)
- return GetLastError();
- }
-
- QFile sourceFile(source);
- qCDebug(lcD3DService) << "Shader source observed at:" << source;
- if (!sourceFile.open(QFile::ReadOnly)) {
- qCWarning(lcD3DService) << "Unable to open shader source:" << sourceFile.errorString();
- return E_FAIL;
- }
-
- const QByteArray data = sourceFile.readAll();
-
- QStringList parts = source.split(QLatin1Char('!'));
- if (parts.size() < 4) {
- qCWarning(lcD3DService) << "The shader source file is missing meta data.";
- return E_FAIL;
- }
-
- ComPtr<ID3DBlob> blob, errorMessage;
- HRESULT hr = D3DCompile(data, data.size(), parts.at(0).toUtf8(), 0, 0, parts.at(1).toUtf8(),
- parts.at(2).toUtf8(), parts.at(3).toUInt(), 0, &blob, &errorMessage);
- if (FAILED(hr)) {
- if (errorMessage) {
- const QString error = QString::fromUtf8(
- static_cast<const char *>(errorMessage->GetBufferPointer()),
- errorMessage->GetBufferSize());
- qCWarning(lcD3DService) << error;
- }
- return hr;
- }
-
- QFile destinationFile(destination);
- if (!destinationFile.open(QFile::WriteOnly)) {
- qCWarning(lcD3DService) << "Unable to open destination file:" << destinationFile.errorString();
- return E_FAIL;
- }
-
- destinationFile.write((const char *)blob->GetBufferPointer(), blob->GetBufferSize());
- return hr;
-}
+++ /dev/null
-/****************************************************************************
-**
-** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the tools applications of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "d3dservice.h"
-
-#include <QtCore/QCommandLineParser>
-#include <QtCore/QDateTime>
-#include <QtCore/QDir>
-#include <QtCore/QStandardPaths>
-#include <QtCore/QStringList>
-#include <QtCore/QVector>
-#include <QtCore/QBitArray>
-
-#include <iostream>
-#include <dbt.h>
-#include <setupapi.h>
-
-QT_USE_NAMESPACE
-
-Q_LOGGING_CATEGORY(lcD3DService, "qt.d3dservice")
-
-#define _WIDEN(x) L ## x
-#define WIDEN(x) _WIDEN(x)
-#define LQT_VERSION_STR WIDEN(QT_VERSION_STR)
-
-// The GUID used by the Windows Phone IP over USB service
-static const GUID GUID_DEVICE_WINPHONE8_USB = { 0x26fedc4eL, 0x6ac3, 0x4241, 0x9e, 0x4d, 0xe3, 0xd4, 0xb2, 0xc5, 0xc5, 0x34 };
-
-// Handlers
-typedef int (*HandleDeviceFunction)(int, const QString &, const QString &, HANDLE);
-extern int handleAppxDevice(int deviceIndex, const QString &app, const QString &cacheDir, HANDLE runLock);
-extern int handleXapDevice(int deviceIndex, const QString &app, const QString &cacheDir, HANDLE runLock);
-typedef int (*AppListFunction)(int, QSet<QString> &);
-extern int xapAppNames(int deviceIndex, QSet<QString> &apps);
-extern int appxAppNames(int deviceIndex, QSet<QString> &app);
-
-extern QStringList xapDeviceNames();
-
-// Callbacks
-static BOOL __stdcall control(DWORD type);
-static LRESULT __stdcall control(HWND window, UINT msg, WPARAM wParam, LPARAM lParam);
-static DWORD __stdcall deviceWorker(LPVOID param);
-static DWORD __stdcall appWorker(LPVOID param);
-
-union ErrorId
-{
- enum FacilityFlag {
- Success = 0x0,
- Informational = 0x40000000,
- Warning = 0x80000000,
- Error = Informational|Warning,
- Customer = 0x20000000
- };
- struct {
- ushort facility;
- ushort code;
- };
- ulong val;
-};
-
-enum ControlEvent
-{
- NoCommand = 0, Stop = 1, NewWorker = 2, PhoneConnected = 3
-};
-
-struct D3DServicePrivate
-{
- D3DServicePrivate()
- : controlEvent(CreateEvent(NULL, FALSE, FALSE, NULL))
- , controlWindow(0)
- , deviceHandle(0)
- {
- }
- ~D3DServicePrivate()
- {
- if (deviceHandle)
- UnregisterDeviceNotification(deviceHandle);
- if (controlWindow)
- CloseHandle(controlWindow);
- if (controlEvent)
- CloseHandle(controlEvent);
- }
-
- HANDLE controlEvent;
- HWND controlWindow;
- HDEVNOTIFY deviceHandle;
- QList<ControlEvent> eventQueue;
- QList<QStringPair> workerQueue;
-};
-Q_GLOBAL_STATIC(D3DServicePrivate, d)
-
-struct WorkerParam
-{
- enum { NoError = 0, GeneralError = 1, BadDeviceIndex = 2, NoCacheDir = 3 };
- WorkerParam(const QString &deviceName, const QString &app, HANDLE runLock)
- : deviceName(deviceName), app(app), runLock(runLock) { }
- QString deviceName;
- QString app;
- HANDLE runLock;
-};
-
-class Worker
-{
-public:
- Worker(const QStringPair &config, LPTHREAD_START_ROUTINE worker)
- : m_runLock(CreateEvent(NULL, FALSE, FALSE, NULL))
- , m_param(config.first, config.second, m_runLock)
- , m_thread(CreateThread(NULL, 0, worker, &m_param, 0, NULL))
- {
- }
- ~Worker()
- {
- SetEvent(m_runLock);
- WaitForSingleObject(m_thread, INFINITE);
- CloseHandle(m_runLock);
- CloseHandle(m_thread);
- }
- HANDLE thread() const
- {
- return m_thread;
- }
-private:
- HANDLE m_runLock;
- WorkerParam m_param;
- HANDLE m_thread;
-};
-
-static QString prepareCache(const QString &device, const QString &app)
-{
- // Make sure we have a writable cache
- QDir baseDir(QStandardPaths::writableLocation(QStandardPaths::DataLocation));
- if (!baseDir.mkpath(QStringLiteral("qtd3dservice")))
- return QString();
- baseDir.cd(QStringLiteral("qtd3dservice"));
- if (!baseDir.mkpath(device))
- return QString();
- baseDir.cd(device);
- if (!baseDir.mkpath(app))
- return QString();
- baseDir.cd(app);
- if (!baseDir.mkpath(QStringLiteral("source")))
- return QString();
- if (!baseDir.mkpath(QStringLiteral("binary")))
- return QString();
- return QDir::toNativeSeparators(baseDir.absolutePath());
-}
-
-bool D3DService::start()
-{
- HANDLE runLock = CreateMutex(NULL, TRUE, L"Local\\qtd3dservice");
- if (!runLock || GetLastError() == ERROR_ALREADY_EXISTS) {
- qCWarning(lcD3DService) << "The service is already running.";
- return false;
- }
-
- SetConsoleCtrlHandler(&control, TRUE);
-
- // Create an invisible window for getting broadcast events
- WNDCLASS controlWindowClass = { 0, &control, 0, 0, NULL, NULL,
- NULL, NULL, NULL, L"controlWindow" };
- if (!RegisterClass(&controlWindowClass)) {
- qCCritical(lcD3DService) << "Unable to register control window class:"
- << qt_error_string(GetLastError());
- return false;
- }
- d->controlWindow = CreateWindowEx(0, L"controlWindow", NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL);
-
- // Register for USB notifications
- DEV_BROADCAST_DEVICEINTERFACE filter = {
- sizeof(DEV_BROADCAST_DEVICEINTERFACE), DBT_DEVTYP_DEVICEINTERFACE,
- 0, GUID_DEVICE_WINPHONE8_USB, 0
- };
- d->deviceHandle = RegisterDeviceNotification(d->controlWindow, &filter, DEVICE_NOTIFY_WINDOW_HANDLE);
-
- QVector<HANDLE> waitHandles;
- waitHandles.append(d->controlEvent);
-
- // Dummy handle for phone (gets replaced by a worker when needed)
- HANDLE dummyHandle;
- DuplicateHandle(GetCurrentProcess(), GetCurrentProcess(),
- GetCurrentProcess(), &dummyHandle, SYNCHRONIZE, FALSE, 0);
- waitHandles.append(dummyHandle);
-
- // Event handles for emulators (XDE)
- WCHAR username[MAX_PATH];
- ULONG usernameSize = MAX_PATH;
- GetUserName(username, &usernameSize);
- const QStringList emulatorNames = xapDeviceNames().mid(1);
- foreach (const QString &name, emulatorNames) {
- const QString eventName = QStringLiteral("Local\\XdeOnServerInitialize")
- + name + QLatin1Char('.') + QString::fromWCharArray(username, usernameSize).toLower();
- HANDLE event = CreateEvent(NULL, TRUE, FALSE, reinterpret_cast<LPCWSTR>(eventName.utf16()));
- if (event)
- waitHandles.append(event);
- else
- qCWarning(lcD3DService) << "Unable to create event:" << qt_error_string(GetLastError());
- }
-
- // App monitoring threads
- QHash<QStringPair, Worker *> workers;
- QHash<HANDLE, QStringPair> workerThreads;
-
- // Device monitoring threads - one per device
- QVector<Worker *> deviceWorkers(emulatorNames.size() + 1, NULL);
-
- // If a Windows Phone is already connected, queue a device worker
- HDEVINFO info = SetupDiGetClassDevs(&GUID_DEVICE_WINPHONE8_USB, NULL, NULL,
- DIGCF_DEVICEINTERFACE|DIGCF_PRESENT);
- if (info != INVALID_HANDLE_VALUE) {
- SP_DEVINFO_DATA infoData = { sizeof(SP_DEVINFO_DATA) };
- if (SetupDiEnumDeviceInfo(info, 0, &infoData)) {
- d->eventQueue.append(PhoneConnected);
- SetEvent(d->controlEvent);
- }
- SetupDiDestroyDeviceInfoList(info);
- }
-
- // Create a monitoring thread for local Appx packages
- Worker appxWorker(qMakePair(QStringLiteral("local"), QString()), &deviceWorker);
- Q_UNUSED(appxWorker);
-
- // Master loop
- // This loop handles incoming events from the service controller and
- // worker threads. It also creates new worker threads as needed.
- const uint phoneEvent = WAIT_OBJECT_0 + 1;
- const uint minEmulatorEvent = phoneEvent + 1;
- const uint maxEmulatorEvent = minEmulatorEvent + emulatorNames.size() - 1;
- const uint minWorker = maxEmulatorEvent + 1;
- uint maxWorker = minWorker + workers.size() - 1;
- forever {
- DWORD event = MsgWaitForMultipleObjects(waitHandles.size(), waitHandles.data(), FALSE, INFINITE, QS_ALLINPUT);
- if (event >= WAIT_OBJECT_0 && event < WAIT_OBJECT_0 + waitHandles.size()) {
- // A control event occurred
- if (event == WAIT_OBJECT_0) {
- bool shutdown = false;
- while (!d->eventQueue.isEmpty()) {
- ControlEvent controlEvent = d->eventQueue.takeFirst();
-
- // Break out and shutdown
- if (controlEvent == Stop) {
- shutdown = true;
- break;
- }
-
- // A new worker is in the queue
- if (controlEvent == NewWorker) {
- while (!d->workerQueue.isEmpty()) {
- const QStringPair config = d->workerQueue.takeFirst();
- if (workers.contains(config)) { // The config is already running
- qCDebug(lcD3DService) << "Discarded worker configuration:"
- << config.first << config.second;
- continue;
- }
-
- Worker *worker = new Worker(config, &appWorker);
- workers.insert(config, worker);
- workerThreads.insert(worker->thread(), config);
- waitHandles.append(worker->thread());
- maxWorker = minWorker + workers.size() - 1;
- }
- continue;
- }
-
- // A Windows Phone device was connected
- if (controlEvent == PhoneConnected) {
- qCDebug(lcD3DService) << "A Windows Phone has connected.";
- // The worker is already active
- if (deviceWorkers.first())
- continue;
-
- // Start the phone monitoring thread
- Worker *worker = new Worker(qMakePair(QString::number(0), QString()), &deviceWorker);
- deviceWorkers[0] = worker;
- CloseHandle(waitHandles[phoneEvent - WAIT_OBJECT_0]);
- waitHandles[phoneEvent - WAIT_OBJECT_0] = worker->thread();
- continue;
- }
- }
-
- if (shutdown)
- break;
-
- continue;
- }
-
- // Device events
- if (event >= phoneEvent && event <= maxEmulatorEvent) {
- const int deviceIndex = event - phoneEvent;
- // Determine if the handle in the slot is an event or thread
- if (GetThreadId(waitHandles[event - WAIT_OBJECT_0])) {
- qCDebug(lcD3DService) << "Device worker exited:" << deviceIndex;
- // The thread has exited, close the handle and replace the event
- delete deviceWorkers.at(deviceIndex);
- deviceWorkers[deviceIndex] = 0;
-
- // The phone case is handled elsewhere; set a dummy handle
- if (event == phoneEvent) {
- HANDLE dummyHandle;
- DuplicateHandle(GetCurrentProcess(), GetCurrentProcess(),
- GetCurrentProcess(), &dummyHandle, SYNCHRONIZE, FALSE, 0);
- waitHandles[event - WAIT_OBJECT_0] = dummyHandle;
- continue;
- }
-
- // Re-create the event handle
- const QString eventName = QStringLiteral("Local\\XdeOnServerInitialize")
- + emulatorNames.at(deviceIndex - 1) + QLatin1Char('.')
- + QString::fromWCharArray(username, usernameSize).toLower();
- HANDLE emulatorEvent = CreateEvent(
- NULL, TRUE, FALSE, reinterpret_cast<LPCWSTR>(eventName.utf16()));
- if (emulatorEvent) {
- waitHandles[event - WAIT_OBJECT_0] = emulatorEvent;
- } else {
- // If the above fails, replace it with a dummy to keep things going
- qCCritical(lcD3DService).nospace() << "Unable to create event for emulator "
- << emulatorNames.at(deviceIndex - 1)
- << ": " << qt_error_string(GetLastError());
- HANDLE dummyHandle;
- DuplicateHandle(GetCurrentProcess(), GetCurrentProcess(),
- GetCurrentProcess(), &dummyHandle, SYNCHRONIZE, FALSE, 0);
- waitHandles[event - WAIT_OBJECT_0] = dummyHandle;
- }
- } else {
- qCDebug(lcD3DService) << "An emulator was activated:" << deviceIndex;
- // The event was set; close the handle and replace with a thread
- CloseHandle(waitHandles[event - WAIT_OBJECT_0]);
-
- // This shouldn't happen
- if (event == phoneEvent)
- continue;
-
- const QStringPair config = qMakePair(QString::number(deviceIndex), QString());
- Worker *worker = new Worker(config, &deviceWorker);
- deviceWorkers[deviceIndex] = worker;
- waitHandles[event - WAIT_OBJECT_0] = worker->thread();
- }
- continue;
- }
-
- // A worker exited
- if (event >= minWorker && event <= maxWorker) {
- // Delete the worker and clear the handle (TODO: remove it?)
- HANDLE thread = waitHandles.takeAt(event - WAIT_OBJECT_0);
- QStringPair config = workerThreads.take(thread);
- Worker *worker = workers.take(config);
- delete worker;
- continue;
- }
- }
-
- // TODO: check return val for this
- MSG msg;
- if (PeekMessage(&msg, d->controlWindow, 0, 0, PM_REMOVE))
- DispatchMessage(&msg);
- }
-
- qDeleteAll(workers);
-
- // Close the phone and emulator handles
- for (int i = 0; i <= emulatorNames.size(); ++i) {
- if (GetThreadId(waitHandles[i + 1]))
- delete deviceWorkers.at(i);
- else
- CloseHandle(waitHandles[i + 1]);
- }
-
- CloseHandle(runLock);
-
- return true;
-}
-
-DWORD __stdcall deviceWorker(LPVOID param)
-{
- WorkerParam *args = reinterpret_cast<WorkerParam *>(param);
-
- // The list of applications on this device will be polled until
- // an error code is returned (e.g. the device is disconnected) or
- // the thread is told to exit.
- QSet<QString> appNames;
- AppListFunction appList;
-
- int deviceIndex = 0;
- HKEY waitKey = 0;
- if (args->deviceName.isEmpty() || args->deviceName == QStringLiteral("local")) {
- appList = appxAppNames;
- LONG result = RegOpenKeyEx(
- HKEY_LOCAL_MACHINE,
- L"SOFTWARE\\Classes\\Local Settings\\Software\\Microsoft\\Windows\\CurrentVersion\\AppModel\\PackageRepository\\Packages",
- 0, KEY_NOTIFY, &waitKey);
- if (result != ERROR_SUCCESS) {
- qCWarning(lcD3DService) << "Unable to open registry key for Appx discovery:"
- << qt_error_string(result);
- waitKey = 0;
- }
- } else {
- // CoreCon (Windows Phone)
- bool ok;
- deviceIndex = args->deviceName.toInt(&ok);
- if (!ok)
- return WorkerParam::BadDeviceIndex;
-
- appList = xapAppNames;
- }
-
- forever {
- if (WaitForSingleObject(args->runLock, 0) == WAIT_OBJECT_0)
- return 0;
-
- QSet<QString> latestAppNames;
- int exitCode = appList(deviceIndex, latestAppNames);
- if (exitCode != WorkerParam::NoError)
- return exitCode;
-
- QSet<QString> newAppNames = latestAppNames - appNames;
- if (!newAppNames.isEmpty()) {
- // Create a new app watcher for each new app
- foreach (const QString &app, newAppNames) {
- qCWarning(lcD3DService).nospace() << "Found app " << app << " on device "
- << args->deviceName << '.';
- d->workerQueue.append(qMakePair(args->deviceName, app));
- }
-
- d->eventQueue.append(NewWorker);
- SetEvent(d->controlEvent);
- }
-
- appNames = latestAppNames;
-
- // If possible, wait for the registry event (otherwise, go straight to sleep)
- if (waitKey) {
- HANDLE waitEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
- LONG result = RegNotifyChangeKeyValue(waitKey, TRUE, REG_NOTIFY_CHANGE_NAME, waitEvent, TRUE);
- if (result != ERROR_SUCCESS) {
- qCWarning(lcD3DService) << "Unable to create registry notifier:"
- << qt_error_string(result);
- RegCloseKey(waitKey); // Revert to polling
- waitKey = 0;
- }
-
- HANDLE waitHandles[] = { args->runLock, waitEvent };
- result = WaitForMultipleObjects(2, waitHandles, FALSE, INFINITE);
- CloseHandle(waitEvent);
- if (result == WAIT_OBJECT_0) // runLock, exit
- return 0;
- if (result == WAIT_OBJECT_0 + 1) { // registry changed, reset app list
- appNames.clear();
- } else {
- qCWarning(lcD3DService) << "Unexpected wait result:" << result
- << qt_error_string(GetLastError());
- RegCloseKey(waitKey); // Revert to polling
- waitKey = 0;
- }
- }
- Sleep(1000);
- }
-
- if (waitKey)
- RegCloseKey(waitKey);
- return 0;
-}
-
-DWORD __stdcall appWorker(LPVOID param)
-{
- WorkerParam *args = reinterpret_cast<WorkerParam *>(param);
-
- HandleDeviceFunction handleDevice;
- QString cachePath;
- int deviceIndex = 0;
- // Simple case, local device
- if (args->deviceName.isEmpty() || args->deviceName == QStringLiteral("local")) {
- cachePath = prepareCache(QStringLiteral("local"), args->app);
- if (cachePath.isEmpty()) {
- qCCritical(lcD3DService) << "Unable to create local shader cache.";
- return WorkerParam::NoCacheDir;
- }
- handleDevice = &handleAppxDevice;
- } else {
- // CoreCon (Windows Phone) case
- bool ok;
- deviceIndex = args->deviceName.toInt(&ok);
- if (!ok)
- return WorkerParam::BadDeviceIndex;
- cachePath = prepareCache(args->deviceName, args->app);
- if (cachePath.isEmpty()) {
- qCCritical(lcD3DService) << "Unable to create local shader cache.";
- return WorkerParam::NoCacheDir;
- }
- handleDevice = &handleXapDevice;
- }
-
- return handleDevice(deviceIndex, args->app, cachePath, args->runLock);
-}
-
-// Console message controller
-LRESULT __stdcall control(HWND window, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- if (msg == WM_DEVICECHANGE && wParam == DBT_DEVICEARRIVAL) {
- DEV_BROADCAST_DEVICEINTERFACE *header =
- reinterpret_cast<DEV_BROADCAST_DEVICEINTERFACE *>(lParam);
- if (header->dbcc_classguid == GUID_DEVICE_WINPHONE8_USB) {
- d->eventQueue.append(PhoneConnected);
- SetEvent(d->controlEvent);
- }
- }
- return DefWindowProc(window, msg, wParam, lParam);
-}
-
-// Console CTRL controller
-BOOL __stdcall control(DWORD type)
-{
- switch (type) {
- case CTRL_C_EVENT:
- case CTRL_CLOSE_EVENT:
- case CTRL_LOGOFF_EVENT:
- case CTRL_SHUTDOWN_EVENT: {
- d->eventQueue.append(Stop);
- SetEvent(d->controlEvent);
- return true;
- }
- // fall through
- case CTRL_BREAK_EVENT:
- default:
- break;
- }
- return false;
-}
+++ /dev/null
-/****************************************************************************
-**
-** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the tools applications of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef D3DSERVICE_H
-#define D3DSERVICE_H
-
-#include <QtCore/qt_windows.h>
-#include <QtCore/QPair>
-#include <QtCore/QString>
-#include <QtCore/QStringList>
-#include <QtCore/QLoggingCategory>
-
-QT_USE_NAMESPACE
-
-typedef QPair<QString, QString> QStringPair;
-namespace D3DService
-{
- HRESULT compileShader(const QString &source, const QString &destination);
-
- bool start();
-
- QStringList devices();
- QStringList apps(const QString &device);
- QStringList sources(const QString &device, const QString &app);
- QStringList binaries(const QString &device, const QString &app);
-}
-
-Q_DECLARE_LOGGING_CATEGORY(lcD3DService)
-
-#endif // D3DSERVICE_H
+++ /dev/null
-/****************************************************************************
-**
-** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the tools applications of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "d3dservice.h"
-
-#include <QtCore/QDir>
-#include <QtCore/QStandardPaths>
-
-QT_USE_NAMESPACE
-
-QStringList D3DService::devices()
-{
- const QDir dir(QStandardPaths::writableLocation(QStandardPaths::DataLocation)
- + QStringLiteral("/qtd3dservice"));
- return dir.entryList(QDir::Dirs|QDir::NoDotAndDotDot);
-}
-
-QStringList D3DService::apps(const QString &device)
-{
- const QDir dir(QStandardPaths::writableLocation(QStandardPaths::DataLocation)
- + QStringLiteral("/qtd3dservice/")
- + (device.isEmpty() ? QStringLiteral("local") : device));
- return dir.entryList(QDir::Dirs|QDir::NoDotAndDotDot);
-}
-
-QStringList D3DService::sources( const QString &device, const QString &app)
-{
- const QDir dir(QStandardPaths::writableLocation(QStandardPaths::DataLocation)
- + QStringLiteral("/qtd3dservice/")
- + (device.isEmpty() ? QStringLiteral("local") : device)
- + QLatin1Char('/') + app + QStringLiteral("/source"));
- QStringList entries;
- foreach (const QFileInfo &info, dir.entryInfoList(QDir::Files))
- entries.append(info.absoluteFilePath());
- return entries;
-}
-
-QStringList D3DService::binaries(const QString &device, const QString &app)
-{
- const QDir dir(QStandardPaths::writableLocation(QStandardPaths::DataLocation)
- + QStringLiteral("/qtd3dservice/")
- + (device.isEmpty() ? QStringLiteral("local") : device)
- + QLatin1Char('/') + app + QStringLiteral("/binary"));
- QStringList entries;
- foreach (const QFileInfo &info, dir.entryInfoList(QDir::Files))
- entries.append(info.absoluteFilePath());
- return entries;
-}
+++ /dev/null
-/****************************************************************************
-**
-** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the tools applications of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtCore/QCommandLineParser>
-#include <QtCore/QDir>
-#include <QtCore/QFile>
-#include <QtCore/QFileInfo>
-#include <QtCore/QXmlStreamWriter>
-
-#include <iostream>
-
-#include "d3dservice.h"
-
-static QFile outputFile;
-static void outputFileMessageHandler(QtMsgType, const QMessageLogContext &, const QString &text)
-{
- outputFile.write(text.toUtf8());
- outputFile.write("\r\n");
-}
-
-static void outputList(const QStringList &files, bool useLogger)
-{
- foreach (const QString &file, files) {
- if (useLogger)
- qCCritical(lcD3DService, qPrintable(file));
- else
- std::wcout << reinterpret_cast<const wchar_t *>(file.utf16()) << std::endl;
- }
-}
-
-static void outputQrc(const QStringList &files, bool useLogger)
-{
- QString stream;
- QXmlStreamWriter xml(&stream);
- xml.setAutoFormatting(true);
- xml.writeStartElement(QStringLiteral("RCC"));
- xml.writeStartElement(QStringLiteral("qresource"));
- xml.writeAttribute(QStringLiteral("prefix"), QStringLiteral("qt.d3dcompiler"));
- foreach (const QString &file, files) {
- xml.writeStartElement(QStringLiteral("file"));
- xml.writeAttribute(QStringLiteral("alias"), QFileInfo(file).fileName());
- xml.writeCharacters(file);
- xml.writeEndElement();
- }
- xml.writeEndElement();
- xml.writeEndElement();
-
- if (useLogger)
- qCCritical(lcD3DService, qPrintable(stream));
- else
- std::wcout << reinterpret_cast<const wchar_t *>(stream.utf16()) << std::endl;
-}
-
-int main(int argc, char *argv[])
-{
- QCoreApplication app(argc, argv);
- app.setApplicationName(QStringLiteral("Qt D3D Shader Compilation Service"));
- app.setApplicationVersion(QLatin1String(QT_VERSION_STR));
- app.setOrganizationName(QStringLiteral("QtProject"));
- app.setOrganizationDomain(QStringLiteral("qt-project.org"));
-
- QCommandLineParser parser;
- QCommandLineOption outputOption(
- QStringLiteral("output"),
- QStringLiteral("Write output to a file."),
- QStringLiteral("file"));
- parser.addOption(outputOption);
- QCommandLineOption verbosityOption(
- QStringLiteral("verbose"),
- QLatin1String("The verbosity level of the message output "
- "(0 - silent, 1 - info, 2 - debug). Defaults to 1."),
- QStringLiteral("level"), QStringLiteral("1"));
- parser.addOption(verbosityOption);
- QCommandLineOption listSourceOption(
- QStringLiteral("list-source"),
- QLatin1String("List the known shader sources. Use with --app and/or --device "
- "to narrow the scope."));
- parser.addOption(listSourceOption);
- QCommandLineOption listBinaryOption(
- QStringLiteral("list-binary"),
- QLatin1String("List the known shader binaries. Use with --app and/or --device "
- "to narrow the scope."));
- parser.addOption(listBinaryOption);
- QCommandLineOption appOption(
- QStringLiteral("app"),
- QStringLiteral("Specifies the application to act upon."),
- QStringLiteral("name"));
- parser.addOption(appOption);
- QCommandLineOption deviceOption(
- QStringLiteral("device"),
- QStringLiteral("Specifies the device to act upon."),
- QStringLiteral("name"));
- parser.addOption(deviceOption);
- QCommandLineOption qrcOption(
- QStringLiteral("qrc"),
- QLatin1String("Outputs the content of --list-source/--list-binary in "
- "Qt resource file format."));
- parser.addOption(qrcOption);
-
- parser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions);
- parser.addHelpOption();
- parser.process(app.arguments());
-
-
- const bool useLogger = parser.isSet(outputOption);
- const bool useQrc = parser.isSet(qrcOption);
- const bool listSource = parser.isSet(listSourceOption);
- const bool listBinary = parser.isSet(listBinaryOption);
-
- if (useLogger) {
- outputFile.setFileName(parser.value(outputOption));
- if (!outputFile.open(QFile::WriteOnly)) {
- qCWarning(lcD3DService) << "The output file could not be opened:"
- << outputFile.errorString();
- return 1;
- }
- qInstallMessageHandler(&outputFileMessageHandler);
- }
-
- if (useQrc && !(listSource || listBinary)) {
- qCWarning(lcD3DService) << "The --qrc option is only valid with either --list-source or --list--binary.";
- return 1;
- }
-
- if (listSource && listBinary) {
- qCWarning(lcD3DService) << "Please specify only --list-binary or --list source, not both.";
- return 1;
- }
-
- QStringList filterRules = QStringList() // Default logging rules
- << QStringLiteral("qt.d3dservice.warning=true")
- << QStringLiteral("qt.d3dservice.critical=true");
- if (parser.isSet(verbosityOption)) {
- bool ok;
- uint verbosity = parser.value(verbosityOption).toUInt(&ok);
- if (!ok || verbosity > 2) {
- qCCritical(lcD3DService) << "Incorrect value specified for verbosity.";
- parser.showHelp(1);
- }
- switch (verbosity) {
- case 2: // Enable debug print
- filterRules.append(QStringLiteral("qt.d3dservice.debug=true"));
- break;
- case 1: // Remove warnings
- filterRules.removeFirst();
- // fall through
- case 0: // Silent
- filterRules.removeFirst();
- // fall through
- default: // Impossible
- break;
- }
- } else if (listSource || listBinary) {
- // In list mode, silence warnings by default
- filterRules.removeFirst();
- }
- QLoggingCategory::setFilterRules(filterRules.join(QLatin1Char('\n')));
-
- const QString deviceName = parser.value(deviceOption);
- const QString appName = parser.value(appOption);
- QStringList devices;
- if (listSource || listBinary)
- devices = deviceName.isEmpty() ? D3DService::devices() : QStringList(deviceName);
-
- if (listSource) {
- foreach (const QString &device, devices) {
- const QStringList apps = appName.isEmpty()
- ? D3DService::apps(device) : QStringList(appName);
- foreach (const QString &app, apps) {
- const QStringList files = D3DService::sources(device, app);
- if (useQrc)
- outputQrc(files, useLogger);
- else
- outputList(files, useLogger);
- }
- }
-
- return 0;
- }
-
- if (listBinary) {
- foreach (const QString &device, devices) {
- const QStringList apps = appName.isEmpty()
- ? D3DService::apps(device) : QStringList(appName);
- foreach (const QString &app, apps) {
- const QStringList files = D3DService::binaries(device, app);
- if (useQrc)
- outputQrc(files, useLogger);
- else
- outputList(files, useLogger);
- }
- }
-
- return 0;
- }
-
- // Default (start service)
- if (!D3DService::start()) {
- qCWarning(lcD3DService) << "The service failed to start.";
- return 1;
- }
-
- return 0;
-}
+++ /dev/null
-option(host_build)
-CONFIG += force_bootstrap
-
-TARGET = qtd3dservice
-
-DEFINES += QT_NO_CAST_FROM_ASCII QT_NO_CAST_TO_ASCII WINRT_LIBRARY WINAPI_FAMILY=WINAPI_FAMILY_DESKTOP_APP
-
-QMAKE_CXXFLAGS += -EHsc
-
-LIBS += -lruntimeobject -lsetupapi -lcredui -lsecur32
-
-SOURCES = \
- appxhandler.cpp \
- d3dservice.cpp \
- main.cpp \
- xaphandler.cpp \
- compilation.cpp \
- info.cpp
-
-HEADERS = \
- d3dservice.h
-
-include(../shared/corecon/corecon.pri)
-
-load(qt_tool)
+++ /dev/null
-/****************************************************************************
-**
-** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the tools applications of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "d3dservice.h"
-
-#include <QtCore/QDateTime>
-#include <QtCore/QDir>
-#include <QtCore/QStandardPaths>
-#include <QtCore/QStringList>
-
-#include <comdef.h>
-#include <wrl.h>
-using namespace Microsoft::WRL;
-
-#include <ccapi_11.h>
-#include <corecon.h>
-Q_GLOBAL_STATIC_WITH_ARGS(CoreConServer, coreConServer, (11))
-
-#define bstr(s) _bstr_t((const wchar_t *)s.utf16())
-
-static bool isEmulatorRunning(CoreConDevice *device)
-{
- const QString deviceName = device->name();
- HWND window = FindWindow(NULL, reinterpret_cast<LPCWSTR>(deviceName.utf16()));
- if (!window)
- return false;
-
- // Sanity check: make sure the window belongs to XDE
- DWORD processId = 0;
- GetWindowThreadProcessId(window, &processId);
- if (!processId) {
- qCDebug(lcD3DService) << "Unable to get process ID for window:"
- << qt_error_string(GetLastError());
- return false;
- }
-
- HANDLE process = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, processId);
- if (!process) {
- qCDebug(lcD3DService) << "Unable to open process:"
- << qt_error_string(GetLastError());
- return false;
- }
-
- WCHAR imageName[MAX_PATH];
- DWORD imageNameSize = MAX_PATH;
- if (!QueryFullProcessImageName(process, 0, imageName, &imageNameSize)) {
- qCDebug(lcD3DService) << "Unable to query process:" << imageName
- << qt_error_string(GetLastError());
- CloseHandle(process);
- return false;
- }
- CloseHandle(process);
-
- // Fuzzy logic: simply check that the owning process is XDE
- const QString imageNameString = QString::fromWCharArray(imageName);
- if (imageNameString.endsWith(QStringLiteral("XDE.exe")))
- return true;
-
- return false;
-}
-
-// This is used by the service to simplify gathering of device data
-extern QStringList xapDeviceNames()
-{
- if (!coreConServer->initialize()) {
- while (!coreConServer.exists())
- Sleep(1);
- }
-
- QStringList deviceNames;
- foreach (const CoreConDevice *device, coreConServer->devices())
- deviceNames.append(device->name());
-
- return deviceNames;
-}
-
-// Allows looking up of application names
-extern int xapAppNames(int deviceIndex, QSet<QString> &apps)
-{
- if (!coreConServer->initialize()) {
- while (!coreConServer.exists())
- Sleep(1);
- }
-
- CoreConDevice *device = coreConServer->devices().value(deviceIndex, 0);
- if (!device) {
- qCWarning(lcD3DService) << "Device at index" << deviceIndex << "not found.";
- return 1;
- }
-
- // For emulators, check that XDE is still running
- if (device->isEmulator() && !isEmulatorRunning(device)) {
- qCWarning(lcD3DService) << "The emulator" << device->name()
- << "does not appear to be running.";
- return 1;
- }
-
- HRESULT hr;
- _bstr_t connectionName;
- ComPtr<ICcConnection> connection;
- hr = static_cast<ICcServer *>(coreConServer->handle())->GetConnection(
- static_cast<ICcDevice *>(device->handle()), 5000, NULL, connectionName.GetAddress(), &connection);
- if (FAILED(hr)) {
- qCWarning(lcD3DService) << "Unable to initialize connection:"
- << coreConServer->formatError(hr);
- return 1;
- }
-
- hr = connection->ConnectDevice();
- // For phones, we wait around for a pin unlock (or a different error)
- if (!device->isEmulator()) {
- while (hr == 0x89740006) { // Device is pinlocked
- qCDebug(lcD3DService) << coreConServer->formatError(hr);
- Sleep(1000);
- hr = connection->ConnectDevice();
- }
- }
- if (FAILED(hr)) {
- qCWarning(lcD3DService) << "Unable to connect to device:"
- << coreConServer->formatError(hr);
- return 1;
- }
-
- ComPtr<ICcConnection3> connection3;
- hr = connection.As(&connection3);
- if (FAILED(hr)) {
- qCWarning(lcD3DService) << "Unable to obtain connection3 interface:"
- << coreConServer->formatError(hr);
- return 1;
- }
-
- SAFEARRAY *productIds, *instanceIds;
- hr = connection3->GetInstalledApplicationIDs(&productIds, &instanceIds);
- if (FAILED(hr)) {
- qCWarning(lcD3DService) << "Unable to get installed applications:"
- << coreConServer->formatError(hr);
- return 1;
- }
- if (productIds && instanceIds) {
- Q_ASSERT(productIds->rgsabound[0].cElements == instanceIds->rgsabound[0].cElements);
- for (ulong i = 0; i < productIds->rgsabound[0].cElements; ++i) {
- LONG indices[] = { i };
- _bstr_t productId;
- _bstr_t instanceId;
- if (SUCCEEDED(SafeArrayGetElement(productIds, indices, productId.GetAddress()))
- && SUCCEEDED(SafeArrayGetElement(instanceIds, indices, instanceId.GetAddress()))) {
- apps.insert(QString::fromWCharArray(productId));
- }
- }
- SafeArrayDestroy(productIds);
- SafeArrayDestroy(instanceIds);
- return 0;
- }
-
- // No installed applications
- return 0;
-}
-
-/* This method runs in its own thread for each CoreCon device/application combo
- * the service is currently handling. */
-extern int handleXapDevice(int deviceIndex, const QString &app, const QString &localBase, HANDLE runLock)
-{
- if (!coreConServer->initialize()) {
- while (!coreConServer.exists())
- Sleep(1);
- }
-
- CoreConDevice *device = coreConServer->devices().value(deviceIndex, 0);
- if (!device) {
- qCWarning(lcD3DService) << "Device at index" << deviceIndex << "not found.";
- return 1;
- }
-
- // For emulators, check that XDE is still running
- if (device->isEmulator() && !isEmulatorRunning(device)) {
- qCWarning(lcD3DService) << "The emulator" << device->name()
- << "does not appear to be running.";
- return 1;
- }
-
- const QString localSourcePath = localBase + QStringLiteral("\\source\\");
- const QString localBinaryPath = localBase + QStringLiteral("\\binary\\");
-
- const QString remoteBase = QStringLiteral("%FOLDERID_APPID_ISOROOT%\\")
- + app + QStringLiteral("\\d3dcompiler");
- const QString remoteSourcePath = remoteBase + QStringLiteral("\\source\\");
- const QString remoteBinaryPath = remoteBase + QStringLiteral("\\binary\\");
-
- HRESULT hr;
- _bstr_t connectionName;
- ComPtr<ICcConnection> connection;
- hr = static_cast<ICcServer *>(coreConServer->handle())->GetConnection(
- static_cast<ICcDevice *>(device->handle()), 5000, NULL, connectionName.GetAddress(), &connection);
- if (FAILED(hr)) {
- qCWarning(lcD3DService) << "Unable to initialize connection:"
- << coreConServer->formatError(hr);
- return 1;
- }
-
- ComPtr<ICcConnection3> connection3;
- hr = connection.As(&connection3);
- if (FAILED(hr)) {
- qCWarning(lcD3DService) << "Unable to obtain connection3 interface:"
- << coreConServer->formatError(hr);
- return 1;
- }
-
- ComPtr<ICcConnection4> connection4;
- hr = connection.As(&connection4);
- if (FAILED(hr)) {
- qCWarning(lcD3DService) << "Unable to obtain connection4 interface:"
- << coreConServer->formatError(hr);
- return 1;
- }
-
- bool wasDisconnected = true;
- forever {
- // If the run lock is signaled, it's time to quit
- if (WaitForSingleObject(runLock, 0) == WAIT_OBJECT_0)
- return 0;
-
- VARIANT_BOOL connected;
- hr = connection->IsConnected(&connected);
- if (FAILED(hr)) {
- qCWarning(lcD3DService) << "Unable to query connection state:"
- << coreConServer->formatError(hr);
- Sleep(1000);
- continue;
- }
-
- if (!connected) {
- hr = connection->ConnectDevice();
- connected = SUCCEEDED(hr);
- if (connected) {
- qCWarning(lcD3DService).nospace() << "Connected to " << device->name() << ".";
- wasDisconnected = true;
- } else {
- qCDebug(lcD3DService).nospace() << "Unable to connect to " << device->name()
- << ": " << coreConServer->formatError(hr);
- return 1;
- }
- }
-
- VARIANT_BOOL isInstalled;
- hr = connection3->IsApplicationInstalled(bstr(app), &isInstalled);
- if (FAILED(hr)) {
- qCCritical(lcD3DService) << "Unable to determine if package is installed:"
- << coreConServer->formatError(hr);
- return 1;
- }
- if (!isInstalled) {
- qCWarning(lcD3DService) << "Package" << app << "is not installed. Exiting worker.";
- return 1;
- }
-
- // Run certain setup steps once per connection
- if (wasDisconnected) {
- FileInfo remoteDirectoryInfo;
- hr = connection->GetFileInfo(bstr(remoteSourcePath), &remoteDirectoryInfo);
- if (FAILED(hr)) {
- if (hr != 0x80070002 && hr != 0x80070003 /* Not found */) {
- qCWarning(lcD3DService) << "Unable to get remote directory info:"
- << coreConServer->formatError(hr);
- Sleep(1000);
- continue;
- }
-
- // Not found, create remote source path
- hr = connection->MakeDirectory(bstr(remoteSourcePath));
- if (FAILED(hr)) {
- qCWarning(lcD3DService) << "Unable to create the shader source directory:"
- << coreConServer->formatError(hr);
- Sleep(1000);
- continue;
- }
- }
-
- hr = connection->GetFileInfo(bstr(remoteBinaryPath), &remoteDirectoryInfo);
- if (FAILED(hr)) {
- if (hr != 0x80070002 && hr != 0x80070003 /* Not found */) {
- qCWarning(lcD3DService) << "Unable to get remote directory info:"
- << coreConServer->formatError(hr);
- Sleep(1000);
- continue;
- }
-
- // Not found, create remote source path
- hr = connection->MakeDirectory(bstr(remoteBinaryPath));
- if (FAILED(hr)) {
- qCWarning(lcD3DService) << "Unable to create the shader source directory:"
- << coreConServer->formatError(hr);
- Sleep(1000);
- continue;
- }
- }
-
- wasDisconnected = false;
- }
-
- // Ok, ready to check for shaders
- SAFEARRAY *listing;
- hr = connection4->GetDirectoryListing(bstr(remoteSourcePath), &listing);
- if (FAILED(hr)) {
- qCWarning(lcD3DService) << "Unable to get the shader source directory listing:"
- << coreConServer->formatError(hr);
- wasDisconnected = true;
- Sleep(1000);
- continue;
- }
- QStringList shaderSources;
- if (listing) {
- for (ulong i = 0; i < listing->rgsabound[0].cElements; ++i) {
- LONG indices[] = { i };
- _bstr_t fileName;
- if (SUCCEEDED(SafeArrayGetElement(listing, indices, fileName.GetAddress()))) {
- // Get the file
- QString remoteFile = remoteSourcePath + QString::fromWCharArray(fileName);
- QString localFile = localSourcePath + QString::fromWCharArray(fileName);
- qCDebug(lcD3DService) << "Found remote shader:" << remoteFile;
- hr = connection->ReceiveFile(bstr(remoteFile), bstr(localFile), 2);
- if (FAILED(hr)) {
- qCWarning(lcD3DService) << "Unable to retrieve the remote shader file:"
- << remoteFile << coreConServer->formatError(hr);
- continue;
- }
- // Remove the remote file, push into a list for compilation
- shaderSources.append(localFile);
- hr = connection->RemoveFile(bstr(remoteFile));
- if (FAILED(hr)) {
- qCWarning(lcD3DService) << "Unable to remove remote shader file:"
- << remoteFile << coreConServer->formatError(hr);
- continue;
- }
- }
- }
- SafeArrayDestroy(listing);
- }
-
- foreach (const QString &shaderSource, shaderSources) {
- const QString shaderFileName = QFileInfo(shaderSource).fileName();
- const QString localBinary = localBinaryPath + shaderFileName;
- hr = D3DService::compileShader(shaderSource, localBinary);
- if (FAILED(hr)) {
- qCWarning(lcD3DService) << "Unable to compile shader:" << shaderSource
- << coreConServer->formatError(hr);
- continue;
- }
-
- // All went well, upload the file
- const QString remoteBinary = remoteBinaryPath + shaderFileName;
- hr = connection->SendFile(bstr(localBinary), bstr(remoteBinary), CREATE_ALWAYS, NULL);
- if (FAILED(hr)) {
- qCWarning(lcD3DService) << "Unable to upload binary:"
- << remoteBinary << coreConServer->formatError(hr);
- continue;
- }
-
- qCDebug(lcD3DService) << "Compiled local shader to:" << localBinary
- << "and uploaded to" << remoteBinary;
- }
-
- // Done, take a break.
- Sleep(1000);
- }
-}
qtHaveModule(dbus): SUBDIRS += qdbus
win32|winrt:SUBDIRS += windeployqt
-winrt:SUBDIRS += winrtrunner qtd3dservice
+winrt:SUBDIRS += winrtrunner
qtHaveModule(gui):!android:!ios:!qnx:!wince*:!winrt*:SUBDIRS += qtdiag
qtNomakeTools( \