Merge dev into 5.6
Change-Id: I061f2513ef58f696e75b11928d89aaaf059659a3
This commit is contained in:
commit
5a039bf53e
3
configure
vendored
3
configure
vendored
@ -3636,9 +3636,6 @@ if [ -z "$QT_INSTALL_PREFIX" ]; then
|
||||
else
|
||||
QT_INSTALL_PREFIX="/usr/local/Qt-${QT_VERSION}" # the default install prefix is /usr/local/Qt-$QT_VERSION
|
||||
fi
|
||||
HAVE_INSTALL_PATH=false
|
||||
else
|
||||
HAVE_INSTALL_PATH=true
|
||||
fi
|
||||
QT_INSTALL_PREFIX=`makeabs "$QT_INSTALL_PREFIX"`
|
||||
|
||||
|
@ -196,6 +196,7 @@ void MainWindow::createActions()
|
||||
QMenu *editMenu = menuBar()->addMenu(tr("&Edit"));
|
||||
QToolBar *editToolBar = addToolBar(tr("Edit"));
|
||||
//!
|
||||
#ifndef QT_NO_CLIPBOARD
|
||||
const QIcon cutIcon = QIcon::fromTheme("edit-cut", QIcon(":/images/cut.png"));
|
||||
QAction *cutAct = new QAction(cutIcon, tr("Cu&t"), this);
|
||||
//! [21]
|
||||
@ -226,6 +227,8 @@ void MainWindow::createActions()
|
||||
|
||||
menuBar()->addSeparator();
|
||||
|
||||
#endif // !QT_NO_CLIPBOARD
|
||||
|
||||
QMenu *helpMenu = menuBar()->addMenu(tr("&Help"));
|
||||
QAction *aboutAct = helpMenu->addAction(tr("&About"), this, &MainWindow::about);
|
||||
aboutAct->setStatusTip(tr("Show the application's About box"));
|
||||
@ -237,11 +240,13 @@ void MainWindow::createActions()
|
||||
//! [22]
|
||||
|
||||
//! [23]
|
||||
#ifndef QT_NO_CLIPBOARD
|
||||
cutAct->setEnabled(false);
|
||||
//! [23] //! [24]
|
||||
copyAct->setEnabled(false);
|
||||
connect(textEdit, &QPlainTextEdit::copyAvailable, cutAct, &QAction::setEnabled);
|
||||
connect(textEdit, &QPlainTextEdit::copyAvailable, copyAct, &QAction::setEnabled);
|
||||
#endif // !QT_NO_CLIPBOARD
|
||||
}
|
||||
//! [24]
|
||||
|
||||
|
@ -224,6 +224,7 @@ void MainWindow::createActions()
|
||||
QMenu *editMenu = menuBar()->addMenu(tr("&Edit"));
|
||||
QToolBar *editToolBar = addToolBar(tr("Edit"));
|
||||
|
||||
#ifndef QT_NO_CLIPBOARD
|
||||
const QIcon cutIcon = QIcon::fromTheme("edit-cut", QIcon(":/images/cut.png"));
|
||||
QAction *cutAct = new QAction(cutIcon, tr("Cu&t"), this);
|
||||
cutAct->setShortcuts(QKeySequence::Cut);
|
||||
@ -252,6 +253,7 @@ void MainWindow::createActions()
|
||||
editToolBar->addAction(pasteAct);
|
||||
|
||||
menuBar()->addSeparator();
|
||||
#endif // !QT_NO_CLIPBOARD
|
||||
|
||||
QMenu *helpMenu = menuBar()->addMenu(tr("&Help"));
|
||||
QAction *aboutAct = helpMenu->addAction(tr("&About"), this, &MainWindow::about);
|
||||
@ -260,10 +262,12 @@ void MainWindow::createActions()
|
||||
QAction *aboutQtAct = helpMenu->addAction(tr("About &Qt"), qApp, &QApplication::aboutQt);
|
||||
aboutQtAct->setStatusTip(tr("Show the Qt library's About box"));
|
||||
|
||||
#ifndef QT_NO_CLIPBOARD
|
||||
cutAct->setEnabled(false);
|
||||
copyAct->setEnabled(false);
|
||||
connect(textEdit, &QTextEdit::copyAvailable, cutAct, &QAction::setEnabled);
|
||||
connect(textEdit, &QTextEdit::copyAvailable, copyAct, &QAction::setEnabled);
|
||||
#endif // !QT_NO_CLIPBOARD
|
||||
}
|
||||
|
||||
void MainWindow::createStatusBar()
|
||||
|
1
src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp
vendored
Normal file → Executable file
1
src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp
vendored
Normal file → Executable file
@ -203,6 +203,7 @@ egl::Error SurfaceD3D::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
|
||||
|
||||
if (width == 0 || height == 0)
|
||||
{
|
||||
checkForOutOfDateSwapChain();
|
||||
return egl::Error(EGL_SUCCESS);
|
||||
}
|
||||
|
||||
|
@ -154,14 +154,8 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei
|
||||
const bool useSharedResource = !mNativeWindow.getNativeWindow() && mRenderer->getShareHandleSupport();
|
||||
|
||||
D3D11_TEXTURE2D_DESC offscreenTextureDesc = {0};
|
||||
#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
|
||||
const int textureLength = std::max(backbufferWidth, backbufferHeight);
|
||||
offscreenTextureDesc.Width = textureLength;
|
||||
offscreenTextureDesc.Height = textureLength;
|
||||
#else
|
||||
offscreenTextureDesc.Width = backbufferWidth;
|
||||
offscreenTextureDesc.Height = backbufferHeight;
|
||||
#endif
|
||||
offscreenTextureDesc.Format = backbufferFormatInfo.texFormat;
|
||||
offscreenTextureDesc.MipLevels = 1;
|
||||
offscreenTextureDesc.ArraySize = 1;
|
||||
@ -241,14 +235,8 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei
|
||||
if (mDepthBufferFormat != GL_NONE)
|
||||
{
|
||||
D3D11_TEXTURE2D_DESC depthStencilTextureDesc;
|
||||
#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
|
||||
const int textureLength = std::max(backbufferWidth, backbufferHeight);
|
||||
depthStencilTextureDesc.Width = textureLength;
|
||||
depthStencilTextureDesc.Height = textureLength;
|
||||
#else
|
||||
depthStencilTextureDesc.Width = backbufferWidth;
|
||||
depthStencilTextureDesc.Height = backbufferHeight;
|
||||
#endif
|
||||
depthStencilTextureDesc.Format = depthBufferFormatInfo.texFormat;
|
||||
depthStencilTextureDesc.MipLevels = 1;
|
||||
depthStencilTextureDesc.ArraySize = 1;
|
||||
@ -349,7 +337,6 @@ EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight)
|
||||
return EGL_SUCCESS;
|
||||
}
|
||||
|
||||
#if !defined(ANGLE_ENABLE_WINDOWS_STORE) || (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP)
|
||||
// Can only call resize if we have already created our swap buffer and resources
|
||||
ASSERT(mSwapChain && mBackBufferTexture && mBackBufferRTView);
|
||||
|
||||
@ -392,12 +379,6 @@ EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight)
|
||||
}
|
||||
|
||||
return resetOffscreenTexture(backbufferWidth, backbufferHeight);
|
||||
#else
|
||||
// Do nothing on Windows Phone apart from updating the internal buffer/width height
|
||||
mWidth = backbufferWidth;
|
||||
mHeight = backbufferHeight;
|
||||
return EGL_SUCCESS;
|
||||
#endif
|
||||
}
|
||||
|
||||
EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swapInterval)
|
||||
@ -552,27 +533,6 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
|
||||
|
||||
d3d11::PositionTexCoordVertex *vertices = static_cast<d3d11::PositionTexCoordVertex*>(mappedResource.pData);
|
||||
|
||||
#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
|
||||
// Create a quad in homogeneous coordinates
|
||||
float x1 = -1.0f;
|
||||
float y1 = -1.0f;
|
||||
float x2 = 1.0f;
|
||||
float y2 = 1.0f;
|
||||
|
||||
const float dim = std::max(mWidth, mHeight);
|
||||
float u1 = 0;
|
||||
float v1 = 0;
|
||||
float u2 = float(width) / dim;
|
||||
float v2 = float(height) / dim;
|
||||
|
||||
const NativeWindow::RotationFlags flags = mNativeWindow.rotationFlags();
|
||||
const bool rotateL = flags == NativeWindow::RotateLeft;
|
||||
const bool rotateR = flags == NativeWindow::RotateRight;
|
||||
d3d11::SetPositionTexCoordVertex(&vertices[0], x1, y1, rotateL ? u2 : u1, rotateR ? v2 : v1);
|
||||
d3d11::SetPositionTexCoordVertex(&vertices[1], x1, y2, rotateR ? u2 : u1, rotateL ? v1 : v2);
|
||||
d3d11::SetPositionTexCoordVertex(&vertices[2], x2, y1, rotateR ? u1 : u2, rotateL ? v2 : v1);
|
||||
d3d11::SetPositionTexCoordVertex(&vertices[3], x2, y2, rotateL ? u1 : u2, rotateR ? v1 : v2);
|
||||
#else
|
||||
// Create a quad in homogeneous coordinates
|
||||
float x1 = (x / float(mWidth)) * 2.0f - 1.0f;
|
||||
float y1 = (y / float(mHeight)) * 2.0f - 1.0f;
|
||||
@ -588,7 +548,6 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
|
||||
d3d11::SetPositionTexCoordVertex(&vertices[1], x1, y2, u1, v2);
|
||||
d3d11::SetPositionTexCoordVertex(&vertices[2], x2, y1, u2, v1);
|
||||
d3d11::SetPositionTexCoordVertex(&vertices[3], x2, y2, u2, v2);
|
||||
#endif
|
||||
|
||||
deviceContext->Unmap(mQuadVB, 0);
|
||||
|
||||
@ -618,13 +577,8 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
|
||||
D3D11_VIEWPORT viewport;
|
||||
viewport.TopLeftX = 0;
|
||||
viewport.TopLeftY = 0;
|
||||
#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
|
||||
viewport.Width = (rotateL || rotateR) ? height : width;
|
||||
viewport.Height = (rotateL || rotateR) ? width : height;
|
||||
#else
|
||||
viewport.Width = mWidth;
|
||||
viewport.Height = mHeight;
|
||||
#endif
|
||||
viewport.MinDepth = 0.0f;
|
||||
viewport.MaxDepth = 1.0f;
|
||||
deviceContext->RSSetViewports(1, &viewport);
|
||||
|
@ -191,25 +191,4 @@ HRESULT GetCoreWindowSizeInPixels(const ComPtr<ABI::Windows::UI::Core::ICoreWind
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static float GetLogicalDpi()
|
||||
{
|
||||
ComPtr<ABI::Windows::Graphics::Display::IDisplayPropertiesStatics> displayProperties;
|
||||
float dpi = 96.0f;
|
||||
|
||||
if (SUCCEEDED(GetActivationFactory(HStringReference(RuntimeClass_Windows_Graphics_Display_DisplayProperties).Get(), displayProperties.GetAddressOf())))
|
||||
{
|
||||
if (SUCCEEDED(displayProperties->get_LogicalDpi(&dpi)))
|
||||
{
|
||||
return dpi;
|
||||
}
|
||||
}
|
||||
return dpi;
|
||||
}
|
||||
|
||||
long ConvertDipsToPixels(float dips)
|
||||
{
|
||||
static const float dipsPerInch = 96.0f;
|
||||
return lround((dips * GetLogicalDpi() / dipsPerInch));
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,6 @@ typedef ABI::Windows::Foundation::__FITypedEventHandler_2_Windows__CGraphics__CD
|
||||
|
||||
namespace rx
|
||||
{
|
||||
long ConvertDipsToPixels(float dips);
|
||||
|
||||
class CoreWindowNativeWindow : public InspectableNativeWindow, public std::enable_shared_from_this<CoreWindowNativeWindow>
|
||||
{
|
||||
@ -64,8 +63,7 @@ class CoreWindowSizeChangedHandler :
|
||||
ABI::Windows::Foundation::Size windowSize;
|
||||
if (SUCCEEDED(sizeChangedEventArgs->get_Size(&windowSize)))
|
||||
{
|
||||
SIZE windowSizeInPixels = { ConvertDipsToPixels(windowSize.Width), ConvertDipsToPixels(windowSize.Height) };
|
||||
host->setNewClientSize(windowSizeInPixels);
|
||||
host->setNewClientSize(windowSize);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -288,4 +288,25 @@ HRESULT GetOptionalSizePropertyValue(const ComPtr<ABI::Windows::Foundation::Coll
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static float GetLogicalDpi()
|
||||
{
|
||||
ComPtr<ABI::Windows::Graphics::Display::IDisplayPropertiesStatics> displayProperties;
|
||||
float dpi = 96.0f;
|
||||
|
||||
if (SUCCEEDED(GetActivationFactory(HStringReference(RuntimeClass_Windows_Graphics_Display_DisplayProperties).Get(), displayProperties.GetAddressOf())))
|
||||
{
|
||||
if (SUCCEEDED(displayProperties->get_LogicalDpi(&dpi)))
|
||||
{
|
||||
return dpi;
|
||||
}
|
||||
}
|
||||
return dpi;
|
||||
}
|
||||
|
||||
long ConvertDipsToPixels(float dips)
|
||||
{
|
||||
static const float dipsPerInch = 96.0f;
|
||||
return lround((dips * GetLogicalDpi() / dipsPerInch));
|
||||
}
|
||||
}
|
||||
|
@ -26,6 +26,8 @@ using namespace ABI::Windows::Foundation::Collections;
|
||||
|
||||
namespace rx
|
||||
{
|
||||
long ConvertDipsToPixels(float dips);
|
||||
|
||||
class InspectableNativeWindow
|
||||
{
|
||||
public:
|
||||
@ -45,7 +47,7 @@ class InspectableNativeWindow
|
||||
virtual HRESULT createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain) = 0;
|
||||
virtual bool registerForSizeChangeEvents() = 0;
|
||||
virtual void unregisterForSizeChangeEvents() = 0;
|
||||
virtual HRESULT scaleSwapChain(const SIZE& newSize) { return S_OK; }
|
||||
virtual HRESULT scaleSwapChain(const Size& newSize) { return S_OK; }
|
||||
|
||||
bool getClientRect(RECT *rect)
|
||||
{
|
||||
@ -59,11 +61,11 @@ class InspectableNativeWindow
|
||||
return true;
|
||||
}
|
||||
|
||||
void setNewClientSize(const SIZE &newSize)
|
||||
void setNewClientSize(const Size &newSize)
|
||||
{
|
||||
if (mSupportsSwapChainResize && !mRequiresSwapChainScaling)
|
||||
if (mSupportsSwapChainResize)
|
||||
{
|
||||
mNewClientRect = { 0, 0, newSize.cx, newSize.cy };
|
||||
mNewClientRect = { 0, 0, ConvertDipsToPixels(newSize.Width), ConvertDipsToPixels(newSize.Height) };
|
||||
mClientRectChanged = true;
|
||||
}
|
||||
|
||||
|
@ -66,7 +66,7 @@ bool SwapChainPanelNativeWindow::initialize(EGLNativeWindowType window, IPropert
|
||||
}
|
||||
else
|
||||
{
|
||||
result = GetSwapChainPanelSize(mSwapChainPanel, &mClientRect);
|
||||
result = GetSwapChainPanelSize(mSwapChainPanel, &mClientRect, &mRequiresSwapChainScaling);
|
||||
}
|
||||
}
|
||||
|
||||
@ -139,7 +139,6 @@ HRESULT SwapChainPanelNativeWindow::createSwapChain(ID3D11Device *device, DXGIFa
|
||||
|
||||
ComPtr<IDXGISwapChain1> newSwapChain;
|
||||
ComPtr<ISwapChainPanelNative> swapChainPanelNative;
|
||||
RECT currentPanelSize = {};
|
||||
|
||||
HRESULT result = factory->CreateSwapChainForComposition(device, &swapChainDesc, nullptr, newSwapChain.ReleaseAndGetAddressOf());
|
||||
|
||||
@ -167,13 +166,13 @@ HRESULT SwapChainPanelNativeWindow::createSwapChain(ID3D11Device *device, DXGIFa
|
||||
// first reading the current size of the swapchain panel, then scaling
|
||||
if (SUCCEEDED(result) && mRequiresSwapChainScaling)
|
||||
{
|
||||
result = GetSwapChainPanelSize(mSwapChainPanel, ¤tPanelSize);
|
||||
}
|
||||
ComPtr<ABI::Windows::UI::Xaml::IUIElement> uiElement;
|
||||
result = mSwapChainPanel.As(&uiElement);
|
||||
ASSERT(SUCCEEDED(result));
|
||||
|
||||
// Scale the swapchain to fit inside the contents of the panel.
|
||||
if (SUCCEEDED(result) && mRequiresSwapChainScaling)
|
||||
{
|
||||
SIZE currentSize = { currentPanelSize.right, currentPanelSize.bottom };
|
||||
Size currentSize;
|
||||
result = uiElement->get_RenderSize(¤tSize);
|
||||
ASSERT(SUCCEEDED(result));
|
||||
result = scaleSwapChain(currentSize);
|
||||
}
|
||||
|
||||
@ -190,9 +189,9 @@ HRESULT SwapChainPanelNativeWindow::createSwapChain(ID3D11Device *device, DXGIFa
|
||||
return result;
|
||||
}
|
||||
|
||||
HRESULT SwapChainPanelNativeWindow::scaleSwapChain(const SIZE &newSize)
|
||||
HRESULT SwapChainPanelNativeWindow::scaleSwapChain(const Size &newSize)
|
||||
{
|
||||
ABI::Windows::Foundation::Size renderScale = { (float)newSize.cx/(float)mClientRect.right, (float)newSize.cy/(float)mClientRect.bottom };
|
||||
ABI::Windows::Foundation::Size renderScale = { newSize.Width / mNewClientRect.right, newSize.Height / mNewClientRect.bottom };
|
||||
// Setup a scale matrix for the swap chain
|
||||
DXGI_MATRIX_3X2_F scaleMatrix = {};
|
||||
scaleMatrix._11 = renderScale.Width;
|
||||
@ -208,7 +207,7 @@ HRESULT SwapChainPanelNativeWindow::scaleSwapChain(const SIZE &newSize)
|
||||
return result;
|
||||
}
|
||||
|
||||
HRESULT GetSwapChainPanelSize(const ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> &swapChainPanel, RECT *windowSize)
|
||||
HRESULT GetSwapChainPanelSize(const ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> &swapChainPanel, RECT *windowSize, bool *scalingActive)
|
||||
{
|
||||
ComPtr<ABI::Windows::UI::Xaml::IUIElement> uiElement;
|
||||
ABI::Windows::Foundation::Size renderSize = { 0, 0 };
|
||||
@ -220,7 +219,14 @@ HRESULT GetSwapChainPanelSize(const ComPtr<ABI::Windows::UI::Xaml::Controls::ISw
|
||||
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
*windowSize = { 0, 0, lround(renderSize.Width), lround(renderSize.Height) };
|
||||
long width = ConvertDipsToPixels(renderSize.Width);
|
||||
long height = ConvertDipsToPixels(renderSize.Height);
|
||||
*windowSize = { 0, 0, width, height };
|
||||
|
||||
if (scalingActive)
|
||||
{
|
||||
*scalingActive = width != renderSize.Width || height != renderSize.Height;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -22,7 +22,7 @@ class SwapChainPanelNativeWindow : public InspectableNativeWindow, public std::e
|
||||
bool registerForSizeChangeEvents();
|
||||
void unregisterForSizeChangeEvents();
|
||||
HRESULT createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain);
|
||||
HRESULT scaleSwapChain(const SIZE &newSize);
|
||||
HRESULT scaleSwapChain(const Size &newSize) override;
|
||||
|
||||
private:
|
||||
ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> mSwapChainPanel;
|
||||
@ -62,8 +62,7 @@ class SwapChainPanelSizeChangedHandler :
|
||||
HRESULT result = sizeChangedEventArgs->get_NewSize(&newSize);
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
SIZE windowSize = { lround(newSize.Width), lround(newSize.Height) };
|
||||
host->setNewClientSize(windowSize);
|
||||
host->setNewClientSize(newSize);
|
||||
}
|
||||
}
|
||||
|
||||
@ -74,6 +73,6 @@ class SwapChainPanelSizeChangedHandler :
|
||||
std::weak_ptr<InspectableNativeWindow> mHost;
|
||||
};
|
||||
|
||||
HRESULT GetSwapChainPanelSize(const ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> &swapChainPanel, RECT *windowSize);
|
||||
HRESULT GetSwapChainPanelSize(const ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> &swapChainPanel, RECT *windowSize, bool *scalingActive = nullptr);
|
||||
}
|
||||
#endif // LIBANGLE_RENDERER_D3D_D3D11_WINRT_SWAPCHAINPANELNATIVEWINDOW_H_
|
||||
|
64
src/3rdparty/forkfd/forkfd.c
vendored
64
src/3rdparty/forkfd/forkfd.c
vendored
@ -54,6 +54,9 @@
|
||||
# define HAVE_PIPE2 1
|
||||
# endif
|
||||
#endif
|
||||
#if defined(__FreeBSD__) && __FreeBSD__ >= 9
|
||||
# include <sys/procdesc.h>
|
||||
#endif
|
||||
|
||||
#if _POSIX_VERSION-0 >= 200809L || _XOPEN_VERSION-0 >= 500
|
||||
# define HAVE_WAITID 1
|
||||
@ -506,6 +509,46 @@ static int create_pipe(int filedes[], int flags)
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if defined(FORKFD_NO_SPAWNFD) && defined(__FreeBSD__) && __FreeBSD__ >= 9
|
||||
# if __FreeBSD__ == 9
|
||||
/* PROCDESC is an optional feature in the kernel and wasn't enabled
|
||||
* by default on FreeBSD 9. So we need to check for it at runtime. */
|
||||
static ffd_atomic_int system_has_forkfd = FFD_ATOMIC_INIT(1);
|
||||
# else
|
||||
/* On FreeBSD 10, PROCDESC was enabled by default. On v11, it's not an option
|
||||
* anymore and can't be disabled. */
|
||||
static const int system_has_forkfd = 1;
|
||||
# endif
|
||||
|
||||
static int system_forkfd(int flags, pid_t *ppid)
|
||||
{
|
||||
int ret;
|
||||
pid_t pid;
|
||||
pid = pdfork(&ret, PD_DAEMON);
|
||||
if (__builtin_expect(pid == -1, 0)) {
|
||||
# if __FreeBSD__ == 9
|
||||
if (errno == ENOSYS) {
|
||||
/* PROCDESC wasn't compiled into the kernel: don't try it again. */
|
||||
ffd_atomic_store(&system_has_forkfd, 0, FFD_ATOMIC_RELAXED);
|
||||
}
|
||||
# endif
|
||||
return -1;
|
||||
}
|
||||
if (pid == 0) {
|
||||
/* child process */
|
||||
return FFD_CHILD_PROCESS;
|
||||
}
|
||||
|
||||
/* parent process */
|
||||
if (flags & FFD_CLOEXEC)
|
||||
fcntl(ret, F_SETFD, FD_CLOEXEC);
|
||||
if (flags & FFD_NONBLOCK)
|
||||
fcntl(ret, F_SETFL, fcntl(ret, F_GETFL) | O_NONBLOCK);
|
||||
if (ppid)
|
||||
*ppid = pid;
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
static const int system_has_forkfd = 0;
|
||||
static int system_forkfd(int flags, pid_t *ppid)
|
||||
{
|
||||
@ -513,6 +556,7 @@ static int system_forkfd(int flags, pid_t *ppid)
|
||||
(void)ppid;
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef FORKFD_NO_FORKFD
|
||||
/**
|
||||
@ -748,6 +792,26 @@ int forkfd_wait(int ffd, forkfd_info *info, struct rusage *rusage)
|
||||
struct pipe_payload payload;
|
||||
int ret;
|
||||
|
||||
if (system_has_forkfd) {
|
||||
#if defined(__FreeBSD__) && __FreeBSD__ >= 9
|
||||
pid_t pid;
|
||||
int status;
|
||||
int options = WEXITED;
|
||||
|
||||
ret = pdgetpid(ffd, &pid);
|
||||
if (ret == -1)
|
||||
return ret;
|
||||
ret = fcntl(ffd, F_GETFL);
|
||||
if (ret == -1)
|
||||
return ret;
|
||||
options |= (ret & O_NONBLOCK) ? WNOHANG : 0;
|
||||
ret = wait4(pid, &status, options, rusage);
|
||||
if (ret != -1 && info)
|
||||
convertStatusToForkfdInfo(status, info);
|
||||
return ret == -1 ? -1 : 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
ret = read(ffd, &payload, sizeof(payload));
|
||||
if (ret == -1)
|
||||
return ret; /* pass errno, probably EINTR, EBADF or EWOULDBLOCK */
|
||||
|
@ -203,6 +203,16 @@ public class QtActivityDelegate
|
||||
private final int ImhUrlCharactersOnly = 0x400000;
|
||||
private final int ImhLatinOnly = 0x800000;
|
||||
|
||||
// enter key type - must be kept in sync with QTDIR/src/corelib/global/qnamespace.h
|
||||
private final int EnterKeyDefault = 0;
|
||||
private final int EnterKeyReturn = 1;
|
||||
private final int EnterKeyDone = 2;
|
||||
private final int EnterKeyGo = 3;
|
||||
private final int EnterKeySend = 4;
|
||||
private final int EnterKeySearch = 5;
|
||||
private final int EnterKeyNext = 6;
|
||||
private final int EnterKeyPrevious = 7;
|
||||
|
||||
// application state
|
||||
private final int ApplicationSuspended = 0x0;
|
||||
private final int ApplicationHidden = 0x1;
|
||||
@ -239,7 +249,7 @@ public class QtActivityDelegate
|
||||
}, 5);
|
||||
}
|
||||
|
||||
public void showSoftwareKeyboard(int x, int y, int width, int height, int inputHints)
|
||||
public void showSoftwareKeyboard(int x, int y, int width, int height, int inputHints, int enterKeyType)
|
||||
{
|
||||
if (m_imm == null)
|
||||
return;
|
||||
@ -252,7 +262,31 @@ public class QtActivityDelegate
|
||||
m_activity.getWindow().setSoftInputMode(m_softInputMode);
|
||||
|
||||
int initialCapsMode = 0;
|
||||
|
||||
int imeOptions = android.view.inputmethod.EditorInfo.IME_ACTION_DONE;
|
||||
|
||||
switch (enterKeyType) {
|
||||
case EnterKeyReturn:
|
||||
imeOptions = android.view.inputmethod.EditorInfo.IME_FLAG_NO_ENTER_ACTION;
|
||||
break;
|
||||
case EnterKeyGo:
|
||||
imeOptions = android.view.inputmethod.EditorInfo.IME_ACTION_GO;
|
||||
break;
|
||||
case EnterKeySend:
|
||||
imeOptions = android.view.inputmethod.EditorInfo.IME_ACTION_SEND;
|
||||
break;
|
||||
case EnterKeySearch:
|
||||
imeOptions = android.view.inputmethod.EditorInfo.IME_ACTION_SEARCH;
|
||||
break;
|
||||
case EnterKeyNext:
|
||||
imeOptions = android.view.inputmethod.EditorInfo.IME_ACTION_NEXT;
|
||||
break;
|
||||
case EnterKeyPrevious:
|
||||
if (Build.VERSION.SDK_INT > 10)
|
||||
imeOptions = android.view.inputmethod.EditorInfo.IME_ACTION_PREVIOUS;
|
||||
break;
|
||||
}
|
||||
|
||||
int inputType = android.text.InputType.TYPE_CLASS_TEXT;
|
||||
|
||||
if ((inputHints & (ImhPreferNumbers | ImhDigitsOnly | ImhFormattedNumbersOnly)) != 0) {
|
||||
@ -278,6 +312,8 @@ public class QtActivityDelegate
|
||||
if ((inputHints & (ImhEmailCharactersOnly | ImhUrlCharactersOnly)) != 0) {
|
||||
if ((inputHints & ImhUrlCharactersOnly) != 0) {
|
||||
inputType |= android.text.InputType.TYPE_TEXT_VARIATION_URI;
|
||||
|
||||
if (enterKeyType == 0) // not explicitly overridden
|
||||
imeOptions = android.view.inputmethod.EditorInfo.IME_ACTION_GO;
|
||||
} else if ((inputHints & ImhEmailCharactersOnly) != 0) {
|
||||
inputType |= android.text.InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
|
||||
@ -305,7 +341,7 @@ public class QtActivityDelegate
|
||||
}
|
||||
}
|
||||
|
||||
if ((inputHints & ImhMultiLine) != 0)
|
||||
if (enterKeyType == 0 && (inputHints & ImhMultiLine) != 0)
|
||||
imeOptions = android.view.inputmethod.EditorInfo.IME_FLAG_NO_ENTER_ACTION;
|
||||
|
||||
m_editText.setInitialCapsMode(initialCapsMode);
|
||||
|
@ -389,12 +389,13 @@ public class QtNative
|
||||
final int y,
|
||||
final int width,
|
||||
final int height,
|
||||
final int inputHints )
|
||||
final int inputHints,
|
||||
final int enterKeyType)
|
||||
{
|
||||
runAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
m_activityDelegate.showSoftwareKeyboard(x, y, width, height, inputHints);
|
||||
m_activityDelegate.showSoftwareKeyboard(x, y, width, height, inputHints, enterKeyType);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -0,0 +1,361 @@
|
||||
From 333bb863e5c3e04fcc513e4750208fa3742be7a1 Mon Sep 17 00:00:00 2001
|
||||
From: Andrew Knight <andrew.knight@intopalo.com>
|
||||
Date: Sat, 8 Aug 2015 21:42:03 +0300
|
||||
Subject: [PATCH 2/4] ANGLE: Use pixel sizes in the XAML swap chain
|
||||
|
||||
This is necessary for Qt applications, as they render to GL in physical
|
||||
pixels. This is consistent with the CoreWindow swap chain behavior.
|
||||
|
||||
This includes a partial revert of "ANGLE: Improve Windows Phone Support"
|
||||
as the modifications to SwapChain11 are incompatible with the XAML swap
|
||||
chain.
|
||||
|
||||
This change only affects Windows Runtime targets.
|
||||
|
||||
Change-Id: I401ae81028a9dfdb9da37f51c60844467c476f76
|
||||
---
|
||||
.../libANGLE/renderer/d3d/d3d11/SwapChain11.cpp | 46 ----------------------
|
||||
.../d3d/d3d11/winrt/CoreWindowNativeWindow.cpp | 21 ----------
|
||||
.../d3d/d3d11/winrt/CoreWindowNativeWindow.h | 4 +-
|
||||
.../d3d/d3d11/winrt/InspectableNativeWindow.cpp | 21 ++++++++++
|
||||
.../d3d/d3d11/winrt/InspectableNativeWindow.h | 10 +++--
|
||||
.../d3d/d3d11/winrt/SwapChainPanelNativeWindow.cpp | 30 ++++++++------
|
||||
.../d3d/d3d11/winrt/SwapChainPanelNativeWindow.h | 7 ++--
|
||||
7 files changed, 49 insertions(+), 90 deletions(-)
|
||||
|
||||
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp
|
||||
index dc539cf..0af2cf1 100644
|
||||
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp
|
||||
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp
|
||||
@@ -154,14 +154,8 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei
|
||||
const bool useSharedResource = !mNativeWindow.getNativeWindow() && mRenderer->getShareHandleSupport();
|
||||
|
||||
D3D11_TEXTURE2D_DESC offscreenTextureDesc = {0};
|
||||
-#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
|
||||
- const int textureLength = std::max(backbufferWidth, backbufferHeight);
|
||||
- offscreenTextureDesc.Width = textureLength;
|
||||
- offscreenTextureDesc.Height = textureLength;
|
||||
-#else
|
||||
offscreenTextureDesc.Width = backbufferWidth;
|
||||
offscreenTextureDesc.Height = backbufferHeight;
|
||||
-#endif
|
||||
offscreenTextureDesc.Format = backbufferFormatInfo.texFormat;
|
||||
offscreenTextureDesc.MipLevels = 1;
|
||||
offscreenTextureDesc.ArraySize = 1;
|
||||
@@ -241,14 +235,8 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei
|
||||
if (mDepthBufferFormat != GL_NONE)
|
||||
{
|
||||
D3D11_TEXTURE2D_DESC depthStencilTextureDesc;
|
||||
-#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
|
||||
- const int textureLength = std::max(backbufferWidth, backbufferHeight);
|
||||
- depthStencilTextureDesc.Width = textureLength;
|
||||
- depthStencilTextureDesc.Height = textureLength;
|
||||
-#else
|
||||
depthStencilTextureDesc.Width = backbufferWidth;
|
||||
depthStencilTextureDesc.Height = backbufferHeight;
|
||||
-#endif
|
||||
depthStencilTextureDesc.Format = depthBufferFormatInfo.texFormat;
|
||||
depthStencilTextureDesc.MipLevels = 1;
|
||||
depthStencilTextureDesc.ArraySize = 1;
|
||||
@@ -349,7 +337,6 @@ EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight)
|
||||
return EGL_SUCCESS;
|
||||
}
|
||||
|
||||
-#if !defined(ANGLE_ENABLE_WINDOWS_STORE) || (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP)
|
||||
// Can only call resize if we have already created our swap buffer and resources
|
||||
ASSERT(mSwapChain && mBackBufferTexture && mBackBufferRTView);
|
||||
|
||||
@@ -392,12 +379,6 @@ EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight)
|
||||
}
|
||||
|
||||
return resetOffscreenTexture(backbufferWidth, backbufferHeight);
|
||||
-#else
|
||||
- // Do nothing on Windows Phone apart from updating the internal buffer/width height
|
||||
- mWidth = backbufferWidth;
|
||||
- mHeight = backbufferHeight;
|
||||
- return EGL_SUCCESS;
|
||||
-#endif
|
||||
}
|
||||
|
||||
EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swapInterval)
|
||||
@@ -552,27 +533,6 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
|
||||
|
||||
d3d11::PositionTexCoordVertex *vertices = static_cast<d3d11::PositionTexCoordVertex*>(mappedResource.pData);
|
||||
|
||||
-#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
|
||||
- // Create a quad in homogeneous coordinates
|
||||
- float x1 = -1.0f;
|
||||
- float y1 = -1.0f;
|
||||
- float x2 = 1.0f;
|
||||
- float y2 = 1.0f;
|
||||
-
|
||||
- const float dim = std::max(mWidth, mHeight);
|
||||
- float u1 = 0;
|
||||
- float v1 = 0;
|
||||
- float u2 = float(width) / dim;
|
||||
- float v2 = float(height) / dim;
|
||||
-
|
||||
- const NativeWindow::RotationFlags flags = mNativeWindow.rotationFlags();
|
||||
- const bool rotateL = flags == NativeWindow::RotateLeft;
|
||||
- const bool rotateR = flags == NativeWindow::RotateRight;
|
||||
- d3d11::SetPositionTexCoordVertex(&vertices[0], x1, y1, rotateL ? u2 : u1, rotateR ? v2 : v1);
|
||||
- d3d11::SetPositionTexCoordVertex(&vertices[1], x1, y2, rotateR ? u2 : u1, rotateL ? v1 : v2);
|
||||
- d3d11::SetPositionTexCoordVertex(&vertices[2], x2, y1, rotateR ? u1 : u2, rotateL ? v2 : v1);
|
||||
- d3d11::SetPositionTexCoordVertex(&vertices[3], x2, y2, rotateL ? u1 : u2, rotateR ? v1 : v2);
|
||||
-#else
|
||||
// Create a quad in homogeneous coordinates
|
||||
float x1 = (x / float(mWidth)) * 2.0f - 1.0f;
|
||||
float y1 = (y / float(mHeight)) * 2.0f - 1.0f;
|
||||
@@ -588,7 +548,6 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
|
||||
d3d11::SetPositionTexCoordVertex(&vertices[1], x1, y2, u1, v2);
|
||||
d3d11::SetPositionTexCoordVertex(&vertices[2], x2, y1, u2, v1);
|
||||
d3d11::SetPositionTexCoordVertex(&vertices[3], x2, y2, u2, v2);
|
||||
-#endif
|
||||
|
||||
deviceContext->Unmap(mQuadVB, 0);
|
||||
|
||||
@@ -618,13 +577,8 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
|
||||
D3D11_VIEWPORT viewport;
|
||||
viewport.TopLeftX = 0;
|
||||
viewport.TopLeftY = 0;
|
||||
-#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
|
||||
- viewport.Width = (rotateL || rotateR) ? height : width;
|
||||
- viewport.Height = (rotateL || rotateR) ? width : height;
|
||||
-#else
|
||||
viewport.Width = mWidth;
|
||||
viewport.Height = mHeight;
|
||||
-#endif
|
||||
viewport.MinDepth = 0.0f;
|
||||
viewport.MaxDepth = 1.0f;
|
||||
deviceContext->RSSetViewports(1, &viewport);
|
||||
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp
|
||||
index fa9a69c..f45a077 100644
|
||||
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp
|
||||
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp
|
||||
@@ -191,25 +191,4 @@ HRESULT GetCoreWindowSizeInPixels(const ComPtr<ABI::Windows::UI::Core::ICoreWind
|
||||
|
||||
return result;
|
||||
}
|
||||
-
|
||||
-static float GetLogicalDpi()
|
||||
-{
|
||||
- ComPtr<ABI::Windows::Graphics::Display::IDisplayPropertiesStatics> displayProperties;
|
||||
- float dpi = 96.0f;
|
||||
-
|
||||
- if (SUCCEEDED(GetActivationFactory(HStringReference(RuntimeClass_Windows_Graphics_Display_DisplayProperties).Get(), displayProperties.GetAddressOf())))
|
||||
- {
|
||||
- if (SUCCEEDED(displayProperties->get_LogicalDpi(&dpi)))
|
||||
- {
|
||||
- return dpi;
|
||||
- }
|
||||
- }
|
||||
- return dpi;
|
||||
-}
|
||||
-
|
||||
-long ConvertDipsToPixels(float dips)
|
||||
-{
|
||||
- static const float dipsPerInch = 96.0f;
|
||||
- return lround((dips * GetLogicalDpi() / dipsPerInch));
|
||||
-}
|
||||
}
|
||||
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.h
|
||||
index 59df9d5..87cdfe6 100644
|
||||
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.h
|
||||
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.h
|
||||
@@ -19,7 +19,6 @@ typedef ABI::Windows::Foundation::__FITypedEventHandler_2_Windows__CGraphics__CD
|
||||
|
||||
namespace rx
|
||||
{
|
||||
-long ConvertDipsToPixels(float dips);
|
||||
|
||||
class CoreWindowNativeWindow : public InspectableNativeWindow, public std::enable_shared_from_this<CoreWindowNativeWindow>
|
||||
{
|
||||
@@ -64,8 +63,7 @@ class CoreWindowSizeChangedHandler :
|
||||
ABI::Windows::Foundation::Size windowSize;
|
||||
if (SUCCEEDED(sizeChangedEventArgs->get_Size(&windowSize)))
|
||||
{
|
||||
- SIZE windowSizeInPixels = { ConvertDipsToPixels(windowSize.Width), ConvertDipsToPixels(windowSize.Height) };
|
||||
- host->setNewClientSize(windowSizeInPixels);
|
||||
+ host->setNewClientSize(windowSize);
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.cpp
|
||||
index 2bf48c5..e83f479 100644
|
||||
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.cpp
|
||||
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.cpp
|
||||
@@ -288,4 +288,25 @@ HRESULT GetOptionalSizePropertyValue(const ComPtr<ABI::Windows::Foundation::Coll
|
||||
|
||||
return result;
|
||||
}
|
||||
+
|
||||
+static float GetLogicalDpi()
|
||||
+{
|
||||
+ ComPtr<ABI::Windows::Graphics::Display::IDisplayPropertiesStatics> displayProperties;
|
||||
+ float dpi = 96.0f;
|
||||
+
|
||||
+ if (SUCCEEDED(GetActivationFactory(HStringReference(RuntimeClass_Windows_Graphics_Display_DisplayProperties).Get(), displayProperties.GetAddressOf())))
|
||||
+ {
|
||||
+ if (SUCCEEDED(displayProperties->get_LogicalDpi(&dpi)))
|
||||
+ {
|
||||
+ return dpi;
|
||||
+ }
|
||||
+ }
|
||||
+ return dpi;
|
||||
+}
|
||||
+
|
||||
+long ConvertDipsToPixels(float dips)
|
||||
+{
|
||||
+ static const float dipsPerInch = 96.0f;
|
||||
+ return lround((dips * GetLogicalDpi() / dipsPerInch));
|
||||
+}
|
||||
}
|
||||
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.h
|
||||
index 575bdf8..f053407 100644
|
||||
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.h
|
||||
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.h
|
||||
@@ -26,6 +26,8 @@ using namespace ABI::Windows::Foundation::Collections;
|
||||
|
||||
namespace rx
|
||||
{
|
||||
+long ConvertDipsToPixels(float dips);
|
||||
+
|
||||
class InspectableNativeWindow
|
||||
{
|
||||
public:
|
||||
@@ -45,7 +47,7 @@ class InspectableNativeWindow
|
||||
virtual HRESULT createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain) = 0;
|
||||
virtual bool registerForSizeChangeEvents() = 0;
|
||||
virtual void unregisterForSizeChangeEvents() = 0;
|
||||
- virtual HRESULT scaleSwapChain(const SIZE& newSize) { return S_OK; }
|
||||
+ virtual HRESULT scaleSwapChain(const Size& newSize) { return S_OK; }
|
||||
|
||||
bool getClientRect(RECT *rect)
|
||||
{
|
||||
@@ -59,11 +61,11 @@ class InspectableNativeWindow
|
||||
return true;
|
||||
}
|
||||
|
||||
- void setNewClientSize(const SIZE &newSize)
|
||||
+ void setNewClientSize(const Size &newSize)
|
||||
{
|
||||
- if (mSupportsSwapChainResize && !mRequiresSwapChainScaling)
|
||||
+ if (mSupportsSwapChainResize)
|
||||
{
|
||||
- mNewClientRect = { 0, 0, newSize.cx, newSize.cy };
|
||||
+ mNewClientRect = { 0, 0, ConvertDipsToPixels(newSize.Width), ConvertDipsToPixels(newSize.Height) };
|
||||
mClientRectChanged = true;
|
||||
}
|
||||
|
||||
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.cpp
|
||||
index 53899db..0b48b54 100644
|
||||
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.cpp
|
||||
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.cpp
|
||||
@@ -66,7 +66,7 @@ bool SwapChainPanelNativeWindow::initialize(EGLNativeWindowType window, IPropert
|
||||
}
|
||||
else
|
||||
{
|
||||
- result = GetSwapChainPanelSize(mSwapChainPanel, &mClientRect);
|
||||
+ result = GetSwapChainPanelSize(mSwapChainPanel, &mClientRect, &mRequiresSwapChainScaling);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,7 +139,6 @@ HRESULT SwapChainPanelNativeWindow::createSwapChain(ID3D11Device *device, DXGIFa
|
||||
|
||||
ComPtr<IDXGISwapChain1> newSwapChain;
|
||||
ComPtr<ISwapChainPanelNative> swapChainPanelNative;
|
||||
- RECT currentPanelSize = {};
|
||||
|
||||
HRESULT result = factory->CreateSwapChainForComposition(device, &swapChainDesc, nullptr, newSwapChain.ReleaseAndGetAddressOf());
|
||||
|
||||
@@ -167,13 +166,13 @@ HRESULT SwapChainPanelNativeWindow::createSwapChain(ID3D11Device *device, DXGIFa
|
||||
// first reading the current size of the swapchain panel, then scaling
|
||||
if (SUCCEEDED(result) && mRequiresSwapChainScaling)
|
||||
{
|
||||
- result = GetSwapChainPanelSize(mSwapChainPanel, ¤tPanelSize);
|
||||
- }
|
||||
+ ComPtr<ABI::Windows::UI::Xaml::IUIElement> uiElement;
|
||||
+ result = mSwapChainPanel.As(&uiElement);
|
||||
+ ASSERT(SUCCEEDED(result));
|
||||
|
||||
- // Scale the swapchain to fit inside the contents of the panel.
|
||||
- if (SUCCEEDED(result) && mRequiresSwapChainScaling)
|
||||
- {
|
||||
- SIZE currentSize = { currentPanelSize.right, currentPanelSize.bottom };
|
||||
+ Size currentSize;
|
||||
+ result = uiElement->get_RenderSize(¤tSize);
|
||||
+ ASSERT(SUCCEEDED(result));
|
||||
result = scaleSwapChain(currentSize);
|
||||
}
|
||||
|
||||
@@ -190,9 +189,9 @@ HRESULT SwapChainPanelNativeWindow::createSwapChain(ID3D11Device *device, DXGIFa
|
||||
return result;
|
||||
}
|
||||
|
||||
-HRESULT SwapChainPanelNativeWindow::scaleSwapChain(const SIZE &newSize)
|
||||
+HRESULT SwapChainPanelNativeWindow::scaleSwapChain(const Size &newSize)
|
||||
{
|
||||
- ABI::Windows::Foundation::Size renderScale = { (float)newSize.cx/(float)mClientRect.right, (float)newSize.cy/(float)mClientRect.bottom };
|
||||
+ ABI::Windows::Foundation::Size renderScale = { newSize.Width / mNewClientRect.right, newSize.Height / mNewClientRect.bottom };
|
||||
// Setup a scale matrix for the swap chain
|
||||
DXGI_MATRIX_3X2_F scaleMatrix = {};
|
||||
scaleMatrix._11 = renderScale.Width;
|
||||
@@ -208,7 +207,7 @@ HRESULT SwapChainPanelNativeWindow::scaleSwapChain(const SIZE &newSize)
|
||||
return result;
|
||||
}
|
||||
|
||||
-HRESULT GetSwapChainPanelSize(const ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> &swapChainPanel, RECT *windowSize)
|
||||
+HRESULT GetSwapChainPanelSize(const ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> &swapChainPanel, RECT *windowSize, bool *scalingActive)
|
||||
{
|
||||
ComPtr<ABI::Windows::UI::Xaml::IUIElement> uiElement;
|
||||
ABI::Windows::Foundation::Size renderSize = { 0, 0 };
|
||||
@@ -220,7 +219,14 @@ HRESULT GetSwapChainPanelSize(const ComPtr<ABI::Windows::UI::Xaml::Controls::ISw
|
||||
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
- *windowSize = { 0, 0, lround(renderSize.Width), lround(renderSize.Height) };
|
||||
+ long width = ConvertDipsToPixels(renderSize.Width);
|
||||
+ long height = ConvertDipsToPixels(renderSize.Height);
|
||||
+ *windowSize = { 0, 0, width, height };
|
||||
+
|
||||
+ if (scalingActive)
|
||||
+ {
|
||||
+ *scalingActive = width != renderSize.Width || height != renderSize.Height;
|
||||
+ }
|
||||
}
|
||||
|
||||
return result;
|
||||
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.h
|
||||
index caf327d..5debd2f 100644
|
||||
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.h
|
||||
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.h
|
||||
@@ -22,7 +22,7 @@ class SwapChainPanelNativeWindow : public InspectableNativeWindow, public std::e
|
||||
bool registerForSizeChangeEvents();
|
||||
void unregisterForSizeChangeEvents();
|
||||
HRESULT createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain);
|
||||
- HRESULT scaleSwapChain(const SIZE &newSize);
|
||||
+ HRESULT scaleSwapChain(const Size &newSize) override;
|
||||
|
||||
private:
|
||||
ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> mSwapChainPanel;
|
||||
@@ -62,8 +62,7 @@ class SwapChainPanelSizeChangedHandler :
|
||||
HRESULT result = sizeChangedEventArgs->get_NewSize(&newSize);
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
- SIZE windowSize = { lround(newSize.Width), lround(newSize.Height) };
|
||||
- host->setNewClientSize(windowSize);
|
||||
+ host->setNewClientSize(newSize);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,6 +73,6 @@ class SwapChainPanelSizeChangedHandler :
|
||||
std::weak_ptr<InspectableNativeWindow> mHost;
|
||||
};
|
||||
|
||||
-HRESULT GetSwapChainPanelSize(const ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> &swapChainPanel, RECT *windowSize);
|
||||
+HRESULT GetSwapChainPanelSize(const ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> &swapChainPanel, RECT *windowSize, bool *scalingActive = nullptr);
|
||||
}
|
||||
#endif // LIBANGLE_RENDERER_D3D_D3D11_WINRT_SWAPCHAINPANELNATIVEWINDOW_H_
|
||||
--
|
||||
1.9.5.msysgit.1
|
||||
|
@ -496,10 +496,13 @@ typedef qptrdiff qintptr;
|
||||
|
||||
#ifdef Q_CC_MSVC
|
||||
# define Q_NEVER_INLINE __declspec(noinline)
|
||||
# define Q_ALWAYS_INLINE __forceinline
|
||||
#elif defined(Q_CC_GNU)
|
||||
# define Q_NEVER_INLINE __attribute__((noinline))
|
||||
# define Q_ALWAYS_INLINE inline __attribute__((always_inline))
|
||||
#else
|
||||
# define Q_NEVER_INLINE
|
||||
# define Q_ALWAYS_INLINE inline
|
||||
#endif
|
||||
|
||||
//defines the type for the WNDPROC on windows
|
||||
|
@ -2206,6 +2206,16 @@ void QProcessPrivate::start(QIODevice::OpenMode mode)
|
||||
mode &= ~QIODevice::ReadOnly; // not open for reading
|
||||
if (mode == 0)
|
||||
mode = QIODevice::Unbuffered;
|
||||
#ifndef Q_OS_WINCE
|
||||
if ((mode & QIODevice::ReadOnly) == 0) {
|
||||
if (stdoutChannel.type == QProcessPrivate::Channel::Normal)
|
||||
q->setStandardOutputFile(q->nullDevice());
|
||||
if (stderrChannel.type == QProcessPrivate::Channel::Normal
|
||||
&& processChannelMode != QProcess::MergedChannels)
|
||||
q->setStandardErrorFile(q->nullDevice());
|
||||
}
|
||||
#endif
|
||||
|
||||
q->QIODevice::open(mode);
|
||||
|
||||
stdinChannel.closed = false;
|
||||
|
@ -182,7 +182,7 @@ QT_BEGIN_NAMESPACE
|
||||
\li "C:/Users/<USER>/AppData/Local/<APPNAME>/cache"
|
||||
\row \li GenericDataLocation
|
||||
\li "~/Library/Application Support", "/Library/Application Support"
|
||||
\li "C:/Users/<USER>/AppData/Local", "C:/ProgramData"
|
||||
\li "C:/Users/<USER>/AppData/Local", "C:/ProgramData", "<APPDIR>", "<APPDIR>/data"
|
||||
\row \li RuntimeLocation
|
||||
\li "~/Library/Application Support"
|
||||
\li "C:/Users/<USER>"
|
||||
|
@ -212,10 +212,8 @@ QStringList QStandardPaths::standardLocations(StandardLocation type)
|
||||
}
|
||||
dirs.append(result);
|
||||
#ifndef QT_BOOTSTRAPPED
|
||||
if (type != GenericDataLocation) {
|
||||
dirs.append(QCoreApplication::applicationDirPath());
|
||||
dirs.append(QCoreApplication::applicationDirPath() + QLatin1String("/data"));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
@ -323,17 +323,9 @@ uint QCoreApplicationPrivate::attribs = (1 << Qt::AA_SynthesizeMouseForUnhandled
|
||||
|
||||
struct QCoreApplicationData {
|
||||
QCoreApplicationData() Q_DECL_NOTHROW {
|
||||
#ifndef QT_NO_LIBRARY
|
||||
app_libpaths = 0;
|
||||
manual_libpaths = 0;
|
||||
#endif
|
||||
applicationNameSet = false;
|
||||
}
|
||||
~QCoreApplicationData() {
|
||||
#ifndef QT_NO_LIBRARY
|
||||
delete app_libpaths;
|
||||
delete manual_libpaths;
|
||||
#endif
|
||||
#ifndef QT_NO_QOBJECT
|
||||
// cleanup the QAdoptedThread created for the main() thread
|
||||
if (QCoreApplicationPrivate::theMainThread) {
|
||||
@ -377,8 +369,8 @@ struct QCoreApplicationData {
|
||||
bool applicationNameSet; // true if setApplicationName was called
|
||||
|
||||
#ifndef QT_NO_LIBRARY
|
||||
QStringList *app_libpaths;
|
||||
QStringList *manual_libpaths;
|
||||
QScopedPointer<QStringList> app_libpaths;
|
||||
QScopedPointer<QStringList> manual_libpaths;
|
||||
#endif
|
||||
|
||||
};
|
||||
@ -571,9 +563,9 @@ void QCoreApplicationPrivate::checkReceiverThread(QObject *receiver)
|
||||
void QCoreApplicationPrivate::appendApplicationPathToLibraryPaths()
|
||||
{
|
||||
#ifndef QT_NO_LIBRARY
|
||||
QStringList *app_libpaths = coreappdata()->app_libpaths;
|
||||
QStringList *app_libpaths = coreappdata()->app_libpaths.data();
|
||||
if (!app_libpaths)
|
||||
coreappdata()->app_libpaths = app_libpaths = new QStringList;
|
||||
coreappdata()->app_libpaths.reset(app_libpaths = new QStringList);
|
||||
QString app_location = QCoreApplication::applicationFilePath();
|
||||
app_location.truncate(app_location.lastIndexOf(QLatin1Char('/')));
|
||||
#ifdef Q_OS_WINRT
|
||||
@ -774,16 +766,14 @@ void QCoreApplication::init()
|
||||
// Reset the lib paths, so that they will be recomputed, taking the availability of argv[0]
|
||||
// into account. If necessary, recompute right away and replay the manual changes on top of the
|
||||
// new lib paths.
|
||||
QStringList *appPaths = coreappdata()->app_libpaths;
|
||||
QStringList *manualPaths = coreappdata()->manual_libpaths;
|
||||
QStringList *appPaths = coreappdata()->app_libpaths.take();
|
||||
QStringList *manualPaths = coreappdata()->manual_libpaths.take();
|
||||
if (appPaths) {
|
||||
coreappdata()->app_libpaths = 0;
|
||||
if (manualPaths) {
|
||||
// Replay the delta. As paths can only be prepended to the front or removed from
|
||||
// anywhere in the list, we can just linearly scan the lists and find the items that
|
||||
// have been removed. Once the original list is exhausted we know all the remaining
|
||||
// items have been added.
|
||||
coreappdata()->manual_libpaths = 0;
|
||||
QStringList newPaths(libraryPaths());
|
||||
for (int i = manualPaths->length(), j = appPaths->length(); i > 0 || j > 0; qt_noop()) {
|
||||
if (--j < 0) {
|
||||
@ -796,7 +786,7 @@ void QCoreApplication::init()
|
||||
}
|
||||
}
|
||||
delete manualPaths;
|
||||
coreappdata()->manual_libpaths = new QStringList(newPaths);
|
||||
coreappdata()->manual_libpaths.reset(new QStringList(newPaths));
|
||||
}
|
||||
delete appPaths;
|
||||
}
|
||||
@ -872,10 +862,8 @@ QCoreApplication::~QCoreApplication()
|
||||
#endif
|
||||
|
||||
#ifndef QT_NO_LIBRARY
|
||||
delete coreappdata()->app_libpaths;
|
||||
coreappdata()->app_libpaths = 0;
|
||||
delete coreappdata()->manual_libpaths;
|
||||
coreappdata()->manual_libpaths = 0;
|
||||
coreappdata()->app_libpaths.reset();
|
||||
coreappdata()->manual_libpaths.reset();
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -2540,7 +2528,8 @@ QStringList QCoreApplication::libraryPaths()
|
||||
return *(coreappdata()->manual_libpaths);
|
||||
|
||||
if (!coreappdata()->app_libpaths) {
|
||||
QStringList *app_libpaths = coreappdata()->app_libpaths = new QStringList;
|
||||
QStringList *app_libpaths = new QStringList;
|
||||
coreappdata()->app_libpaths.reset(app_libpaths);
|
||||
|
||||
const QByteArray libPathEnv = qgetenv("QT_PLUGIN_PATH");
|
||||
if (!libPathEnv.isEmpty()) {
|
||||
@ -2592,9 +2581,10 @@ void QCoreApplication::setLibraryPaths(const QStringList &paths)
|
||||
if (!coreappdata()->app_libpaths)
|
||||
libraryPaths();
|
||||
|
||||
if (!coreappdata()->manual_libpaths)
|
||||
coreappdata()->manual_libpaths = new QStringList;
|
||||
if (coreappdata()->manual_libpaths)
|
||||
*(coreappdata()->manual_libpaths) = paths;
|
||||
else
|
||||
coreappdata()->manual_libpaths.reset(new QStringList(paths));
|
||||
|
||||
locker.unlock();
|
||||
QFactoryLoader::refreshAll();
|
||||
@ -2626,18 +2616,18 @@ void QCoreApplication::addLibraryPath(const QString &path)
|
||||
|
||||
QMutexLocker locker(libraryPathMutex());
|
||||
|
||||
QStringList *libpaths = coreappdata()->manual_libpaths;
|
||||
QStringList *libpaths = coreappdata()->manual_libpaths.data();
|
||||
if (libpaths) {
|
||||
if (libpaths->contains(canonicalPath))
|
||||
return;
|
||||
} else {
|
||||
// make sure that library paths are initialized
|
||||
libraryPaths();
|
||||
QStringList *app_libpaths = coreappdata()->app_libpaths;
|
||||
QStringList *app_libpaths = coreappdata()->app_libpaths.data();
|
||||
if (app_libpaths->contains(canonicalPath))
|
||||
return;
|
||||
|
||||
libpaths = coreappdata()->manual_libpaths = new QStringList(*app_libpaths);
|
||||
coreappdata()->manual_libpaths.reset(libpaths = new QStringList(*app_libpaths));
|
||||
}
|
||||
|
||||
libpaths->prepend(canonicalPath);
|
||||
@ -2665,18 +2655,18 @@ void QCoreApplication::removeLibraryPath(const QString &path)
|
||||
|
||||
QMutexLocker locker(libraryPathMutex());
|
||||
|
||||
QStringList *libpaths = coreappdata()->manual_libpaths;
|
||||
QStringList *libpaths = coreappdata()->manual_libpaths.data();
|
||||
if (libpaths) {
|
||||
if (libpaths->removeAll(canonicalPath) == 0)
|
||||
return;
|
||||
} else {
|
||||
// make sure that library paths is initialized
|
||||
libraryPaths();
|
||||
QStringList *app_libpaths = coreappdata()->app_libpaths;
|
||||
QStringList *app_libpaths = coreappdata()->app_libpaths.data();
|
||||
if (!app_libpaths->contains(canonicalPath))
|
||||
return;
|
||||
|
||||
libpaths = coreappdata()->manual_libpaths = new QStringList(*app_libpaths);
|
||||
coreappdata()->manual_libpaths.reset(libpaths = new QStringList(*app_libpaths));
|
||||
libpaths->removeAll(canonicalPath);
|
||||
}
|
||||
|
||||
|
@ -40,6 +40,7 @@
|
||||
#include <private/qabstracteventdispatcher_p.h>
|
||||
#include <private/qcoreapplication_p.h>
|
||||
|
||||
#include <functional>
|
||||
#include <wrl.h>
|
||||
#include <windows.foundation.h>
|
||||
#include <windows.system.threading.h>
|
||||
@ -70,6 +71,23 @@ struct WinRTTimerInfo : public QAbstractEventDispatcher::TimerInfo {
|
||||
quint64 targetTime;
|
||||
};
|
||||
|
||||
class AgileDispatchedHandler : public RuntimeClass<RuntimeClassFlags<WinRtClassicComMix>, IDispatchedHandler, IAgileObject>
|
||||
{
|
||||
public:
|
||||
AgileDispatchedHandler(const std::function<HRESULT()> &delegate)
|
||||
: delegate(delegate)
|
||||
{
|
||||
}
|
||||
|
||||
HRESULT __stdcall Invoke()
|
||||
{
|
||||
return delegate();
|
||||
}
|
||||
|
||||
private:
|
||||
std::function<HRESULT()> delegate;
|
||||
};
|
||||
|
||||
class QEventDispatcherWinRTPrivate : public QAbstractEventDispatcherPrivate
|
||||
{
|
||||
Q_DECLARE_PUBLIC(QEventDispatcherWinRT)
|
||||
@ -80,8 +98,6 @@ public:
|
||||
|
||||
private:
|
||||
ComPtr<IThreadPoolTimerStatics> timerFactory;
|
||||
ComPtr<ICoreDispatcher> coreDispatcher;
|
||||
QPointer<QThread> thread;
|
||||
|
||||
QHash<int, QObject *> timerIdToObject;
|
||||
QVector<WinRTTimerInfo> timerInfos;
|
||||
@ -136,40 +152,11 @@ private:
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void fetchCoreDispatcher()
|
||||
{
|
||||
ComPtr<ICoreImmersiveApplication> application;
|
||||
HRESULT hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_ApplicationModel_Core_CoreApplication).Get(),
|
||||
IID_PPV_ARGS(&application));
|
||||
RETURN_VOID_IF_FAILED("Failed to get the application factory");
|
||||
|
||||
static ComPtr<ICoreApplicationView> view;
|
||||
if (view)
|
||||
return;
|
||||
|
||||
hr = application->get_MainView(&view);
|
||||
RETURN_VOID_IF_FAILED("Failed to get the main view");
|
||||
|
||||
ComPtr<ICoreApplicationView2> view2;
|
||||
hr = view.As(&view2);
|
||||
RETURN_VOID_IF_FAILED("Failed to cast the main view");
|
||||
|
||||
hr = view2->get_Dispatcher(&coreDispatcher);
|
||||
if (hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND)) // expected in thread pool cases
|
||||
return;
|
||||
RETURN_VOID_IF_FAILED("Failed to get core dispatcher");
|
||||
|
||||
thread = QThread::currentThread();
|
||||
}
|
||||
};
|
||||
|
||||
QEventDispatcherWinRT::QEventDispatcherWinRT(QObject *parent)
|
||||
: QAbstractEventDispatcher(*new QEventDispatcherWinRTPrivate, parent)
|
||||
{
|
||||
Q_D(QEventDispatcherWinRT);
|
||||
|
||||
d->fetchCoreDispatcher();
|
||||
}
|
||||
|
||||
QEventDispatcherWinRT::QEventDispatcherWinRT(QEventDispatcherWinRTPrivate &dd, QObject *parent)
|
||||
@ -180,25 +167,43 @@ QEventDispatcherWinRT::~QEventDispatcherWinRT()
|
||||
{
|
||||
}
|
||||
|
||||
HRESULT QEventDispatcherWinRT::runOnXamlThread(const std::function<HRESULT ()> &delegate)
|
||||
{
|
||||
static __declspec(thread) ICoreDispatcher *dispatcher = nullptr;
|
||||
if (!dispatcher) {
|
||||
HRESULT hr;
|
||||
ComPtr<ICoreImmersiveApplication> application;
|
||||
hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_ApplicationModel_Core_CoreApplication).Get(),
|
||||
IID_PPV_ARGS(&application));
|
||||
ComPtr<ICoreApplicationView> view;
|
||||
hr = application->get_MainView(&view);
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
ComPtr<ICoreWindow> window;
|
||||
hr = view->get_CoreWindow(&window);
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
hr = window->get_Dispatcher(&dispatcher);
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
}
|
||||
|
||||
HRESULT hr;
|
||||
boolean onXamlThread;
|
||||
hr = dispatcher->get_HasThreadAccess(&onXamlThread);
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
if (onXamlThread) // Already there
|
||||
return delegate();
|
||||
|
||||
ComPtr<IAsyncAction> op;
|
||||
hr = dispatcher->RunAsync(CoreDispatcherPriority_Normal, Make<AgileDispatchedHandler>(delegate).Get(), &op);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
return QWinRTFunctions::await(op);
|
||||
}
|
||||
|
||||
bool QEventDispatcherWinRT::processEvents(QEventLoop::ProcessEventsFlags flags)
|
||||
{
|
||||
Q_D(QEventDispatcherWinRT);
|
||||
|
||||
if (d->thread && d->thread != QThread::currentThread())
|
||||
d->fetchCoreDispatcher();
|
||||
|
||||
do {
|
||||
// Process native events
|
||||
if (d->coreDispatcher) {
|
||||
boolean hasThreadAccess;
|
||||
HRESULT hr = d->coreDispatcher->get_HasThreadAccess(&hasThreadAccess);
|
||||
if (SUCCEEDED(hr) && hasThreadAccess) {
|
||||
hr = d->coreDispatcher->ProcessEvents(CoreProcessEventsOption_ProcessAllIfPresent);
|
||||
if (FAILED(hr))
|
||||
qErrnoWarning(hr, "Failed to process events");
|
||||
}
|
||||
}
|
||||
|
||||
// Additional user events have to be handled before timer events, but the function may not
|
||||
// return yet.
|
||||
const bool userEventsSent = sendPostedEvents(flags);
|
||||
@ -284,9 +289,10 @@ void QEventDispatcherWinRT::registerTimer(int timerId, int interval, Qt::TimerTy
|
||||
|
||||
TimeSpan period;
|
||||
period.Duration = interval ? (interval * 10000) : 1; // TimeSpan is based on 100-nanosecond units
|
||||
IThreadPoolTimer *timer;
|
||||
const HANDLE handle = CreateEventEx(NULL, NULL, CREATE_EVENT_MANUAL_RESET, SYNCHRONIZE | EVENT_MODIFY_STATE);
|
||||
const HANDLE cancelHandle = CreateEventEx(NULL, NULL, CREATE_EVENT_MANUAL_RESET, SYNCHRONIZE|EVENT_MODIFY_STATE);
|
||||
HRESULT hr = runOnXamlThread([&]() {
|
||||
IThreadPoolTimer *timer;
|
||||
HRESULT hr = d->timerFactory->CreatePeriodicTimerWithCompletion(
|
||||
Callback<ITimerElapsedHandler>([handle, cancelHandle](IThreadPoolTimer *timer) {
|
||||
DWORD cancelResult = WaitForSingleObjectEx(cancelHandle, 0, TRUE);
|
||||
@ -306,13 +312,15 @@ void QEventDispatcherWinRT::registerTimer(int timerId, int interval, Qt::TimerTy
|
||||
CloseHandle(cancelHandle);
|
||||
return S_OK;
|
||||
}).Get(), &timer);
|
||||
RETURN_HR_IF_FAILED("Failed to create periodic timer");
|
||||
|
||||
d->addTimer(timerId, interval, timerType, object, handle, cancelHandle);
|
||||
return hr;
|
||||
});
|
||||
if (FAILED(hr)) {
|
||||
qErrnoWarning(hr, "Failed to create periodic timer");
|
||||
CloseHandle(handle);
|
||||
CloseHandle(cancelHandle);
|
||||
return;
|
||||
}
|
||||
d->addTimer(timerId, interval, timerType, object, handle, cancelHandle);
|
||||
}
|
||||
|
||||
bool QEventDispatcherWinRT::unregisterTimer(int timerId)
|
||||
|
@ -50,6 +50,8 @@
|
||||
|
||||
#include <qt_windows.h>
|
||||
|
||||
namespace std { template <typename T> class function; }
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
quint64 qt_msectime();
|
||||
@ -65,6 +67,8 @@ public:
|
||||
explicit QEventDispatcherWinRT(QObject *parent = 0);
|
||||
~QEventDispatcherWinRT();
|
||||
|
||||
static HRESULT runOnXamlThread(const std::function<HRESULT()> &delegate);
|
||||
|
||||
bool processEvents(QEventLoop::ProcessEventsFlags flags);
|
||||
bool hasPendingEvents();
|
||||
|
||||
|
@ -46,13 +46,6 @@ QT_END_NAMESPACE
|
||||
#pragma qt_sync_stop_processing
|
||||
#endif
|
||||
|
||||
#ifdef Q_CC_GNU
|
||||
// lowercase is fine, we'll undef it below
|
||||
#define always_inline __attribute__((always_inline, gnu_inline))
|
||||
#else
|
||||
#define always_inline
|
||||
#endif
|
||||
|
||||
template<int> struct QAtomicOpsSupport { enum { IsSupported = 0 }; };
|
||||
template<> struct QAtomicOpsSupport<4> { enum { IsSupported = 1 }; };
|
||||
|
||||
@ -84,19 +77,19 @@ template <typename BaseClass> struct QGenericAtomicOps
|
||||
{
|
||||
}
|
||||
|
||||
template <typename T> static inline always_inline
|
||||
template <typename T> static Q_ALWAYS_INLINE
|
||||
T load(const T &_q_value) Q_DECL_NOTHROW
|
||||
{
|
||||
return _q_value;
|
||||
}
|
||||
|
||||
template <typename T, typename X> static inline always_inline
|
||||
template <typename T, typename X> static Q_ALWAYS_INLINE
|
||||
void store(T &_q_value, X newValue) Q_DECL_NOTHROW
|
||||
{
|
||||
_q_value = newValue;
|
||||
}
|
||||
|
||||
template <typename T> static inline always_inline
|
||||
template <typename T> static Q_ALWAYS_INLINE
|
||||
T loadAcquire(const T &_q_value) Q_DECL_NOTHROW
|
||||
{
|
||||
T tmp = *static_cast<const volatile T *>(&_q_value);
|
||||
@ -104,7 +97,7 @@ template <typename BaseClass> struct QGenericAtomicOps
|
||||
return tmp;
|
||||
}
|
||||
|
||||
template <typename T, typename X> static inline always_inline
|
||||
template <typename T, typename X> static Q_ALWAYS_INLINE
|
||||
void storeRelease(T &_q_value, X newValue) Q_DECL_NOTHROW
|
||||
{
|
||||
BaseClass::releaseMemoryFence(_q_value);
|
||||
@ -115,13 +108,13 @@ template <typename BaseClass> struct QGenericAtomicOps
|
||||
{ return BaseClass::isFetchAndAddNative(); }
|
||||
static inline Q_DECL_CONSTEXPR bool isReferenceCountingWaitFree() Q_DECL_NOTHROW
|
||||
{ return BaseClass::isFetchAndAddWaitFree(); }
|
||||
template <typename T> static inline always_inline
|
||||
template <typename T> static Q_ALWAYS_INLINE
|
||||
bool ref(T &_q_value) Q_DECL_NOTHROW
|
||||
{
|
||||
return BaseClass::fetchAndAddRelaxed(_q_value, 1) != T(-1);
|
||||
}
|
||||
|
||||
template <typename T> static inline always_inline
|
||||
template <typename T> static Q_ALWAYS_INLINE
|
||||
bool deref(T &_q_value) Q_DECL_NOTHROW
|
||||
{
|
||||
return BaseClass::fetchAndAddRelaxed(_q_value, -1) != 1;
|
||||
@ -138,7 +131,7 @@ template <typename BaseClass> struct QGenericAtomicOps
|
||||
bool testAndSetRelaxed(T &_q_value, X expectedValue, X newValue, X *currentValue) Q_DECL_NOTHROW;
|
||||
#endif
|
||||
|
||||
template <typename T, typename X> static inline always_inline
|
||||
template <typename T, typename X> static Q_ALWAYS_INLINE
|
||||
bool testAndSetAcquire(T &_q_value, X expectedValue, X newValue) Q_DECL_NOTHROW
|
||||
{
|
||||
bool tmp = BaseClass::testAndSetRelaxed(_q_value, expectedValue, newValue);
|
||||
@ -146,21 +139,21 @@ template <typename BaseClass> struct QGenericAtomicOps
|
||||
return tmp;
|
||||
}
|
||||
|
||||
template <typename T, typename X> static inline always_inline
|
||||
template <typename T, typename X> static Q_ALWAYS_INLINE
|
||||
bool testAndSetRelease(T &_q_value, X expectedValue, X newValue) Q_DECL_NOTHROW
|
||||
{
|
||||
BaseClass::releaseMemoryFence(_q_value);
|
||||
return BaseClass::testAndSetRelaxed(_q_value, expectedValue, newValue);
|
||||
}
|
||||
|
||||
template <typename T, typename X> static inline always_inline
|
||||
template <typename T, typename X> static Q_ALWAYS_INLINE
|
||||
bool testAndSetOrdered(T &_q_value, X expectedValue, X newValue) Q_DECL_NOTHROW
|
||||
{
|
||||
BaseClass::orderedMemoryFence(_q_value);
|
||||
return BaseClass::testAndSetRelaxed(_q_value, expectedValue, newValue);
|
||||
}
|
||||
|
||||
template <typename T, typename X> static inline always_inline
|
||||
template <typename T, typename X> static Q_ALWAYS_INLINE
|
||||
bool testAndSetAcquire(T &_q_value, X expectedValue, X newValue, X *currentValue) Q_DECL_NOTHROW
|
||||
{
|
||||
bool tmp = BaseClass::testAndSetRelaxed(_q_value, expectedValue, newValue, currentValue);
|
||||
@ -168,14 +161,14 @@ template <typename BaseClass> struct QGenericAtomicOps
|
||||
return tmp;
|
||||
}
|
||||
|
||||
template <typename T, typename X> static inline always_inline
|
||||
template <typename T, typename X> static Q_ALWAYS_INLINE
|
||||
bool testAndSetRelease(T &_q_value, X expectedValue, X newValue, X *currentValue) Q_DECL_NOTHROW
|
||||
{
|
||||
BaseClass::releaseMemoryFence(_q_value);
|
||||
return BaseClass::testAndSetRelaxed(_q_value, expectedValue, newValue, currentValue);
|
||||
}
|
||||
|
||||
template <typename T, typename X> static inline always_inline
|
||||
template <typename T, typename X> static Q_ALWAYS_INLINE
|
||||
bool testAndSetOrdered(T &_q_value, X expectedValue, X newValue, X *currentValue) Q_DECL_NOTHROW
|
||||
{
|
||||
BaseClass::orderedMemoryFence(_q_value);
|
||||
@ -185,7 +178,7 @@ template <typename BaseClass> struct QGenericAtomicOps
|
||||
static inline Q_DECL_CONSTEXPR bool isFetchAndStoreNative() Q_DECL_NOTHROW { return false; }
|
||||
static inline Q_DECL_CONSTEXPR bool isFetchAndStoreWaitFree() Q_DECL_NOTHROW { return false; }
|
||||
|
||||
template <typename T, typename X> static inline always_inline
|
||||
template <typename T, typename X> static Q_ALWAYS_INLINE
|
||||
T fetchAndStoreRelaxed(T &_q_value, X newValue) Q_DECL_NOTHROW
|
||||
{
|
||||
// implement fetchAndStore on top of testAndSet
|
||||
@ -196,7 +189,7 @@ template <typename BaseClass> struct QGenericAtomicOps
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, typename X> static inline always_inline
|
||||
template <typename T, typename X> static Q_ALWAYS_INLINE
|
||||
T fetchAndStoreAcquire(T &_q_value, X newValue) Q_DECL_NOTHROW
|
||||
{
|
||||
T tmp = BaseClass::fetchAndStoreRelaxed(_q_value, newValue);
|
||||
@ -204,14 +197,14 @@ template <typename BaseClass> struct QGenericAtomicOps
|
||||
return tmp;
|
||||
}
|
||||
|
||||
template <typename T, typename X> static inline always_inline
|
||||
template <typename T, typename X> static Q_ALWAYS_INLINE
|
||||
T fetchAndStoreRelease(T &_q_value, X newValue) Q_DECL_NOTHROW
|
||||
{
|
||||
BaseClass::releaseMemoryFence(_q_value);
|
||||
return BaseClass::fetchAndStoreRelaxed(_q_value, newValue);
|
||||
}
|
||||
|
||||
template <typename T, typename X> static inline always_inline
|
||||
template <typename T, typename X> static Q_ALWAYS_INLINE
|
||||
T fetchAndStoreOrdered(T &_q_value, X newValue) Q_DECL_NOTHROW
|
||||
{
|
||||
BaseClass::orderedMemoryFence(_q_value);
|
||||
@ -220,7 +213,7 @@ template <typename BaseClass> struct QGenericAtomicOps
|
||||
|
||||
static inline Q_DECL_CONSTEXPR bool isFetchAndAddNative() Q_DECL_NOTHROW { return false; }
|
||||
static inline Q_DECL_CONSTEXPR bool isFetchAndAddWaitFree() Q_DECL_NOTHROW { return false; }
|
||||
template <typename T> static inline always_inline
|
||||
template <typename T> static Q_ALWAYS_INLINE
|
||||
T fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
|
||||
{
|
||||
// implement fetchAndAdd on top of testAndSet
|
||||
@ -231,7 +224,7 @@ template <typename BaseClass> struct QGenericAtomicOps
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T> static inline always_inline
|
||||
template <typename T> static Q_ALWAYS_INLINE
|
||||
T fetchAndAddAcquire(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
|
||||
{
|
||||
T tmp = BaseClass::fetchAndAddRelaxed(_q_value, valueToAdd);
|
||||
@ -239,28 +232,28 @@ template <typename BaseClass> struct QGenericAtomicOps
|
||||
return tmp;
|
||||
}
|
||||
|
||||
template <typename T> static inline always_inline
|
||||
template <typename T> static Q_ALWAYS_INLINE
|
||||
T fetchAndAddRelease(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
|
||||
{
|
||||
BaseClass::releaseMemoryFence(_q_value);
|
||||
return BaseClass::fetchAndAddRelaxed(_q_value, valueToAdd);
|
||||
}
|
||||
|
||||
template <typename T> static inline always_inline
|
||||
template <typename T> static Q_ALWAYS_INLINE
|
||||
T fetchAndAddOrdered(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
|
||||
{
|
||||
BaseClass::orderedMemoryFence(_q_value);
|
||||
return BaseClass::fetchAndAddRelaxed(_q_value, valueToAdd);
|
||||
}
|
||||
|
||||
template <typename T> static inline always_inline
|
||||
template <typename T> static Q_ALWAYS_INLINE
|
||||
T fetchAndSubRelaxed(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT operand) Q_DECL_NOTHROW
|
||||
{
|
||||
// implement fetchAndSub on top of fetchAndAdd
|
||||
return fetchAndAddRelaxed(_q_value, -operand);
|
||||
}
|
||||
|
||||
template <typename T> static inline always_inline
|
||||
template <typename T> static Q_ALWAYS_INLINE
|
||||
T fetchAndSubAcquire(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT operand) Q_DECL_NOTHROW
|
||||
{
|
||||
T tmp = BaseClass::fetchAndSubRelaxed(_q_value, operand);
|
||||
@ -268,21 +261,21 @@ template <typename BaseClass> struct QGenericAtomicOps
|
||||
return tmp;
|
||||
}
|
||||
|
||||
template <typename T> static inline always_inline
|
||||
template <typename T> static Q_ALWAYS_INLINE
|
||||
T fetchAndSubRelease(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT operand) Q_DECL_NOTHROW
|
||||
{
|
||||
BaseClass::releaseMemoryFence(_q_value);
|
||||
return BaseClass::fetchAndSubRelaxed(_q_value, operand);
|
||||
}
|
||||
|
||||
template <typename T> static inline always_inline
|
||||
template <typename T> static Q_ALWAYS_INLINE
|
||||
T fetchAndSubOrdered(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT operand) Q_DECL_NOTHROW
|
||||
{
|
||||
BaseClass::orderedMemoryFence(_q_value);
|
||||
return BaseClass::fetchAndSubRelaxed(_q_value, operand);
|
||||
}
|
||||
|
||||
template <typename T> static inline always_inline
|
||||
template <typename T> static Q_ALWAYS_INLINE
|
||||
T fetchAndAndRelaxed(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW
|
||||
{
|
||||
// implement fetchAndAnd on top of testAndSet
|
||||
@ -293,7 +286,7 @@ template <typename BaseClass> struct QGenericAtomicOps
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T> static inline always_inline
|
||||
template <typename T> static Q_ALWAYS_INLINE
|
||||
T fetchAndAndAcquire(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW
|
||||
{
|
||||
T tmp = BaseClass::fetchAndAndRelaxed(_q_value, operand);
|
||||
@ -301,21 +294,21 @@ template <typename BaseClass> struct QGenericAtomicOps
|
||||
return tmp;
|
||||
}
|
||||
|
||||
template <typename T> static inline always_inline
|
||||
template <typename T> static Q_ALWAYS_INLINE
|
||||
T fetchAndAndRelease(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW
|
||||
{
|
||||
BaseClass::releaseMemoryFence(_q_value);
|
||||
return BaseClass::fetchAndAndRelaxed(_q_value, operand);
|
||||
}
|
||||
|
||||
template <typename T> static inline always_inline
|
||||
template <typename T> static Q_ALWAYS_INLINE
|
||||
T fetchAndAndOrdered(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW
|
||||
{
|
||||
BaseClass::orderedMemoryFence(_q_value);
|
||||
return BaseClass::fetchAndAndRelaxed(_q_value, operand);
|
||||
}
|
||||
|
||||
template <typename T> static inline always_inline
|
||||
template <typename T> static Q_ALWAYS_INLINE
|
||||
T fetchAndOrRelaxed(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW
|
||||
{
|
||||
// implement fetchAndOr on top of testAndSet
|
||||
@ -326,7 +319,7 @@ template <typename BaseClass> struct QGenericAtomicOps
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T> static inline always_inline
|
||||
template <typename T> static Q_ALWAYS_INLINE
|
||||
T fetchAndOrAcquire(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW
|
||||
{
|
||||
T tmp = BaseClass::fetchAndOrRelaxed(_q_value, operand);
|
||||
@ -334,21 +327,21 @@ template <typename BaseClass> struct QGenericAtomicOps
|
||||
return tmp;
|
||||
}
|
||||
|
||||
template <typename T> static inline always_inline
|
||||
template <typename T> static Q_ALWAYS_INLINE
|
||||
T fetchAndOrRelease(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW
|
||||
{
|
||||
BaseClass::releaseMemoryFence(_q_value);
|
||||
return BaseClass::fetchAndOrRelaxed(_q_value, operand);
|
||||
}
|
||||
|
||||
template <typename T> static inline always_inline
|
||||
template <typename T> static Q_ALWAYS_INLINE
|
||||
T fetchAndOrOrdered(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW
|
||||
{
|
||||
BaseClass::orderedMemoryFence(_q_value);
|
||||
return BaseClass::fetchAndOrRelaxed(_q_value, operand);
|
||||
}
|
||||
|
||||
template <typename T> static inline always_inline
|
||||
template <typename T> static Q_ALWAYS_INLINE
|
||||
T fetchAndXorRelaxed(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW
|
||||
{
|
||||
// implement fetchAndXor on top of testAndSet
|
||||
@ -359,7 +352,7 @@ template <typename BaseClass> struct QGenericAtomicOps
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T> static inline always_inline
|
||||
template <typename T> static Q_ALWAYS_INLINE
|
||||
T fetchAndXorAcquire(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW
|
||||
{
|
||||
T tmp = BaseClass::fetchAndXorRelaxed(_q_value, operand);
|
||||
@ -367,14 +360,14 @@ template <typename BaseClass> struct QGenericAtomicOps
|
||||
return tmp;
|
||||
}
|
||||
|
||||
template <typename T> static inline always_inline
|
||||
template <typename T> static Q_ALWAYS_INLINE
|
||||
T fetchAndXorRelease(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW
|
||||
{
|
||||
BaseClass::releaseMemoryFence(_q_value);
|
||||
return BaseClass::fetchAndXorRelaxed(_q_value, operand);
|
||||
}
|
||||
|
||||
template <typename T> static inline always_inline
|
||||
template <typename T> static Q_ALWAYS_INLINE
|
||||
T fetchAndXorOrdered(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW
|
||||
{
|
||||
BaseClass::orderedMemoryFence(_q_value);
|
||||
@ -382,7 +375,5 @@ template <typename BaseClass> struct QGenericAtomicOps
|
||||
}
|
||||
};
|
||||
|
||||
#undef always_inline
|
||||
|
||||
QT_END_NAMESPACE
|
||||
#endif // QGENERICATOMIC_H
|
||||
|
@ -2240,7 +2240,7 @@ uint qHash(long double key, uint seed) Q_DECL_NOTHROW
|
||||
Returns a pointer to the current item's key.
|
||||
*/
|
||||
|
||||
/*! \fn bool QHash::key_iterator::operator==(key_iterator other)
|
||||
/*! \fn bool QHash::key_iterator::operator==(key_iterator other) const
|
||||
|
||||
Returns \c true if \a other points to the same item as this
|
||||
iterator; otherwise returns \c false.
|
||||
@ -2248,7 +2248,7 @@ uint qHash(long double key, uint seed) Q_DECL_NOTHROW
|
||||
\sa operator!=()
|
||||
*/
|
||||
|
||||
/*! \fn bool QHash::key_iterator::operator!=(key_iterator other)
|
||||
/*! \fn bool QHash::key_iterator::operator!=(key_iterator other) const
|
||||
|
||||
Returns \c true if \a other points to a different item than this
|
||||
iterator; otherwise returns \c false.
|
||||
|
@ -378,7 +378,7 @@ void **QListData::erase(void **xi)
|
||||
references into a QVector and non-heap-allocating QLists.
|
||||
|
||||
Internally, QList\<T\> is represented as an array of T if
|
||||
If \c{sizeof(T) <= sizeof(void*)} and T has been declared to be
|
||||
\c{sizeof(T) <= sizeof(void*)} and T has been declared to be
|
||||
either a \c{Q_MOVABLE_TYPE} or a \c{Q_PRIMITIVE_TYPE} using
|
||||
\l {Q_DECLARE_TYPEINFO}. Otherwise, QList\<T\> is represented
|
||||
as an array of T* and the items are allocated on the heap.
|
||||
|
@ -1719,7 +1719,7 @@ void QMapDataBase::freeData(QMapDataBase *d)
|
||||
Returns a pointer to the current item's key.
|
||||
*/
|
||||
|
||||
/*! \fn bool QMap::key_iterator::operator==(key_iterator other)
|
||||
/*! \fn bool QMap::key_iterator::operator==(key_iterator other) const
|
||||
|
||||
Returns \c true if \a other points to the same item as this
|
||||
iterator; otherwise returns \c false.
|
||||
@ -1727,7 +1727,7 @@ void QMapDataBase::freeData(QMapDataBase *d)
|
||||
\sa operator!=()
|
||||
*/
|
||||
|
||||
/*! \fn bool QMap::key_iterator::operator!=(key_iterator other)
|
||||
/*! \fn bool QMap::key_iterator::operator!=(key_iterator other) const
|
||||
|
||||
Returns \c true if \a other points to a different item than this
|
||||
iterator; otherwise returns \c false.
|
||||
|
@ -1935,6 +1935,7 @@ void QGuiApplicationPrivate::processKeyEvent(QWindowSystemInterfacePrivate::KeyE
|
||||
}
|
||||
}
|
||||
#endif
|
||||
e->eventAccepted = ev.isAccepted();
|
||||
}
|
||||
|
||||
void QGuiApplicationPrivate::processEnterEvent(QWindowSystemInterfacePrivate::EnterEvent *e)
|
||||
|
@ -689,6 +689,14 @@ QRect QPlatformWindow::windowGeometry() const
|
||||
return QHighDpi::toNativePixels(window()->geometry(), window());
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the QWindow frame geometry.
|
||||
*/
|
||||
QRect QPlatformWindow::windowFrameGeometry() const
|
||||
{
|
||||
return QHighDpi::toNativePixels(window()->frameGeometry(), window());
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the closest acceptable geometry for a given geometry before
|
||||
a resize/move event for platforms that support it, for example to
|
||||
|
@ -138,6 +138,7 @@ public:
|
||||
QSize windowBaseSize() const;
|
||||
QSize windowSizeIncrement() const;
|
||||
QRect windowGeometry() const;
|
||||
QRect windowFrameGeometry() const;
|
||||
QRectF windowClosestAcceptableGeometry(const QRectF &nativeRect) const;
|
||||
|
||||
protected:
|
||||
|
@ -303,24 +303,24 @@ bool QWindowSystemInterface::tryHandleExtendedShortcutEvent(QWindow *w, ulong ti
|
||||
}
|
||||
|
||||
|
||||
void QWindowSystemInterface::handleKeyEvent(QWindow *w, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text, bool autorep, ushort count) {
|
||||
bool QWindowSystemInterface::handleKeyEvent(QWindow *w, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text, bool autorep, ushort count) {
|
||||
unsigned long time = QWindowSystemInterfacePrivate::eventTime.elapsed();
|
||||
handleKeyEvent(w, time, t, k, mods, text, autorep, count);
|
||||
return handleKeyEvent(w, time, t, k, mods, text, autorep, count);
|
||||
}
|
||||
|
||||
void QWindowSystemInterface::handleKeyEvent(QWindow *tlw, ulong timestamp, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text, bool autorep, ushort count)
|
||||
bool QWindowSystemInterface::handleKeyEvent(QWindow *tlw, ulong timestamp, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text, bool autorep, ushort count)
|
||||
{
|
||||
// This is special handling needed for OS X which eventually will call sendEvent(), on other platforms
|
||||
// this might not be safe, e.g., on Android. See: QGuiApplicationPrivate::processKeyEvent() for
|
||||
// shortcut overriding on other platforms.
|
||||
#if defined(Q_OS_OSX)
|
||||
if (t == QEvent::KeyPress && QWindowSystemInterface::tryHandleShortcutEvent(tlw, timestamp, k, mods, text))
|
||||
return;
|
||||
return true;
|
||||
#endif // Q_OS_OSX
|
||||
|
||||
QWindowSystemInterfacePrivate::KeyEvent * e =
|
||||
new QWindowSystemInterfacePrivate::KeyEvent(tlw, timestamp, t, k, mods, text, autorep, count);
|
||||
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
|
||||
return QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
|
||||
}
|
||||
|
||||
void QWindowSystemInterface::handleExtendedKeyEvent(QWindow *w, QEvent::Type type, int key, Qt::KeyboardModifiers modifiers,
|
||||
@ -441,10 +441,12 @@ void QWindowSystemInterfacePrivate::removeWindowSystemEvent(WindowSystemEvent *e
|
||||
windowSystemEventQueue.remove(event);
|
||||
}
|
||||
|
||||
void QWindowSystemInterfacePrivate::handleWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *ev)
|
||||
bool QWindowSystemInterfacePrivate::handleWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *ev)
|
||||
{
|
||||
bool accepted = true;
|
||||
if (synchronousWindowSystemEvents) {
|
||||
QGuiApplicationPrivate::processWindowSystemEvent(ev);
|
||||
accepted = ev->eventAccepted;
|
||||
delete ev;
|
||||
} else {
|
||||
windowSystemEventQueue.append(ev);
|
||||
@ -452,6 +454,7 @@ void QWindowSystemInterfacePrivate::handleWindowSystemEvent(QWindowSystemInterfa
|
||||
if (dispatcher)
|
||||
dispatcher->wakeUp();
|
||||
}
|
||||
return accepted;
|
||||
}
|
||||
|
||||
void QWindowSystemInterface::registerTouchDevice(QTouchDevice *device)
|
||||
@ -611,7 +614,7 @@ void QWindowSystemInterface::deferredFlushWindowSystemEvents(QEventLoop::Process
|
||||
Q_ASSERT(QThread::currentThread() == QGuiApplication::instance()->thread());
|
||||
|
||||
QMutexLocker locker(&QWindowSystemInterfacePrivate::flushEventMutex);
|
||||
flushWindowSystemEvents(flags);
|
||||
sendWindowSystemEvents(flags);
|
||||
QWindowSystemInterfacePrivate::eventsFlushed.wakeOne();
|
||||
}
|
||||
|
||||
|
@ -95,8 +95,8 @@ public:
|
||||
quint32 nativeScanCode, quint32 nativeVirtualKey, quint32 nativeModifiers,
|
||||
const QString & text = QString(), bool autorep = false, ushort count = 1);
|
||||
|
||||
static void handleKeyEvent(QWindow *w, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text = QString(), bool autorep = false, ushort count = 1);
|
||||
static void handleKeyEvent(QWindow *w, ulong timestamp, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text = QString(), bool autorep = false, ushort count = 1);
|
||||
static bool handleKeyEvent(QWindow *w, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text = QString(), bool autorep = false, ushort count = 1);
|
||||
static bool handleKeyEvent(QWindow *w, ulong timestamp, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text = QString(), bool autorep = false, ushort count = 1);
|
||||
|
||||
static void handleExtendedKeyEvent(QWindow *w, QEvent::Type type, int key, Qt::KeyboardModifiers modifiers,
|
||||
quint32 nativeScanCode, quint32 nativeVirtualKey,
|
||||
|
@ -101,7 +101,7 @@ public:
|
||||
};
|
||||
|
||||
explicit WindowSystemEvent(EventType t)
|
||||
: type(t), flags(0) { }
|
||||
: type(t), flags(0), eventAccepted(true) { }
|
||||
virtual ~WindowSystemEvent() { }
|
||||
|
||||
bool synthetic() const { return flags & Synthetic; }
|
||||
@ -109,6 +109,7 @@ public:
|
||||
|
||||
EventType type;
|
||||
int flags;
|
||||
bool eventAccepted;
|
||||
};
|
||||
|
||||
class CloseEvent : public WindowSystemEvent {
|
||||
@ -480,7 +481,7 @@ public:
|
||||
static WindowSystemEvent *getNonUserInputWindowSystemEvent();
|
||||
static WindowSystemEvent *peekWindowSystemEvent(EventType t);
|
||||
static void removeWindowSystemEvent(WindowSystemEvent *event);
|
||||
static void handleWindowSystemEvent(WindowSystemEvent *ev);
|
||||
static bool handleWindowSystemEvent(WindowSystemEvent *ev);
|
||||
|
||||
static QElapsedTimer eventTime;
|
||||
static bool synchronousWindowSystemEvents;
|
||||
|
@ -182,7 +182,8 @@ void QBackingStore::beginPaint(const QRegion ®ion)
|
||||
qCDebug(lcScaling) << "QBackingStore::beginPaint new backingstore for" << d_ptr->window;
|
||||
qCDebug(lcScaling) << " source size" << source->size() << "dpr" << source->devicePixelRatio();
|
||||
d_ptr->highDpiBackingstore.reset(
|
||||
new QImage(source->bits(), source->width(), source->height(), source->format()));
|
||||
new QImage(source->bits(), source->width(), source->height(), source->bytesPerLine(), source->format()));
|
||||
|
||||
qreal targetDevicePixelRatio = d_ptr->window->devicePixelRatio();
|
||||
d_ptr->highDpiBackingstore->setDevicePixelRatio(targetDevicePixelRatio);
|
||||
qCDebug(lcScaling) <<" destination size" << d_ptr->highDpiBackingstore->size()
|
||||
|
@ -395,169 +395,6 @@ void qt_blend_rgb32_on_rgb32(uchar *destPixels, int dbpl,
|
||||
}
|
||||
}
|
||||
|
||||
template<QtPixelOrder PixelOrder>
|
||||
static void qt_blend_argb32pm_on_a2rgb30pm(uchar *destPixels, int dbpl,
|
||||
const uchar *srcPixels, int sbpl,
|
||||
int w, int h,
|
||||
int const_alpha)
|
||||
{
|
||||
#ifdef QT_DEBUG_DRAW
|
||||
fprintf(stdout, "qt_blend_argb32pm_on_a2rgb30pm: dst=(%p, %d), src=(%p, %d), dim=(%d, %d) alpha=%d\n",
|
||||
destPixels, dbpl, srcPixels, sbpl, w, h, const_alpha);
|
||||
fflush(stdout);
|
||||
#endif
|
||||
|
||||
const uint *src = (const uint *) srcPixels;
|
||||
uint *dst = (uint *) destPixels;
|
||||
if (const_alpha == 256) {
|
||||
for (int y=0; y<h; ++y) {
|
||||
for (int x=0; x<w; ++x) {
|
||||
uint s = src[x];
|
||||
dst[x] = qConvertArgb32ToA2rgb30<PixelOrder>(s) + BYTE_MUL_RGB30(dst[x], 255 - qAlpha(s));
|
||||
}
|
||||
dst = (quint32 *)(((uchar *) dst) + dbpl);
|
||||
src = (const quint32 *)(((const uchar *) src) + sbpl);
|
||||
}
|
||||
} else if (const_alpha != 0) {
|
||||
const_alpha = (const_alpha * 255) >> 8;
|
||||
for (int y=0; y<h; ++y) {
|
||||
for (int x=0; x<w; ++x) {
|
||||
uint s = src[x];
|
||||
dst[x] = BYTE_MUL_RGB30(qConvertArgb32ToA2rgb30<PixelOrder>(s), const_alpha) + BYTE_MUL_RGB30(dst[x], 255 - qt_div_255(qAlpha(s) * const_alpha));
|
||||
}
|
||||
dst = (quint32 *)(((uchar *) dst) + dbpl);
|
||||
src = (const quint32 *)(((const uchar *) src) + sbpl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<QtPixelOrder PixelOrder>
|
||||
static void qt_blend_rgb32_on_rgb30(uchar *destPixels, int dbpl,
|
||||
const uchar *srcPixels, int sbpl,
|
||||
int w, int h,
|
||||
int const_alpha)
|
||||
{
|
||||
#ifdef QT_DEBUG_DRAW
|
||||
fprintf(stdout, "qt_blend_rgb32_on_rgb30: dst=(%p, %d), src=(%p, %d), dim=(%d, %d) alpha=%d\n",
|
||||
destPixels, dbpl, srcPixels, sbpl, w, h, const_alpha);
|
||||
fflush(stdout);
|
||||
#endif
|
||||
|
||||
if (const_alpha != 256) {
|
||||
qt_blend_argb32pm_on_a2rgb30pm<PixelOrder>(destPixels, dbpl, srcPixels, sbpl, w, h, const_alpha);
|
||||
return;
|
||||
}
|
||||
|
||||
const uint *src = (const uint *) srcPixels;
|
||||
uint *dst = (uint *) destPixels;
|
||||
for (int y = 0; y < h; ++y) {
|
||||
for (int x = 0; x < w; ++x) {
|
||||
dst[x] = qConvertRgb32ToRgb30<PixelOrder>(src[x]);
|
||||
}
|
||||
dst = (quint32 *)(((uchar *) dst) + dbpl);
|
||||
src = (const quint32 *)(((const uchar *) src) + sbpl);
|
||||
}
|
||||
}
|
||||
|
||||
static void qt_blend_a2rgb30pm_on_a2rgb30pm(uchar *destPixels, int dbpl,
|
||||
const uchar *srcPixels, int sbpl,
|
||||
int w, int h,
|
||||
int const_alpha)
|
||||
{
|
||||
#ifdef QT_DEBUG_DRAW
|
||||
fprintf(stdout, "qt_blend_a2rgb30pm_on_a2rgb30pm: dst=(%p, %d), src=(%p, %d), dim=(%d, %d) alpha=%d\n",
|
||||
destPixels, dbpl, srcPixels, sbpl, w, h, const_alpha);
|
||||
fflush(stdout);
|
||||
#endif
|
||||
|
||||
const uint *src = (const uint *) srcPixels;
|
||||
uint *dst = (uint *) destPixels;
|
||||
if (const_alpha == 256) {
|
||||
for (int y=0; y<h; ++y) {
|
||||
for (int x=0; x<w; ++x) {
|
||||
uint s = src[x];
|
||||
dst[x] = s + BYTE_MUL_RGB30(dst[x], 255 - qAlphaRgb30(s));
|
||||
}
|
||||
dst = (quint32 *)(((uchar *) dst) + dbpl);
|
||||
src = (const quint32 *)(((const uchar *) src) + sbpl);
|
||||
}
|
||||
} else if (const_alpha != 0) {
|
||||
const uint const_alpha255 = (const_alpha * 255) >> 8;
|
||||
for (int y=0; y<h; ++y) {
|
||||
for (int x=0; x<w; ++x) {
|
||||
uint a = (qAlphaRgb30(src[x]) * const_alpha) >> 8;
|
||||
uint s = BYTE_MUL_RGB30(src[x], const_alpha255);
|
||||
dst[x] = s + BYTE_MUL_RGB30(dst[x], 255 - a);
|
||||
}
|
||||
dst = (quint32 *)(((uchar *) dst) + dbpl);
|
||||
src = (const quint32 *)(((const uchar *) src) + sbpl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void qt_blend_rgb30_on_rgb30(uchar *destPixels, int dbpl,
|
||||
const uchar *srcPixels, int sbpl,
|
||||
int w, int h,
|
||||
int const_alpha)
|
||||
{
|
||||
#ifdef QT_DEBUG_DRAW
|
||||
fprintf(stdout, "qt_blend_rgb30_on_rgb30: dst=(%p, %d), src=(%p, %d), dim=(%d, %d) alpha=%d\n",
|
||||
destPixels, dbpl, srcPixels, sbpl, w, h, const_alpha);
|
||||
fflush(stdout);
|
||||
#endif
|
||||
|
||||
if (const_alpha != 256) {
|
||||
qt_blend_a2rgb30pm_on_a2rgb30pm(destPixels, dbpl, srcPixels, sbpl, w, h, const_alpha);
|
||||
return;
|
||||
}
|
||||
|
||||
const uint *src = (const uint *) srcPixels;
|
||||
uint *dst = (uint *) destPixels;
|
||||
int len = w * 4;
|
||||
for (int y=0; y<h; ++y) {
|
||||
memcpy(dst, src, len);
|
||||
dst = (quint32 *)(((uchar *) dst) + dbpl);
|
||||
src = (const quint32 *)(((const uchar *) src) + sbpl);
|
||||
}
|
||||
}
|
||||
|
||||
static void qt_blend_a2bgr30pm_on_a2rgb30pm(uchar *destPixels, int dbpl,
|
||||
const uchar *srcPixels, int sbpl,
|
||||
int w, int h,
|
||||
int const_alpha)
|
||||
{
|
||||
#ifdef QT_DEBUG_DRAW
|
||||
fprintf(stdout, "qt_blend_a2bgr30pm_on_a2rgb32pm: dst=(%p, %d), src=(%p, %d), dim=(%d, %d) alpha=%d\n",
|
||||
destPixels, dbpl, srcPixels, sbpl, w, h, const_alpha);
|
||||
fflush(stdout);
|
||||
#endif
|
||||
|
||||
const uint *src = (const uint *) srcPixels;
|
||||
uint *dst = (uint *) destPixels;
|
||||
if (const_alpha == 256) {
|
||||
for (int y=0; y<h; ++y) {
|
||||
for (int x=0; x<w; ++x) {
|
||||
uint s = qRgbSwapRgb30(src[x]);
|
||||
dst[x] = s + BYTE_MUL_RGB30(dst[x], 255 - qAlphaRgb30(s));
|
||||
}
|
||||
dst = (quint32 *)(((uchar *) dst) + dbpl);
|
||||
src = (const quint32 *)(((const uchar *) src) + sbpl);
|
||||
}
|
||||
} else if (const_alpha != 0) {
|
||||
const uint const_alpha255 = (const_alpha * 255) >> 8;
|
||||
for (int y=0; y<h; ++y) {
|
||||
for (int x=0; x<w; ++x) {
|
||||
uint a = (qAlphaRgb30(src[x]) * const_alpha) >> 8;
|
||||
uint s = BYTE_MUL_RGB30(src[x], const_alpha255);
|
||||
dst[x] = qRgbSwapRgb30(s) + BYTE_MUL_RGB30(dst[x], 255 - a);
|
||||
}
|
||||
dst = (quint32 *)(((uchar *) dst) + dbpl);
|
||||
src = (const quint32 *)(((const uchar *) src) + sbpl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct Blend_RGB32_on_RGB32_NoAlpha {
|
||||
inline void write(quint32 *dst, quint32 src) { *dst = src; }
|
||||
|
||||
@ -772,30 +609,6 @@ void qInitBlendFunctions()
|
||||
qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32;
|
||||
qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32;
|
||||
#endif
|
||||
qBlendFunctions[QImage::Format_BGR30][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb30<PixelOrderBGR>;
|
||||
qBlendFunctions[QImage::Format_BGR30][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32pm_on_a2rgb30pm<PixelOrderBGR>;
|
||||
qBlendFunctions[QImage::Format_BGR30][QImage::Format_BGR30] = qt_blend_rgb30_on_rgb30;
|
||||
qBlendFunctions[QImage::Format_BGR30][QImage::Format_A2BGR30_Premultiplied] = qt_blend_a2rgb30pm_on_a2rgb30pm;
|
||||
qBlendFunctions[QImage::Format_BGR30][QImage::Format_RGB30] = qt_blend_a2bgr30pm_on_a2rgb30pm;
|
||||
qBlendFunctions[QImage::Format_BGR30][QImage::Format_A2RGB30_Premultiplied] = qt_blend_a2bgr30pm_on_a2rgb30pm;
|
||||
qBlendFunctions[QImage::Format_A2BGR30_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb30<PixelOrderBGR>;
|
||||
qBlendFunctions[QImage::Format_A2BGR30_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32pm_on_a2rgb30pm<PixelOrderBGR>;
|
||||
qBlendFunctions[QImage::Format_A2BGR30_Premultiplied][QImage::Format_BGR30] = qt_blend_rgb30_on_rgb30;
|
||||
qBlendFunctions[QImage::Format_A2BGR30_Premultiplied][QImage::Format_A2BGR30_Premultiplied] = qt_blend_a2rgb30pm_on_a2rgb30pm;
|
||||
qBlendFunctions[QImage::Format_A2BGR30_Premultiplied][QImage::Format_RGB30] = qt_blend_a2bgr30pm_on_a2rgb30pm;
|
||||
qBlendFunctions[QImage::Format_A2BGR30_Premultiplied][QImage::Format_A2RGB30_Premultiplied] = qt_blend_a2bgr30pm_on_a2rgb30pm;
|
||||
qBlendFunctions[QImage::Format_RGB30][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb30<PixelOrderRGB>;
|
||||
qBlendFunctions[QImage::Format_RGB30][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32pm_on_a2rgb30pm<PixelOrderRGB>;
|
||||
qBlendFunctions[QImage::Format_RGB30][QImage::Format_BGR30] = qt_blend_a2bgr30pm_on_a2rgb30pm;
|
||||
qBlendFunctions[QImage::Format_RGB30][QImage::Format_A2BGR30_Premultiplied] = qt_blend_a2bgr30pm_on_a2rgb30pm;
|
||||
qBlendFunctions[QImage::Format_RGB30][QImage::Format_RGB30] = qt_blend_rgb30_on_rgb30;
|
||||
qBlendFunctions[QImage::Format_RGB30][QImage::Format_A2RGB30_Premultiplied] = qt_blend_a2rgb30pm_on_a2rgb30pm;
|
||||
qBlendFunctions[QImage::Format_A2RGB30_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb30<PixelOrderRGB>;
|
||||
qBlendFunctions[QImage::Format_A2RGB30_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32pm_on_a2rgb30pm<PixelOrderRGB>;
|
||||
qBlendFunctions[QImage::Format_A2RGB30_Premultiplied][QImage::Format_BGR30] = qt_blend_a2bgr30pm_on_a2rgb30pm;
|
||||
qBlendFunctions[QImage::Format_A2RGB30_Premultiplied][QImage::Format_A2BGR30_Premultiplied] = qt_blend_a2bgr30pm_on_a2rgb30pm;
|
||||
qBlendFunctions[QImage::Format_A2RGB30_Premultiplied][QImage::Format_RGB30] = qt_blend_rgb30_on_rgb30;
|
||||
qBlendFunctions[QImage::Format_A2RGB30_Premultiplied][QImage::Format_A2RGB30_Premultiplied] = qt_blend_a2rgb30pm_on_a2rgb30pm;
|
||||
|
||||
qTransformFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_transform_image_rgb32_on_rgb32;
|
||||
qTransformFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_transform_image_argb32_on_argb32;
|
||||
|
@ -1252,8 +1252,27 @@ static inline void qConvertARGB64PMToA2RGB30PM_sse2(uint *dest, const QRgba64 *b
|
||||
const __m128i cmask = _mm_set1_epi32(0x000003ff);
|
||||
int i = 0;
|
||||
__m128i vr, vg, vb, va;
|
||||
for (; i < count-1; i += 2) {
|
||||
__m128i vs = _mm_loadu_si128((const __m128i*)buffer);
|
||||
if (i < count && (const uintptr_t)buffer & 0x8) {
|
||||
*dest++ = qConvertRgb64ToRgb30<PixelOrder>(*buffer++);
|
||||
++i;
|
||||
}
|
||||
|
||||
for (; i < count-15; i += 16) {
|
||||
// Repremultiplying is really expensive and hard to do in SIMD without AVX2,
|
||||
// so we try to avoid it by checking if it is needed 16 samples at a time.
|
||||
__m128i vOr = _mm_set1_epi32(0);
|
||||
__m128i vAnd = _mm_set1_epi32(0xffffffff);
|
||||
for (int j = 0; j < 16; j += 2) {
|
||||
__m128i vs = _mm_load_si128((const __m128i*)(buffer + j));
|
||||
vOr = _mm_or_si128(vOr, vs);
|
||||
vAnd = _mm_and_si128(vAnd, vs);
|
||||
}
|
||||
const quint16 orAlpha = ((uint)_mm_extract_epi16(vOr, 3)) | ((uint)_mm_extract_epi16(vOr, 7));
|
||||
const quint16 andAlpha = ((uint)_mm_extract_epi16(vAnd, 3)) & ((uint)_mm_extract_epi16(vAnd, 7));
|
||||
|
||||
if (andAlpha == 0xffff) {
|
||||
for (int j = 0; j < 16; j += 2) {
|
||||
__m128i vs = _mm_load_si128((const __m128i*)buffer);
|
||||
buffer += 2;
|
||||
vr = _mm_srli_epi64(vs, 6);
|
||||
vg = _mm_srli_epi64(vs, 16 + 6 - 10);
|
||||
@ -1272,6 +1291,16 @@ static inline void qConvertARGB64PMToA2RGB30PM_sse2(uint *dest, const QRgba64 *b
|
||||
_mm_storel_epi64((__m128i*)dest, vd);
|
||||
dest += 2;
|
||||
}
|
||||
} else if (orAlpha == 0) {
|
||||
for (int j = 0; j < 16; ++j) {
|
||||
*dest++ = 0;
|
||||
buffer++;
|
||||
}
|
||||
} else {
|
||||
for (int j = 0; j < 16; ++j)
|
||||
*dest++ = qConvertRgb64ToRgb30<PixelOrder>(*buffer++);
|
||||
}
|
||||
}
|
||||
|
||||
for (; i < count; ++i)
|
||||
*dest++ = qConvertRgb64ToRgb30<PixelOrder>(*buffer++);
|
||||
|
@ -62,15 +62,12 @@ QT_BEGIN_NAMESPACE
|
||||
|
||||
#if defined(Q_CC_GNU)
|
||||
# define Q_STATIC_TEMPLATE_FUNCTION static
|
||||
# define Q_ALWAYS_INLINE inline __attribute__((always_inline))
|
||||
# define Q_DECL_RESTRICT __restrict__
|
||||
#elif defined(Q_CC_MSVC)
|
||||
# define Q_STATIC_TEMPLATE_FUNCTION static
|
||||
# define Q_ALWAYS_INLINE __forceinline
|
||||
# define Q_DECL_RESTRICT __restrict
|
||||
#else
|
||||
# define Q_STATIC_TEMPLATE_FUNCTION static
|
||||
# define Q_ALWAYS_INLINE inline
|
||||
# define Q_DECL_RESTRICT
|
||||
#endif
|
||||
|
||||
@ -712,18 +709,6 @@ static Q_ALWAYS_INLINE uint BYTE_MUL_RGB16_32(uint x, uint a) {
|
||||
static Q_DECL_CONSTEXPR Q_ALWAYS_INLINE int qt_div_255(int x) { return (x + (x>>8) + 0x80) >> 8; }
|
||||
static Q_DECL_CONSTEXPR Q_ALWAYS_INLINE uint qt_div_65535(uint x) { return (x + (x>>16) + 0x8000U) >> 16; }
|
||||
|
||||
static Q_ALWAYS_INLINE uint BYTE_MUL_RGB30(uint x, uint a) {
|
||||
uint xa = x >> 30;
|
||||
uint xr = (x >> 20) & 0x3ff;
|
||||
uint xg = (x >> 10) & 0x3ff;
|
||||
uint xb = x & 0x3ff;
|
||||
xa = qt_div_255(xa * a);
|
||||
xr = qt_div_255(xr * a);
|
||||
xg = qt_div_255(xg * a);
|
||||
xb = qt_div_255(xb * a);
|
||||
return (xa << 30) | (xr << 20) | (xg << 10) | xb;
|
||||
}
|
||||
|
||||
static Q_ALWAYS_INLINE uint qAlphaRgb30(uint c)
|
||||
{
|
||||
uint a = c >> 30;
|
||||
@ -897,6 +882,18 @@ inline QRgb qRepremultiply(QRgb p)
|
||||
return qPremultiply(p);
|
||||
}
|
||||
|
||||
template<unsigned int Shift>
|
||||
inline QRgba64 qRepremultiply(QRgba64 p)
|
||||
{
|
||||
const uint alpha = p.alpha();
|
||||
if (alpha == 65535 || alpha == 0)
|
||||
return p;
|
||||
p = p.unpremultiplied();
|
||||
Q_CONSTEXPR uint mult = 65535 / (65535 >> Shift);
|
||||
p.setAlpha(mult * (alpha >> Shift));
|
||||
return p.premultiplied();
|
||||
}
|
||||
|
||||
template<>
|
||||
inline uint qConvertArgb32ToA2rgb30<PixelOrderBGR>(QRgb c)
|
||||
{
|
||||
@ -1000,6 +997,7 @@ template<enum QtPixelOrder> inline unsigned int qConvertRgb64ToRgb30(QRgba64);
|
||||
template<>
|
||||
inline unsigned int qConvertRgb64ToRgb30<PixelOrderBGR>(QRgba64 c)
|
||||
{
|
||||
c = qRepremultiply<14>(c);
|
||||
const uint a = c.alpha() >> 14;
|
||||
const uint r = c.red() >> 6;
|
||||
const uint g = c.green() >> 6;
|
||||
@ -1010,6 +1008,7 @@ inline unsigned int qConvertRgb64ToRgb30<PixelOrderBGR>(QRgba64 c)
|
||||
template<>
|
||||
inline unsigned int qConvertRgb64ToRgb30<PixelOrderRGB>(QRgba64 c)
|
||||
{
|
||||
c = qRepremultiply<14>(c);
|
||||
const uint a = c.alpha() >> 14;
|
||||
const uint r = c.red() >> 6;
|
||||
const uint g = c.green() >> 6;
|
||||
|
@ -40,35 +40,43 @@
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QRgba64 {
|
||||
struct qrgba_t {
|
||||
quint16 red;
|
||||
quint16 green;
|
||||
quint16 blue;
|
||||
quint16 alpha;
|
||||
quint64 rgba;
|
||||
|
||||
// Make sure that the representation always has the order: red green blue alpha, independent
|
||||
// of byte order. This way, vector operations that assume 4 16-bit values see the correct ones.
|
||||
enum {
|
||||
#if Q_BYTE_ORDER == Q_BIG_ENDIAN
|
||||
RedShift = 48,
|
||||
GreenShift = 32,
|
||||
BlueShift = 16,
|
||||
AlphaShift = 0
|
||||
#else // little endian:
|
||||
RedShift = 0,
|
||||
GreenShift = 16,
|
||||
BlueShift = 32,
|
||||
AlphaShift = 48
|
||||
#endif
|
||||
};
|
||||
|
||||
union {
|
||||
struct qrgba_t c;
|
||||
quint64 rgba;
|
||||
};
|
||||
public:
|
||||
// No constructors are allowed, since this needs to be usable in a union in no-c++11 mode.
|
||||
// When c++11 is mandatory, we can add all but a copy constructor.
|
||||
Q_DECL_RELAXED_CONSTEXPR static QRgba64 fromRgba64(quint16 red, quint16 green, quint16 blue, quint16 alpha)
|
||||
Q_DECL_RELAXED_CONSTEXPR static
|
||||
QRgba64 fromRgba64(quint16 red, quint16 green, quint16 blue, quint16 alpha)
|
||||
{
|
||||
QRgba64 rgba64
|
||||
#ifdef Q_COMPILER_UNIFORM_INIT
|
||||
= {}
|
||||
#endif
|
||||
;
|
||||
|
||||
rgba64.c.red = red;
|
||||
rgba64.c.green = green;
|
||||
rgba64.c.blue = blue;
|
||||
rgba64.c.alpha = alpha;
|
||||
rgba64.rgba = quint64(red) << RedShift
|
||||
| quint64(green) << GreenShift
|
||||
| quint64(blue) << BlueShift
|
||||
| quint64(alpha) << AlphaShift;
|
||||
return rgba64;
|
||||
}
|
||||
Q_DECL_RELAXED_CONSTEXPR static QRgba64 fromRgba64(quint64 c)
|
||||
Q_DECL_RELAXED_CONSTEXPR static
|
||||
QRgba64 fromRgba64(quint64 c)
|
||||
{
|
||||
QRgba64 rgba64
|
||||
#ifdef Q_COMPILER_UNIFORM_INIT
|
||||
@ -85,42 +93,49 @@ public:
|
||||
rgb64.rgba |= rgb64.rgba << 8;
|
||||
return rgb64;
|
||||
}
|
||||
Q_DECL_RELAXED_CONSTEXPR static QRgba64 fromArgb32(uint rgb)
|
||||
Q_DECL_RELAXED_CONSTEXPR static
|
||||
QRgba64 fromArgb32(uint rgb)
|
||||
{
|
||||
return fromRgba(rgb >> 16, rgb >> 8, rgb, rgb >> 24);
|
||||
}
|
||||
|
||||
Q_DECL_CONSTEXPR bool isOpaque() const { return c.alpha == 0xffff; }
|
||||
Q_DECL_CONSTEXPR bool isTransparent() const { return c.alpha == 0; }
|
||||
Q_DECL_CONSTEXPR bool isOpaque() const
|
||||
{
|
||||
return (rgba & alphaMask()) == alphaMask();
|
||||
}
|
||||
Q_DECL_CONSTEXPR bool isTransparent() const
|
||||
{
|
||||
return (rgba & alphaMask()) == 0;
|
||||
}
|
||||
|
||||
Q_DECL_CONSTEXPR quint16 red() const { return c.red; }
|
||||
Q_DECL_CONSTEXPR quint16 green() const { return c.green; }
|
||||
Q_DECL_CONSTEXPR quint16 blue() const { return c.blue; }
|
||||
Q_DECL_CONSTEXPR quint16 alpha() const { return c.alpha; }
|
||||
void setRed(quint16 _red) { c.red = _red; }
|
||||
void setGreen(quint16 _green) { c.green = _green; }
|
||||
void setBlue(quint16 _blue) { c.blue = _blue; }
|
||||
void setAlpha(quint16 _alpha) { c.alpha = _alpha; }
|
||||
Q_DECL_CONSTEXPR quint16 red() const { return rgba >> RedShift; }
|
||||
Q_DECL_CONSTEXPR quint16 green() const { return rgba >> GreenShift; }
|
||||
Q_DECL_CONSTEXPR quint16 blue() const { return rgba >> BlueShift; }
|
||||
Q_DECL_CONSTEXPR quint16 alpha() const { return rgba >> AlphaShift; }
|
||||
void setRed(quint16 _red) { *this = fromRgba64(_red, green(), blue(), alpha()); }
|
||||
void setGreen(quint16 _green) { *this = fromRgba64(red(), _green, blue(), alpha()); }
|
||||
void setBlue(quint16 _blue) { *this = fromRgba64(red(), green(), _blue, alpha()); }
|
||||
void setAlpha(quint16 _alpha) { *this = fromRgba64(red(), green(), blue(), _alpha); }
|
||||
|
||||
Q_DECL_CONSTEXPR quint8 red8() const { return div_257(c.red); }
|
||||
Q_DECL_CONSTEXPR quint8 green8() const { return div_257(c.green); }
|
||||
Q_DECL_CONSTEXPR quint8 blue8() const { return div_257(c.blue); }
|
||||
Q_DECL_CONSTEXPR quint8 alpha8() const { return div_257(c.alpha); }
|
||||
Q_DECL_CONSTEXPR quint8 red8() const { return div_257(red()); }
|
||||
Q_DECL_CONSTEXPR quint8 green8() const { return div_257(green()); }
|
||||
Q_DECL_CONSTEXPR quint8 blue8() const { return div_257(blue()); }
|
||||
Q_DECL_CONSTEXPR quint8 alpha8() const { return div_257(alpha()); }
|
||||
Q_DECL_CONSTEXPR uint toArgb32() const
|
||||
{
|
||||
return (alpha8() << 24) | (red8() << 16) | (green8() << 8) | blue8();
|
||||
}
|
||||
Q_DECL_CONSTEXPR ushort toRgb16() const
|
||||
{
|
||||
return (c.red & 0xf800) | ((c.green >> 10) << 5) | (c.blue >> 11);
|
||||
return (red() & 0xf800) | ((green() >> 10) << 5) | (blue() >> 11);
|
||||
}
|
||||
|
||||
Q_DECL_RELAXED_CONSTEXPR QRgba64 premultiplied() const
|
||||
{
|
||||
const quint32 a = c.alpha;
|
||||
const quint16 r = div_65535(c.red * a);
|
||||
const quint16 g = div_65535(c.green * a);
|
||||
const quint16 b = div_65535(c.blue * a);
|
||||
const quint32 a = alpha();
|
||||
const quint16 r = div_65535(red() * a);
|
||||
const quint16 g = div_65535(green() * a);
|
||||
const quint16 b = div_65535(blue() * a);
|
||||
return fromRgba64(r, g, b, a);
|
||||
}
|
||||
|
||||
@ -145,27 +160,31 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
static Q_DECL_CONSTEXPR quint64 alphaMask() { return quint64(0xffff) << AlphaShift; }
|
||||
|
||||
static Q_DECL_CONSTEXPR uint div_257_floor(uint x) { return (x - (x >> 8)) >> 8; }
|
||||
static Q_DECL_CONSTEXPR uint div_257(uint x) { return div_257_floor(x + 128); }
|
||||
static Q_DECL_CONSTEXPR uint div_65535(uint x) { return (x + (x>>16) + 0x8000U) >> 16; }
|
||||
Q_DECL_RELAXED_CONSTEXPR QRgba64 unpremultiplied_32bit() const
|
||||
{
|
||||
if (c.alpha == 0xffff || c.alpha == 0)
|
||||
const quint16 a = alpha();
|
||||
if (a == 0xffff || a == 0)
|
||||
return *this;
|
||||
const quint16 r = (quint32(c.red) * 0xffff + c.alpha/2) / c.alpha;
|
||||
const quint16 g = (quint32(c.green) * 0xffff + c.alpha/2) / c.alpha;
|
||||
const quint16 b = (quint32(c.blue) * 0xffff + c.alpha/2) / c.alpha;
|
||||
return fromRgba64(r, g, b, c.alpha);
|
||||
const quint16 r = (quint32(red()) * 0xffff + a/2) / a;
|
||||
const quint16 g = (quint32(green()) * 0xffff + a/2) / a;
|
||||
const quint16 b = (quint32(blue()) * 0xffff + a/2) / a;
|
||||
return fromRgba64(r, g, b, a);
|
||||
}
|
||||
Q_DECL_RELAXED_CONSTEXPR QRgba64 unpremultiplied_64bit() const
|
||||
{
|
||||
if (c.alpha == 0xffff || c.alpha == 0)
|
||||
const quint16 a = alpha();
|
||||
if (a == 0xffff || a == 0)
|
||||
return *this;
|
||||
const quint64 fa = (Q_UINT64_C(0xffff00008000) + c.alpha/2) / c.alpha;
|
||||
const quint16 r = (c.red * fa + 0x80000000) >> 32;
|
||||
const quint16 g = (c.green * fa + 0x80000000) >> 32;
|
||||
const quint16 b = (c.blue * fa + 0x80000000) >> 32;
|
||||
return fromRgba64(r, g, b, c.alpha);
|
||||
const quint64 fa = (Q_UINT64_C(0xffff00008000) + a/2) / a;
|
||||
const quint16 r = (red() * fa + 0x80000000) >> 32;
|
||||
const quint16 g = (green() * fa + 0x80000000) >> 32;
|
||||
const quint16 b = (blue() * fa + 0x80000000) >> 32;
|
||||
return fromRgba64(r, g, b, a);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -99,6 +99,13 @@ static bool ft_getSfntTable(void *user_data, uint tag, uchar *buffer, uint *leng
|
||||
|
||||
static QFontEngineFT::Glyph emptyGlyph = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
|
||||
static const QFontEngine::HintStyle ftInitialDefaultHintStyle =
|
||||
#ifdef Q_OS_WIN
|
||||
QFontEngineFT::HintFull;
|
||||
#else
|
||||
QFontEngineFT::HintNone;
|
||||
#endif
|
||||
|
||||
// -------------------------- Freetype support ------------------------------
|
||||
|
||||
class QtFreetypeData
|
||||
@ -629,11 +636,7 @@ QFontEngineFT::QFontEngineFT(const QFontDef &fd)
|
||||
antialias = true;
|
||||
freetype = 0;
|
||||
default_load_flags = FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH;
|
||||
#ifndef Q_OS_WIN
|
||||
default_hint_style = HintNone;
|
||||
#else
|
||||
default_hint_style = HintFull;
|
||||
#endif
|
||||
default_hint_style = ftInitialDefaultHintStyle;
|
||||
subpixelType = Subpixel_None;
|
||||
lcdFilterType = 0;
|
||||
#if defined(FT_LCD_FILTER_H)
|
||||
@ -760,6 +763,24 @@ bool QFontEngineFT::init(FaceId faceId, bool antialias, GlyphFormat format,
|
||||
return true;
|
||||
}
|
||||
|
||||
void QFontEngineFT::setQtDefaultHintStyle(QFont::HintingPreference hintingPreference)
|
||||
{
|
||||
switch (hintingPreference) {
|
||||
case QFont::PreferNoHinting:
|
||||
setDefaultHintStyle(HintNone);
|
||||
break;
|
||||
case QFont::PreferFullHinting:
|
||||
setDefaultHintStyle(HintFull);
|
||||
break;
|
||||
case QFont::PreferVerticalHinting:
|
||||
setDefaultHintStyle(HintLight);
|
||||
break;
|
||||
case QFont::PreferDefaultHinting:
|
||||
setDefaultHintStyle(ftInitialDefaultHintStyle);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void QFontEngineFT::setDefaultHintStyle(HintStyle style)
|
||||
{
|
||||
default_hint_style = style;
|
||||
|
@ -281,7 +281,7 @@ private:
|
||||
|
||||
virtual int getPointInOutline(glyph_t glyph, int flags, quint32 point, QFixed *xpos, QFixed *ypos, quint32 *nPoints) Q_DECL_OVERRIDE;
|
||||
|
||||
|
||||
void setQtDefaultHintStyle(QFont::HintingPreference hintingPreference);
|
||||
virtual void setDefaultHintStyle(HintStyle style) Q_DECL_OVERRIDE;
|
||||
|
||||
virtual QFontEngine *cloneWithSize(qreal pixelSize) const Q_DECL_OVERRIDE;
|
||||
@ -307,6 +307,7 @@ private:
|
||||
friend class QFontEngineFTRawFont;
|
||||
friend class QFontconfigDatabase;
|
||||
friend class QBasicFontDatabase;
|
||||
friend class QCoreTextFontDatabase;
|
||||
friend class QFontEngineMultiFontConfig;
|
||||
|
||||
int loadFlags(QGlyphSet *set, GlyphFormat format, int flags, bool &hsubpixel, int &vfactor) const;
|
||||
|
@ -1120,6 +1120,15 @@ QT_BEGIN_INCLUDE_NAMESPACE
|
||||
|
||||
QT_END_INCLUDE_NAMESPACE
|
||||
|
||||
#if defined(Q_OS_OSX) && !defined(QT_NO_FREETYPE)
|
||||
static const char *s_shapersForOsxFreeType[] =
|
||||
{
|
||||
"ot",
|
||||
"fallback",
|
||||
Q_NULLPTR
|
||||
};
|
||||
#endif
|
||||
|
||||
int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, const ushort *string, int itemLength, QFontEngine *fontEngine, const QVector<uint> &itemBoundaries, bool kerningEnabled) const
|
||||
{
|
||||
uint glyphs_shaped = 0;
|
||||
@ -1172,7 +1181,15 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, const ushort *st
|
||||
};
|
||||
const int num_features = 1;
|
||||
|
||||
bool shapedOk = hb_shape_full(hb_font, buffer, features, num_features, 0);
|
||||
const char *const *shaper_list = Q_NULLPTR;
|
||||
#if defined(Q_OS_OSX) && !defined(QT_NO_FREETYPE)
|
||||
// What's behind QFontEngine::FaceData::user_data isn't compatible between CoreText and
|
||||
// FreeType font engines - specifically functions in hb-coretext.cc would run into undefined
|
||||
// behavior with data from the FreeType engine. The OpenType shaper works with that engine.
|
||||
if (actualFontEngine->type() == QFontEngine::Freetype)
|
||||
shaper_list = s_shapersForOsxFreeType;
|
||||
#endif
|
||||
bool shapedOk = hb_shape_full(hb_font, buffer, features, num_features, shaper_list);
|
||||
if (Q_UNLIKELY(!shapedOk)) {
|
||||
hb_buffer_destroy(buffer);
|
||||
return 0;
|
||||
|
@ -115,8 +115,6 @@ public:
|
||||
QNetworkReplyImplPrivate();
|
||||
|
||||
void _q_startOperation();
|
||||
void _q_sourceReadyRead();
|
||||
void _q_sourceReadChannelFinished();
|
||||
void _q_copyReadyRead();
|
||||
void _q_copyReadChannelFinished();
|
||||
void _q_bufferOutgoingData();
|
||||
|
@ -1810,12 +1810,12 @@ QString QAbstractSocket::peerName() const
|
||||
*/
|
||||
bool QAbstractSocket::canReadLine() const
|
||||
{
|
||||
bool hasLine = d_func()->buffer.canReadLine();
|
||||
bool hasLine = QIODevice::canReadLine();
|
||||
#if defined (QABSTRACTSOCKET_DEBUG)
|
||||
qDebug("QAbstractSocket::canReadLine() == %s, buffer size = %lld, size = %lld",
|
||||
hasLine ? "true" : "false", d_func()->buffer.size(), d_func()->buffer.size());
|
||||
#endif
|
||||
return hasLine || QIODevice::canReadLine();
|
||||
return hasLine;
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -149,7 +149,7 @@ public:
|
||||
qint64 bytesAvailable() const Q_DECL_OVERRIDE;
|
||||
qint64 bytesToWrite() const Q_DECL_OVERRIDE;
|
||||
|
||||
bool canReadLine() const Q_DECL_OVERRIDE;
|
||||
bool canReadLine() const Q_DECL_OVERRIDE; // ### Qt6: remove me
|
||||
|
||||
quint16 localPort() const;
|
||||
QHostAddress localAddress() const;
|
||||
|
@ -76,24 +76,6 @@ void QBasicFontDatabase::populateFontDatabase()
|
||||
}
|
||||
}
|
||||
|
||||
inline static void setHintingPreference(QFontEngine *engine, QFont::HintingPreference hintingPreference)
|
||||
{
|
||||
switch (hintingPreference) {
|
||||
case QFont::PreferNoHinting:
|
||||
engine->setDefaultHintStyle(QFontEngineFT::HintNone);
|
||||
break;
|
||||
case QFont::PreferFullHinting:
|
||||
engine->setDefaultHintStyle(QFontEngineFT::HintFull);
|
||||
break;
|
||||
case QFont::PreferVerticalHinting:
|
||||
engine->setDefaultHintStyle(QFontEngineFT::HintLight);
|
||||
break;
|
||||
case QFont::PreferDefaultHinting:
|
||||
// Leave it as it is
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
QFontEngine *QBasicFontDatabase::fontEngine(const QFontDef &fontDef, void *usrPtr)
|
||||
{
|
||||
FontFile *fontfile = static_cast<FontFile *> (usrPtr);
|
||||
@ -119,7 +101,7 @@ QFontEngine *QBasicFontDatabase::fontEngine(const QFontDef &fontDef, void *usrPt
|
||||
delete engine;
|
||||
engine = 0;
|
||||
} else {
|
||||
setHintingPreference(engine, static_cast<QFont::HintingPreference>(fontDef.hintingPreference));
|
||||
engine->setQtDefaultHintStyle(static_cast<QFont::HintingPreference>(fontDef.hintingPreference));
|
||||
}
|
||||
|
||||
return engine;
|
||||
@ -172,7 +154,7 @@ QFontEngine *QBasicFontDatabase::fontEngine(const QByteArray &fontData, qreal pi
|
||||
}
|
||||
|
||||
fe->updateFamilyNameAndStyle();
|
||||
setHintingPreference(fe, hintingPreference);
|
||||
fe->setQtDefaultHintStyle(static_cast<QFont::HintingPreference>(fontDef.hintingPreference));
|
||||
|
||||
return fe;
|
||||
}
|
||||
|
@ -1,6 +1,13 @@
|
||||
HEADERS += $$PWD/qcoretextfontdatabase_p.h $$PWD/qfontengine_coretext_p.h
|
||||
OBJECTIVE_SOURCES += $$PWD/qfontengine_coretext.mm $$PWD/qcoretextfontdatabase.mm
|
||||
|
||||
contains(QT_CONFIG, freetype) {
|
||||
include($$QT_SOURCE_TREE/src/3rdparty/freetype_dependency.pri)
|
||||
HEADERS += $$QT_SOURCE_TREE/src/gui/text/qfontengine_ft_p.h
|
||||
SOURCES += $$QT_SOURCE_TREE/src/gui/text/qfontengine_ft.cpp
|
||||
CONFIG += opentype
|
||||
}
|
||||
|
||||
ios: \
|
||||
# On iOS CoreText and CoreGraphics are stand-alone frameworks
|
||||
LIBS_PRIVATE += -framework CoreText -framework CoreGraphics
|
||||
|
@ -33,6 +33,8 @@
|
||||
|
||||
#include "qglobal.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#if defined(Q_OS_MACX)
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <IOKit/graphics/IOGraphicsLib.h>
|
||||
@ -45,6 +47,9 @@
|
||||
#include <QtCore/QSettings>
|
||||
#include <QtGui/QGuiApplication>
|
||||
#include <QtCore/QtEndian>
|
||||
#ifndef QT_NO_FREETYPE
|
||||
#include <QtGui/private/qfontengine_ft_p.h>
|
||||
#endif
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
@ -102,8 +107,12 @@ static NSInteger languageMapSort(id obj1, id obj2, void *context)
|
||||
}
|
||||
#endif
|
||||
|
||||
QCoreTextFontDatabase::QCoreTextFontDatabase()
|
||||
QCoreTextFontDatabase::QCoreTextFontDatabase(bool useFreeType)
|
||||
#ifndef QT_NO_FREETYPE
|
||||
: m_useFreeType(useFreeType)
|
||||
#endif
|
||||
{
|
||||
Q_UNUSED(useFreeType)
|
||||
#ifdef Q_OS_MACX
|
||||
QSettings appleSettings(QLatin1String("apple.com"));
|
||||
QVariant appleValue = appleSettings.value(QLatin1String("AppleAntiAliasingThreshold"));
|
||||
@ -348,10 +357,48 @@ void QCoreTextFontDatabase::releaseHandle(void *handle)
|
||||
CFRelease(CTFontDescriptorRef(handle));
|
||||
}
|
||||
|
||||
#ifndef QT_NO_FREETYPE
|
||||
static QByteArray filenameForCFUrl(CFURLRef url)
|
||||
{
|
||||
// The on-stack buffer prevents that a QByteArray allocated for the worst case (MAXPATHLEN)
|
||||
// stays around for the lifetime of the font. Additionally, it helps to move the char
|
||||
// signedness cast to an acceptable place.
|
||||
uchar buffer[MAXPATHLEN];
|
||||
QByteArray filename;
|
||||
|
||||
if (!CFURLGetFileSystemRepresentation(url, true, buffer, sizeof(buffer))) {
|
||||
qWarning("QCoreTextFontDatabase::filenameForCFUrl: could not resolve file for URL %s",
|
||||
qPrintable(QString::fromCFString(CFURLGetString(url))));
|
||||
} else {
|
||||
QCFType<CFStringRef> scheme = CFURLCopyScheme(url);
|
||||
if (QString::fromCFString(scheme) == QLatin1String("qrc"))
|
||||
filename = ":";
|
||||
|
||||
filename += reinterpret_cast<char *>(buffer);
|
||||
}
|
||||
|
||||
return filename;
|
||||
}
|
||||
#endif
|
||||
|
||||
extern CGAffineTransform qt_transform_from_fontdef(const QFontDef &fontDef);
|
||||
|
||||
QFontEngine *QCoreTextFontDatabase::fontEngine(const QFontDef &f, void *usrPtr)
|
||||
{
|
||||
CTFontDescriptorRef descriptor = static_cast<CTFontDescriptorRef>(usrPtr);
|
||||
|
||||
#ifndef QT_NO_FREETYPE
|
||||
if (m_useFreeType) {
|
||||
QCFType<CFURLRef> url(static_cast<CFURLRef>(CTFontDescriptorCopyAttribute(descriptor, kCTFontURLAttribute)));
|
||||
|
||||
QByteArray filename;
|
||||
if (url)
|
||||
filename = filenameForCFUrl(url);
|
||||
|
||||
return freeTypeFontEngine(f, filename);
|
||||
}
|
||||
#endif
|
||||
|
||||
qreal scaledPointSize = f.pixelSize;
|
||||
|
||||
// When 96 DPI is forced, the Mac plugin will use DPI 72 for some
|
||||
@ -363,7 +410,6 @@ QFontEngine *QCoreTextFontDatabase::fontEngine(const QFontDef &f, void *usrPtr)
|
||||
if (QGuiApplication::testAttribute(Qt::AA_Use96Dpi))
|
||||
scaledPointSize = f.pointSize;
|
||||
|
||||
CTFontDescriptorRef descriptor = (CTFontDescriptorRef) usrPtr;
|
||||
CGAffineTransform matrix = qt_transform_from_fontdef(f);
|
||||
CTFontRef font = CTFontCreateWithFontDescriptor(descriptor, scaledPointSize, &matrix);
|
||||
if (font) {
|
||||
@ -385,6 +431,29 @@ static void releaseFontData(void* info, const void* data, size_t size)
|
||||
|
||||
QFontEngine *QCoreTextFontDatabase::fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference)
|
||||
{
|
||||
#ifndef QT_NO_FREETYPE
|
||||
if (m_useFreeType) {
|
||||
QByteArray *fontDataCopy = new QByteArray(fontData);
|
||||
QCFType<CGDataProviderRef> dataProvider = CGDataProviderCreateWithData(fontDataCopy,
|
||||
fontDataCopy->constData(), fontDataCopy->size(), releaseFontData);
|
||||
QCFType<CGFontRef> cgFont(CGFontCreateWithDataProvider(dataProvider));
|
||||
|
||||
if (!cgFont) {
|
||||
qWarning("QCoreTextFontDatabase::fontEngine: CGFontCreateWithDataProvider failed");
|
||||
return Q_NULLPTR;
|
||||
}
|
||||
|
||||
QFontDef fontDef;
|
||||
fontDef.pixelSize = pixelSize;
|
||||
fontDef.pointSize = pixelSize * 72.0 / qt_defaultDpi();
|
||||
fontDef.hintingPreference = hintingPreference;
|
||||
CGAffineTransform transform = qt_transform_from_fontdef(fontDef);
|
||||
QCFType<CTFontRef> ctFont(CTFontCreateWithGraphicsFont(cgFont, fontDef.pixelSize, &transform, Q_NULLPTR));
|
||||
QCFType<CFURLRef> url(static_cast<CFURLRef>(CTFontCopyAttribute(ctFont, kCTFontURLAttribute)));
|
||||
return freeTypeFontEngine(fontDef, filenameForCFUrl(url), fontData);
|
||||
}
|
||||
#endif
|
||||
|
||||
Q_UNUSED(hintingPreference);
|
||||
|
||||
QByteArray* fontDataCopy = new QByteArray(fontData);
|
||||
@ -556,10 +625,36 @@ QStringList QCoreTextFontDatabase::fallbacksForFamily(const QString &family, QFo
|
||||
}
|
||||
|
||||
#if HAVE_CORETEXT
|
||||
static CFArrayRef createDescriptorArrayForFont(CTFontRef font)
|
||||
static CFArrayRef createDescriptorArrayForFont(CTFontRef font, const QString &fileName = QString())
|
||||
{
|
||||
CFMutableArrayRef array = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
|
||||
CFArrayAppendValue(array, QCFType<CTFontDescriptorRef>(CTFontCopyFontDescriptor(font)));
|
||||
QCFType<CTFontDescriptorRef> descriptor = CTFontCopyFontDescriptor(font);
|
||||
|
||||
Q_UNUSED(fileName)
|
||||
#ifndef QT_NO_FREETYPE
|
||||
// The physical font source URL (usually a local file or Qt resource) is only required for
|
||||
// FreeType, when using non-system fonts, and needs some hackery to attach in a format
|
||||
// agreeable to OSX.
|
||||
if (!fileName.isEmpty()) {
|
||||
QCFType<CFURLRef> fontURL;
|
||||
|
||||
if (fileName.startsWith(QLatin1String(":/"))) {
|
||||
// QUrl::fromLocalFile() doesn't accept qrc pseudo-paths like ":/fonts/myfont.ttf".
|
||||
// Therefore construct from QString with the qrc:// scheme -> "qrc:///fonts/myfont.ttf".
|
||||
fontURL = QUrl(QStringLiteral("qrc://") + fileName.mid(1)).toCFURL();
|
||||
} else if (!fileName.isEmpty()) {
|
||||
// At this point we hope that filename is in a format that QUrl can handle.
|
||||
fontURL = QUrl::fromLocalFile(fileName).toCFURL();
|
||||
}
|
||||
|
||||
QCFType<CFMutableDictionaryRef> attributes = CFDictionaryCreateMutable(kCFAllocatorDefault, 1,
|
||||
&kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
|
||||
CFDictionaryAddValue(attributes, kCTFontURLAttribute, fontURL);
|
||||
descriptor = CTFontDescriptorCreateCopyWithAttributes(descriptor, attributes);
|
||||
}
|
||||
#endif
|
||||
|
||||
CFArrayAppendValue(array, descriptor);
|
||||
return array;
|
||||
}
|
||||
#endif
|
||||
@ -580,7 +675,11 @@ QStringList QCoreTextFontDatabase::addApplicationFont(const QByteArray &fontData
|
||||
if (cgFont) {
|
||||
if (CTFontManagerRegisterGraphicsFont(cgFont, &error)) {
|
||||
QCFType<CTFontRef> font = CTFontCreateWithGraphicsFont(cgFont, 0.0, NULL, NULL);
|
||||
fonts = createDescriptorArrayForFont(font);
|
||||
fonts = createDescriptorArrayForFont(font
|
||||
#ifndef QT_NO_FREETYPE
|
||||
, m_useFreeType ? fileName : QString()
|
||||
#endif
|
||||
);
|
||||
m_applicationFonts.append(QVariant::fromValue(QCFType<CGFontRef>::constructFromGet(cgFont)));
|
||||
}
|
||||
}
|
||||
@ -880,5 +979,36 @@ void QCoreTextFontDatabase::removeApplicationFonts()
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef QT_NO_FREETYPE
|
||||
QFontEngine *QCoreTextFontDatabase::freeTypeFontEngine(const QFontDef &fontDef, const QByteArray &filename,
|
||||
const QByteArray &fontData)
|
||||
{
|
||||
QFontEngine::FaceId faceId;
|
||||
faceId.filename = filename;
|
||||
const bool antialias = !(fontDef.styleStrategy & QFont::NoAntialias);
|
||||
|
||||
QScopedPointer<QFontEngineFT> engine(new QFontEngineFT(fontDef));
|
||||
QFontEngineFT::GlyphFormat format = QFontEngineFT::Format_Mono;
|
||||
if (antialias) {
|
||||
QFontEngine::SubpixelAntialiasingType subpixelType = subpixelAntialiasingTypeHint();
|
||||
if (subpixelType == QFontEngine::Subpixel_None || (fontDef.styleStrategy & QFont::NoSubpixelAntialias)) {
|
||||
format = QFontEngineFT::Format_A8;
|
||||
engine->subpixelType = QFontEngine::Subpixel_None;
|
||||
} else {
|
||||
format = QFontEngineFT::Format_A32;
|
||||
engine->subpixelType = subpixelType;
|
||||
}
|
||||
}
|
||||
|
||||
if (!engine->init(faceId, antialias, format, fontData) || engine->invalid()) {
|
||||
qWarning() << "QCoreTextFontDatabase::freeTypefontEngine Failed to create engine";
|
||||
return Q_NULLPTR;
|
||||
}
|
||||
engine->setQtDefaultHintStyle(static_cast<QFont::HintingPreference>(fontDef.hintingPreference));
|
||||
|
||||
return engine.take();
|
||||
}
|
||||
#endif
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
|
@ -73,7 +73,7 @@ QT_BEGIN_NAMESPACE
|
||||
class QCoreTextFontDatabase : public QPlatformFontDatabase
|
||||
{
|
||||
public:
|
||||
QCoreTextFontDatabase();
|
||||
QCoreTextFontDatabase(bool useFreeType = false);
|
||||
~QCoreTextFontDatabase();
|
||||
void populateFontDatabase() Q_DECL_OVERRIDE;
|
||||
void populateFamily(const QString &familyName) Q_DECL_OVERRIDE;
|
||||
@ -95,6 +95,11 @@ public:
|
||||
private:
|
||||
void populateFromDescriptor(CTFontDescriptorRef font);
|
||||
|
||||
#ifndef QT_NO_FREETYPE
|
||||
bool m_useFreeType;
|
||||
QFontEngine *freeTypeFontEngine(const QFontDef &fontDef, const QByteArray &filename,
|
||||
const QByteArray &fontData = QByteArray());
|
||||
#endif
|
||||
mutable QString defaultFontName;
|
||||
|
||||
void removeApplicationFonts();
|
||||
|
@ -70,18 +70,20 @@ namespace QtAndroidInput
|
||||
candidatesEnd);
|
||||
}
|
||||
|
||||
void showSoftwareKeyboard(int left, int top, int width, int height, int inputHints)
|
||||
void showSoftwareKeyboard(int left, int top, int width, int height, int inputHints, int enterKeyType)
|
||||
{
|
||||
QJNIObjectPrivate::callStaticMethod<void>(applicationClass(),
|
||||
"showSoftwareKeyboard",
|
||||
"(IIIII)V",
|
||||
"(IIIIII)V",
|
||||
left,
|
||||
top,
|
||||
width,
|
||||
height,
|
||||
inputHints);
|
||||
inputHints,
|
||||
enterKeyType
|
||||
);
|
||||
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
|
||||
qDebug() << "@@@ SHOWSOFTWAREKEYBOARD" << left << top << width << height << inputHints;
|
||||
qDebug() << "@@@ SHOWSOFTWAREKEYBOARD" << left << top << width << height << inputHints << enterKeyType;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -41,7 +41,7 @@ QT_BEGIN_NAMESPACE
|
||||
namespace QtAndroidInput
|
||||
{
|
||||
// Software keyboard support
|
||||
void showSoftwareKeyboard(int top, int left, int width, int height, int inputHints);
|
||||
void showSoftwareKeyboard(int top, int left, int width, int height, int inputHints, int enterKeyType);
|
||||
void resetSoftwareKeyboard();
|
||||
void hideSoftwareKeyboard();
|
||||
bool isSoftwareKeyboardVisible();
|
||||
|
@ -545,7 +545,9 @@ void QAndroidInputContext::showInputPanel()
|
||||
rect.top(),
|
||||
rect.width(),
|
||||
rect.height(),
|
||||
query->value(Qt::ImHints).toUInt());
|
||||
query->value(Qt::ImHints).toUInt(),
|
||||
query->value(Qt::ImEnterKeyType).toUInt()
|
||||
);
|
||||
}
|
||||
|
||||
void QAndroidInputContext::showInputPanelLater(Qt::ApplicationState state)
|
||||
|
@ -50,11 +50,9 @@ public:
|
||||
|
||||
QPlatformIntegration * QCocoaIntegrationPlugin::create(const QString& system, const QStringList& paramList)
|
||||
{
|
||||
Q_UNUSED(paramList);
|
||||
|
||||
QMacAutoReleasePool pool;
|
||||
if (system.compare(QLatin1String("cocoa"), Qt::CaseInsensitive) == 0)
|
||||
return new QCocoaIntegration;
|
||||
return new QCocoaIntegration(paramList);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -73,6 +73,7 @@ public:
|
||||
QPlatformCursor *cursor() const Q_DECL_OVERRIDE { return m_cursor; }
|
||||
QWindow *topLevelAt(const QPoint &point) const Q_DECL_OVERRIDE;
|
||||
QList<QPlatformScreen *> virtualSiblings() const Q_DECL_OVERRIDE { return m_siblings; }
|
||||
QPlatformScreen::SubpixelAntialiasingType subpixelAntialiasingTypeHint() const Q_DECL_OVERRIDE;
|
||||
|
||||
// ----------------------------------------------------
|
||||
// Additional methods
|
||||
@ -97,10 +98,16 @@ public:
|
||||
class QCocoaIntegration : public QPlatformIntegration
|
||||
{
|
||||
public:
|
||||
QCocoaIntegration();
|
||||
enum Option {
|
||||
UseFreeTypeFontEngine = 0x1
|
||||
};
|
||||
Q_DECLARE_FLAGS(Options, Option)
|
||||
|
||||
QCocoaIntegration(const QStringList ¶mList);
|
||||
~QCocoaIntegration();
|
||||
|
||||
static QCocoaIntegration *instance();
|
||||
Options options() const;
|
||||
|
||||
bool hasCapability(QPlatformIntegration::Capability cap) const Q_DECL_OVERRIDE;
|
||||
QPlatformWindow *createPlatformWindow(QWindow *window) const Q_DECL_OVERRIDE;
|
||||
@ -141,6 +148,7 @@ public:
|
||||
void setApplicationIcon(const QIcon &icon) const Q_DECL_OVERRIDE;
|
||||
private:
|
||||
static QCocoaIntegration *mInstance;
|
||||
Options mOptions;
|
||||
|
||||
QScopedPointer<QCoreTextFontDatabase> mFontDb;
|
||||
|
||||
@ -160,6 +168,8 @@ private:
|
||||
QList<QCocoaWindow *> m_popupWindowStack;
|
||||
};
|
||||
|
||||
Q_DECLARE_OPERATORS_FOR_FLAGS(QCocoaIntegration::Options)
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
|
@ -142,6 +142,16 @@ qreal QCocoaScreen::devicePixelRatio() const
|
||||
return qreal(screen ? [screen backingScaleFactor] : 1.0);
|
||||
}
|
||||
|
||||
QPlatformScreen::SubpixelAntialiasingType QCocoaScreen::subpixelAntialiasingTypeHint() const
|
||||
{
|
||||
QPlatformScreen::SubpixelAntialiasingType type = QPlatformScreen::subpixelAntialiasingTypeHint();
|
||||
if (type == QPlatformScreen::Subpixel_None) {
|
||||
// Every OSX machine has RGB pixels unless a peculiar or rotated non-Apple screen is attached
|
||||
type = QPlatformScreen::Subpixel_RGB;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
QWindow *QCocoaScreen::topLevelAt(const QPoint &point) const
|
||||
{
|
||||
NSPoint screenPoint = qt_mac_flipPoint(point);
|
||||
@ -244,10 +254,25 @@ QPixmap QCocoaScreen::grabWindow(WId window, int x, int y, int width, int height
|
||||
return windowPixmap;
|
||||
}
|
||||
|
||||
static QCocoaIntegration::Options parseOptions(const QStringList ¶mList)
|
||||
{
|
||||
QCocoaIntegration::Options options;
|
||||
foreach (const QString ¶m, paramList) {
|
||||
#ifndef QT_NO_FREETYPE
|
||||
if (param == QLatin1String("fontengine=freetype"))
|
||||
options |= QCocoaIntegration::UseFreeTypeFontEngine;
|
||||
else
|
||||
#endif
|
||||
qWarning() << "Unknown option" << param;
|
||||
}
|
||||
return options;
|
||||
}
|
||||
|
||||
QCocoaIntegration *QCocoaIntegration::mInstance = 0;
|
||||
|
||||
QCocoaIntegration::QCocoaIntegration()
|
||||
: mFontDb(new QCoreTextFontDatabase())
|
||||
QCocoaIntegration::QCocoaIntegration(const QStringList ¶mList)
|
||||
: mOptions(parseOptions(paramList))
|
||||
, mFontDb(new QCoreTextFontDatabase(mOptions.testFlag(UseFreeTypeFontEngine)))
|
||||
#ifndef QT_NO_ACCESSIBILITY
|
||||
, mAccessibility(new QCocoaAccessibility)
|
||||
#endif
|
||||
@ -345,6 +370,11 @@ QCocoaIntegration *QCocoaIntegration::instance()
|
||||
return mInstance;
|
||||
}
|
||||
|
||||
QCocoaIntegration::Options QCocoaIntegration::options() const
|
||||
{
|
||||
return mOptions;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Synchronizes the screen list, adds new screens, removes deleted ones
|
||||
*/
|
||||
|
@ -36,11 +36,13 @@
|
||||
|
||||
#include "qwinrtcursor.h"
|
||||
#include "qwinrtscreen.h"
|
||||
#include <private/qeventdispatcher_winrt_p.h>
|
||||
|
||||
#include <QtCore/qfunctions_winrt.h>
|
||||
#include <QtGui/QGuiApplication>
|
||||
#include <QtGui/QScreen>
|
||||
|
||||
#include <functional>
|
||||
#include <wrl.h>
|
||||
#include <windows.ui.core.h>
|
||||
#include <windows.foundation.h>
|
||||
@ -77,12 +79,17 @@ void QWinRTCursor::changeCursor(QCursor *windowCursor, QWindow *window)
|
||||
{
|
||||
Q_D(QWinRTCursor);
|
||||
|
||||
HRESULT hr;
|
||||
ICoreWindow *coreWindow = static_cast<QWinRTScreen *>(window->screen()->handle())->coreWindow();
|
||||
|
||||
CoreCursorType type;
|
||||
switch (windowCursor ? windowCursor->shape() : Qt::ArrowCursor) {
|
||||
case Qt::BlankCursor:
|
||||
hr = QEventDispatcherWinRT::runOnXamlThread([coreWindow]() {
|
||||
coreWindow->put_PointerCursor(Q_NULLPTR);
|
||||
return S_OK;
|
||||
});
|
||||
RETURN_VOID_IF_FAILED("Failed to set blank native cursor");
|
||||
return;
|
||||
default:
|
||||
case Qt::OpenHandCursor:
|
||||
@ -142,11 +149,13 @@ void QWinRTCursor::changeCursor(QCursor *windowCursor, QWindow *window)
|
||||
}
|
||||
|
||||
ComPtr<ICoreCursor> cursor;
|
||||
HRESULT hr = d->cursorFactory->CreateCursor(type, 0, &cursor);
|
||||
hr = d->cursorFactory->CreateCursor(type, 0, &cursor);
|
||||
RETURN_VOID_IF_FAILED("Failed to create native cursor.");
|
||||
|
||||
hr = coreWindow->put_PointerCursor(cursor.Get());
|
||||
RETURN_VOID_IF_FAILED("Failed to set native cursor.");
|
||||
hr = QEventDispatcherWinRT::runOnXamlThread([coreWindow, &cursor]() {
|
||||
return coreWindow->put_PointerCursor(cursor.Get());
|
||||
});
|
||||
RETURN_VOID_IF_FAILED("Failed to set native cursor");
|
||||
}
|
||||
#endif // QT_NO_CURSOR
|
||||
|
||||
@ -154,8 +163,12 @@ QPoint QWinRTCursor::pos() const
|
||||
{
|
||||
ICoreWindow *coreWindow =
|
||||
static_cast<QWinRTScreen *>(QGuiApplication::primaryScreen()->handle())->coreWindow();
|
||||
HRESULT hr;
|
||||
Point point;
|
||||
coreWindow->get_PointerPosition(&point);
|
||||
hr = QEventDispatcherWinRT::runOnXamlThread([coreWindow, &point]() {
|
||||
return coreWindow->get_PointerPosition(&point);
|
||||
});
|
||||
RETURN_IF_FAILED("Failed to get native cursor position", QPoint());
|
||||
return QPoint(point.X, point.Y);
|
||||
}
|
||||
|
||||
|
@ -35,40 +35,133 @@
|
||||
****************************************************************************/
|
||||
|
||||
#include "qwinrteglcontext.h"
|
||||
#include "qwinrtwindow.h"
|
||||
#include <private/qeventdispatcher_winrt_p.h>
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include <EGL/egl.h>
|
||||
#define EGL_EGLEXT_PROTOTYPES
|
||||
#include "EGL/eglext.h"
|
||||
#include <EGL/eglext.h>
|
||||
|
||||
#include <QOpenGLContext>
|
||||
#include <QtPlatformSupport/private/qeglconvenience_p.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QWinRTEGLContext::QWinRTEGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display, EGLSurface surface, EGLConfig config)
|
||||
: QEGLPlatformContext(format, share, display, &config), m_eglSurface(surface)
|
||||
class QWinRTEGLContextPrivate
|
||||
{
|
||||
public:
|
||||
QSurfaceFormat format;
|
||||
EGLDisplay eglDisplay;
|
||||
EGLConfig eglConfig;
|
||||
EGLContext eglContext;
|
||||
QHash<QPlatformSurface *, EGLSurface> surfaceForWindow;
|
||||
};
|
||||
|
||||
QWinRTEGLContext::QWinRTEGLContext(QOpenGLContext *context)
|
||||
: d_ptr(new QWinRTEGLContextPrivate)
|
||||
{
|
||||
Q_D(QWinRTEGLContext);
|
||||
d->format = context->format();
|
||||
d->format.setRenderableType(QSurfaceFormat::OpenGLES);
|
||||
}
|
||||
|
||||
void QWinRTEGLContext::swapBuffers(QPlatformSurface *surface)
|
||||
QWinRTEGLContext::~QWinRTEGLContext()
|
||||
{
|
||||
#ifdef Q_OS_WINPHONE
|
||||
const QSize size = surface->surface()->size();
|
||||
eglPostSubBufferNV(eglDisplay(), eglSurfaceForPlatformSurface(surface),
|
||||
0, 0, size.width(), size.height());
|
||||
#else
|
||||
eglSwapBuffers(eglDisplay(), eglSurfaceForPlatformSurface(surface));
|
||||
#endif
|
||||
Q_D(QWinRTEGLContext);
|
||||
foreach (const EGLSurface &surface, d->surfaceForWindow)
|
||||
eglDestroySurface(d->eglDisplay, surface);
|
||||
if (d->eglContext != EGL_NO_CONTEXT)
|
||||
eglDestroyContext(d->eglDisplay, d->eglContext);
|
||||
if (d->eglDisplay != EGL_NO_DISPLAY)
|
||||
eglTerminate(d->eglDisplay);
|
||||
}
|
||||
|
||||
EGLSurface QWinRTEGLContext::eglSurfaceForPlatformSurface(QPlatformSurface *surface)
|
||||
void QWinRTEGLContext::initialize()
|
||||
{
|
||||
if (surface->surface()->surfaceClass() == QSurface::Window) {
|
||||
// All windows use the same surface
|
||||
return m_eglSurface;
|
||||
} else {
|
||||
// TODO: return EGL surfaces for offscreen surfaces
|
||||
qWarning("This plugin does not support offscreen surfaces.");
|
||||
return EGL_NO_SURFACE;
|
||||
Q_D(QWinRTEGLContext);
|
||||
|
||||
eglBindAPI(EGL_OPENGL_ES_API);
|
||||
d->eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
||||
if (d->eglDisplay == EGL_NO_DISPLAY)
|
||||
qCritical("Failed to initialize EGL display: 0x%x", eglGetError());
|
||||
|
||||
if (!eglInitialize(d->eglDisplay, nullptr, nullptr))
|
||||
qCritical("Failed to initialize EGL: 0x%x", eglGetError());
|
||||
|
||||
d->eglConfig = q_configFromGLFormat(d->eglDisplay, d->format);
|
||||
|
||||
const EGLint flags = d->format.testOption(QSurfaceFormat::DebugContext)
|
||||
? EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR : 0;
|
||||
const EGLint attributes[] = {
|
||||
EGL_CONTEXT_CLIENT_VERSION, d->format.majorVersion(),
|
||||
EGL_CONTEXT_MINOR_VERSION_KHR, d->format.minorVersion(),
|
||||
EGL_CONTEXT_FLAGS_KHR, flags,
|
||||
EGL_NONE
|
||||
};
|
||||
d->eglContext = eglCreateContext(d->eglDisplay, d->eglConfig, nullptr, attributes);
|
||||
if (d->eglContext == EGL_NO_CONTEXT) {
|
||||
qWarning("QEGLPlatformContext: Failed to create context: %x", eglGetError());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool QWinRTEGLContext::makeCurrent(QPlatformSurface *windowSurface)
|
||||
{
|
||||
Q_D(QWinRTEGLContext);
|
||||
Q_ASSERT(windowSurface->surface()->surfaceType() == QSurface::OpenGLSurface);
|
||||
|
||||
EGLSurface surface = d->surfaceForWindow.value(windowSurface);
|
||||
if (surface == EGL_NO_SURFACE) {
|
||||
QWinRTWindow *window = static_cast<QWinRTWindow *>(windowSurface);
|
||||
HRESULT hr = QEventDispatcherWinRT::runOnXamlThread([this, d, window, &surface]() {
|
||||
surface = eglCreateWindowSurface(d->eglDisplay, d->eglConfig,
|
||||
reinterpret_cast<EGLNativeWindowType>(window->winId()),
|
||||
nullptr);
|
||||
if (surface == EGL_NO_SURFACE) {
|
||||
qCritical("Failed to create EGL window surface: 0x%x", eglGetError());
|
||||
return E_FAIL;
|
||||
}
|
||||
return S_OK;
|
||||
});
|
||||
if (FAILED(hr))
|
||||
return false;
|
||||
d->surfaceForWindow.insert(windowSurface, surface);
|
||||
}
|
||||
|
||||
const bool ok = eglMakeCurrent(d->eglDisplay, surface, surface, d->eglContext);
|
||||
if (!ok) {
|
||||
qWarning("QEGLPlatformContext: eglMakeCurrent failed: %x", eglGetError());
|
||||
return false;
|
||||
}
|
||||
|
||||
eglSwapInterval(d->eglDisplay, d->format.swapInterval());
|
||||
return true;
|
||||
}
|
||||
|
||||
void QWinRTEGLContext::doneCurrent()
|
||||
{
|
||||
Q_D(const QWinRTEGLContext);
|
||||
const bool ok = eglMakeCurrent(d->eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||
if (!ok)
|
||||
qWarning("QEGLPlatformContext: eglMakeCurrent failed: %x", eglGetError());
|
||||
}
|
||||
|
||||
void QWinRTEGLContext::swapBuffers(QPlatformSurface *windowSurface)
|
||||
{
|
||||
Q_D(QWinRTEGLContext);
|
||||
Q_ASSERT(windowSurface->surface()->surfaceType() == QSurface::OpenGLSurface);
|
||||
|
||||
eglSwapBuffers(d->eglDisplay, d->surfaceForWindow.value(windowSurface));
|
||||
}
|
||||
|
||||
QSurfaceFormat QWinRTEGLContext::format() const
|
||||
{
|
||||
Q_D(const QWinRTEGLContext);
|
||||
return d->format;
|
||||
}
|
||||
|
||||
QFunctionPointer QWinRTEGLContext::getProcAddress(const QByteArray &procName)
|
||||
{
|
||||
static QHash<QByteArray, QFunctionPointer> standardFuncs;
|
||||
@ -221,7 +314,7 @@ QFunctionPointer QWinRTEGLContext::getProcAddress(const QByteArray &procName)
|
||||
if (i != standardFuncs.end())
|
||||
return i.value();
|
||||
|
||||
return QEGLPlatformContext::getProcAddress(procName);
|
||||
return eglGetProcAddress(procName.constData());
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -37,23 +37,29 @@
|
||||
#ifndef QWINDOWSEGLCONTEXT_H
|
||||
#define QWINDOWSEGLCONTEXT_H
|
||||
|
||||
#include <QtPlatformSupport/private/qeglplatformcontext_p.h>
|
||||
#include <qpa/qplatformopenglcontext.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QWinRTEGLContext : public QEGLPlatformContext
|
||||
class QWinRTEGLContextPrivate;
|
||||
class QWinRTEGLContext : public QPlatformOpenGLContext
|
||||
{
|
||||
public:
|
||||
explicit QWinRTEGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display, EGLSurface surface, EGLConfig config);
|
||||
explicit QWinRTEGLContext(QOpenGLContext *context);
|
||||
~QWinRTEGLContext();
|
||||
|
||||
void swapBuffers(QPlatformSurface *surface) Q_DECL_OVERRIDE;
|
||||
void initialize() Q_DECL_OVERRIDE;
|
||||
|
||||
bool makeCurrent(QPlatformSurface *windowSurface) Q_DECL_OVERRIDE;
|
||||
void doneCurrent() Q_DECL_OVERRIDE;
|
||||
void swapBuffers(QPlatformSurface *windowSurface) Q_DECL_OVERRIDE;
|
||||
|
||||
QSurfaceFormat format() const Q_DECL_OVERRIDE;
|
||||
QFunctionPointer getProcAddress(const QByteArray &procName) Q_DECL_OVERRIDE;
|
||||
|
||||
protected:
|
||||
EGLSurface eglSurfaceForPlatformSurface(QPlatformSurface *surface);
|
||||
|
||||
private:
|
||||
EGLSurface m_eglSurface;
|
||||
QScopedPointer<QWinRTEGLContextPrivate> d_ptr;
|
||||
Q_DECLARE_PRIVATE(QWinRTEGLContext)
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -182,135 +182,6 @@ void QWinRTInputContext::hideInputPanel()
|
||||
qErrnoWarning(hr, "Failed to hide input panel.");
|
||||
}
|
||||
|
||||
#else // Q_OS_WINPHONE
|
||||
|
||||
// IRawElementProviderSimple
|
||||
HRESULT QWinRTInputContext::get_ProviderOptions(ProviderOptions *retVal)
|
||||
{
|
||||
*retVal = ProviderOptions_ServerSideProvider|ProviderOptions_UseComThreading;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT QWinRTInputContext::GetPatternProvider(PATTERNID id, IUnknown **retVal)
|
||||
{
|
||||
switch (id) {
|
||||
case 10002: //UIA_ValuePatternId
|
||||
return QueryInterface(__uuidof(IValueProvider), (void**)retVal);
|
||||
break;
|
||||
case 10014: //UIA_TextPatternId:
|
||||
return QueryInterface(__uuidof(ITextProvider), (void**)retVal);
|
||||
case 10029: //UIA_TextChildPatternId:
|
||||
*retVal = nullptr;
|
||||
break;
|
||||
default:
|
||||
qWarning("Unhandled pattern ID: %d", id);
|
||||
break;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT QWinRTInputContext::GetPropertyValue(PROPERTYID idProp, VARIANT *retVal)
|
||||
{
|
||||
switch (idProp) {
|
||||
case 30003: //UIA_ControlTypePropertyId
|
||||
retVal->vt = VT_I4;
|
||||
retVal->lVal = 50025; //UIA_CustomControlTypeId
|
||||
break;
|
||||
case 30008: //UIA_IsKeyboardFocusablePropertyId
|
||||
case 30009: //UIA_HasKeyboardFocusPropertyId
|
||||
// These are probably never actually called
|
||||
case 30016: //UIA_IsControlElementPropertyId
|
||||
case 30017: //UIA_IsContentElementPropertyId
|
||||
retVal->vt = VT_BOOL;
|
||||
retVal->boolVal = VARIANT_TRUE;
|
||||
break;
|
||||
case 30019: //UIA_IsPasswordPropertyId
|
||||
retVal->vt = VT_BOOL;
|
||||
retVal->boolVal = VARIANT_FALSE;
|
||||
break;
|
||||
case 30020: //UIA_NativeWindowHandlePropertyId
|
||||
retVal->vt = VT_PTR;
|
||||
retVal->punkVal = m_screen->coreWindow();
|
||||
break;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT QWinRTInputContext::get_HostRawElementProvider(IRawElementProviderSimple **retVal)
|
||||
{
|
||||
// Return the window's element provider
|
||||
IInspectable *hostProvider;
|
||||
HRESULT hr = m_screen->coreWindow()->get_AutomationHostProvider(&hostProvider);
|
||||
if (SUCCEEDED(hr)) {
|
||||
hr = hostProvider->QueryInterface(IID_PPV_ARGS(retVal));
|
||||
hostProvider->Release();
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
// ITextProvider
|
||||
HRESULT QWinRTInputContext::GetSelection(SAFEARRAY **)
|
||||
{
|
||||
// To be useful, requires listening to the focus object for a selection change and raising an event
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT QWinRTInputContext::GetVisibleRanges(SAFEARRAY **)
|
||||
{
|
||||
// To be useful, requires listening to the focus object for a selection change and raising an event
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT QWinRTInputContext::RangeFromChild(IRawElementProviderSimple *,ITextRangeProvider **)
|
||||
{
|
||||
// To be useful, requires listening to the focus object for a selection change and raising an event
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT QWinRTInputContext::RangeFromPoint(UiaPoint, ITextRangeProvider **)
|
||||
{
|
||||
// To be useful, requires listening to the focus object for a selection change and raising an event
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT QWinRTInputContext::get_DocumentRange(ITextRangeProvider **)
|
||||
{
|
||||
// To be useful, requires listening to the focus object for a selection change and raising an event
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT QWinRTInputContext::get_SupportedTextSelection(SupportedTextSelection *)
|
||||
{
|
||||
// To be useful, requires listening to the focus object for a selection change and raising an event
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// IValueProvider
|
||||
HRESULT QWinRTInputContext::SetValue(LPCWSTR)
|
||||
{
|
||||
// To be useful, requires listening to the focus object for a value change and raising an event
|
||||
// May be useful for inputPanel autocomplete, etc.
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT QWinRTInputContext::get_Value(BSTR *)
|
||||
{
|
||||
// To be useful, requires listening to the focus object for a value change and raising an event
|
||||
// May be useful for inputPanel autocomplete, etc.
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT QWinRTInputContext::get_IsReadOnly(BOOL *isReadOnly)
|
||||
{
|
||||
// isReadOnly dictates keyboard opening behavior when view is tapped.
|
||||
// We need to decide if the user tapped within a control which is about to receive focus...
|
||||
// Since this isn't possible (this function gets called before we receive the touch event),
|
||||
// the most platform-aligned option is to show the keyboard if an editable item has focus,
|
||||
// and close the keyboard if it is already open.
|
||||
*isReadOnly = m_isInputPanelVisible || !inputMethodAccepted();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
#endif // !Q_OS_WINPHONE
|
||||
#endif // Q_OS_WINPHONE
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -41,9 +41,6 @@
|
||||
#include <QtCore/QRectF>
|
||||
|
||||
#include <wrl.h>
|
||||
#ifndef Q_OS_WINPHONE
|
||||
# include <UIAutomationCore.h>
|
||||
#endif
|
||||
|
||||
namespace ABI {
|
||||
namespace Windows {
|
||||
@ -63,11 +60,6 @@ QT_BEGIN_NAMESPACE
|
||||
|
||||
class QWinRTScreen;
|
||||
class QWinRTInputContext : public QPlatformInputContext
|
||||
#ifndef Q_OS_WINPHONE
|
||||
, public Microsoft::WRL::RuntimeClass<
|
||||
Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::WinRtClassicComMix>,
|
||||
IRawElementProviderSimple, ITextProvider, IValueProvider>
|
||||
#endif // !Q_OS_WINPHONE
|
||||
{
|
||||
public:
|
||||
explicit QWinRTInputContext(QWinRTScreen *);
|
||||
@ -79,26 +71,7 @@ public:
|
||||
#ifdef Q_OS_WINPHONE
|
||||
void showInputPanel();
|
||||
void hideInputPanel();
|
||||
#else // Q_OS_WINPHONE
|
||||
// IRawElementProviderSimple
|
||||
HRESULT __stdcall get_ProviderOptions(ProviderOptions *retVal);
|
||||
HRESULT __stdcall GetPatternProvider(PATTERNID, IUnknown **);
|
||||
HRESULT __stdcall GetPropertyValue(PROPERTYID idProp, VARIANT *retVal);
|
||||
HRESULT __stdcall get_HostRawElementProvider(IRawElementProviderSimple **retVal);
|
||||
|
||||
// ITextProvider
|
||||
HRESULT __stdcall GetSelection(SAFEARRAY **);
|
||||
HRESULT __stdcall GetVisibleRanges(SAFEARRAY **);
|
||||
HRESULT __stdcall RangeFromChild(IRawElementProviderSimple *,ITextRangeProvider **);
|
||||
HRESULT __stdcall RangeFromPoint(UiaPoint, ITextRangeProvider **);
|
||||
HRESULT __stdcall get_DocumentRange(ITextRangeProvider **);
|
||||
HRESULT __stdcall get_SupportedTextSelection(SupportedTextSelection *);
|
||||
|
||||
// IValueProvider
|
||||
HRESULT __stdcall SetValue(LPCWSTR);
|
||||
HRESULT __stdcall get_Value(BSTR *);
|
||||
HRESULT __stdcall get_IsReadOnly(BOOL *);
|
||||
#endif // !Q_OS_WINPHONE
|
||||
#endif
|
||||
|
||||
private:
|
||||
HRESULT onShowing(ABI::Windows::UI::ViewManagement::IInputPane *,
|
||||
|
@ -45,37 +45,138 @@
|
||||
#include "qwinrtfontdatabase.h"
|
||||
#include "qwinrttheme.h"
|
||||
|
||||
#include <QtCore/QCoreApplication>
|
||||
#include <QtGui/QSurface>
|
||||
#include <QtGui/QOpenGLContext>
|
||||
#include <qfunctions_winrt.h>
|
||||
|
||||
#include <functional>
|
||||
#include <wrl.h>
|
||||
#include <windows.ui.xaml.h>
|
||||
#include <windows.applicationmodel.h>
|
||||
#include <windows.applicationmodel.core.h>
|
||||
#include <windows.ui.core.h>
|
||||
#include <windows.ui.viewmanagement.h>
|
||||
#include <Windows.ApplicationModel.core.h>
|
||||
#include <windows.graphics.display.h>
|
||||
#ifdef Q_OS_WINPHONE
|
||||
# include <windows.phone.ui.input.h>
|
||||
#endif
|
||||
|
||||
using namespace Microsoft::WRL;
|
||||
using namespace Microsoft::WRL::Wrappers;
|
||||
using namespace ABI::Windows::Foundation;
|
||||
using namespace ABI::Windows::ApplicationModel;
|
||||
using namespace ABI::Windows::ApplicationModel::Core;
|
||||
using namespace ABI::Windows::UI;
|
||||
using namespace ABI::Windows::UI::Core;
|
||||
using namespace ABI::Windows::UI::ViewManagement;
|
||||
using namespace ABI::Windows::Graphics::Display;
|
||||
using namespace ABI::Windows::ApplicationModel::Core;
|
||||
#ifdef Q_OS_WINPHONE
|
||||
using namespace ABI::Windows::Phone::UI::Input;
|
||||
#endif
|
||||
|
||||
typedef IEventHandler<IInspectable *> ResumeHandler;
|
||||
typedef IEventHandler<SuspendingEventArgs *> SuspendHandler;
|
||||
#ifdef Q_OS_WINPHONE
|
||||
typedef IEventHandler<BackPressedEventArgs*> BackPressedHandler;
|
||||
#endif
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QWinRTIntegration::QWinRTIntegration()
|
||||
: m_success(false)
|
||||
, m_fontDatabase(new QWinRTFontDatabase)
|
||||
, m_services(new QWinRTServices)
|
||||
{
|
||||
m_screen = new QWinRTScreen;
|
||||
screenAdded(m_screen);
|
||||
typedef HRESULT (__stdcall ICoreApplication::*CoreApplicationCallbackRemover)(EventRegistrationToken);
|
||||
uint qHash(CoreApplicationCallbackRemover key) { void *ptr = *(void **)(&key); return qHash(ptr); }
|
||||
#ifdef Q_OS_WINPHONE
|
||||
typedef HRESULT (__stdcall IHardwareButtonsStatics::*HardwareButtonsCallbackRemover)(EventRegistrationToken);
|
||||
uint qHash(HardwareButtonsCallbackRemover key) { void *ptr = *(void **)(&key); return qHash(ptr); }
|
||||
#endif
|
||||
|
||||
m_success = true;
|
||||
class QWinRTIntegrationPrivate
|
||||
{
|
||||
public:
|
||||
QPlatformFontDatabase *fontDatabase;
|
||||
QPlatformServices *platformServices;
|
||||
QWinRTScreen *mainScreen;
|
||||
QScopedPointer<QWinRTInputContext> inputContext;
|
||||
|
||||
ComPtr<ICoreApplication> application;
|
||||
QHash<CoreApplicationCallbackRemover, EventRegistrationToken> applicationTokens;
|
||||
#ifdef Q_OS_WINPHONE
|
||||
ComPtr<IHardwareButtonsStatics> hardwareButtons;
|
||||
QHash<HardwareButtonsCallbackRemover, EventRegistrationToken> buttonsTokens;
|
||||
#endif
|
||||
};
|
||||
|
||||
QWinRTIntegration::QWinRTIntegration() : d_ptr(new QWinRTIntegrationPrivate)
|
||||
{
|
||||
Q_D(QWinRTIntegration);
|
||||
|
||||
d->fontDatabase = new QWinRTFontDatabase;
|
||||
|
||||
HRESULT hr;
|
||||
hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_ApplicationModel_Core_CoreApplication).Get(),
|
||||
IID_PPV_ARGS(&d->application));
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
hr = d->application->add_Suspending(Callback<SuspendHandler>(this, &QWinRTIntegration::onSuspended).Get(),
|
||||
&d->applicationTokens[&ICoreApplication::remove_Resuming]);
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
hr = d->application->add_Resuming(Callback<ResumeHandler>(this, &QWinRTIntegration::onResume).Get(),
|
||||
&d->applicationTokens[&ICoreApplication::remove_Resuming]);
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
|
||||
#ifdef Q_OS_WINPHONE
|
||||
hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Phone_UI_Input_HardwareButtons).Get(),
|
||||
IID_PPV_ARGS(&d->hardwareButtons));
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
hr = d->hardwareButtons->add_BackPressed(Callback<BackPressedHandler>(this, &QWinRTIntegration::onBackButtonPressed).Get(),
|
||||
&d->buttonsTokens[&IHardwareButtonsStatics::remove_BackPressed]);
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
#endif // Q_OS_WINPHONE
|
||||
|
||||
hr = QEventDispatcherWinRT::runOnXamlThread([this, d]() {
|
||||
HRESULT hr;
|
||||
ComPtr<Xaml::IWindowStatics> windowStatics;
|
||||
hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_Xaml_Window).Get(),
|
||||
IID_PPV_ARGS(&windowStatics));
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
ComPtr<Xaml::IWindow> window;
|
||||
hr = windowStatics->get_Current(&window);
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
hr = window->Activate();
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
|
||||
d->mainScreen = new QWinRTScreen(window.Get());
|
||||
d->inputContext.reset(new QWinRTInputContext(d->mainScreen));
|
||||
screenAdded(d->mainScreen);
|
||||
return S_OK;
|
||||
});
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
}
|
||||
|
||||
QWinRTIntegration::~QWinRTIntegration()
|
||||
{
|
||||
Q_D(QWinRTIntegration);
|
||||
HRESULT hr;
|
||||
#ifdef Q_OS_WINPHONE
|
||||
for (QHash<HardwareButtonsCallbackRemover, EventRegistrationToken>::const_iterator i = d->buttonsTokens.begin(); i != d->buttonsTokens.end(); ++i) {
|
||||
hr = (d->hardwareButtons.Get()->*i.key())(i.value());
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
}
|
||||
#endif
|
||||
for (QHash<CoreApplicationCallbackRemover, EventRegistrationToken>::const_iterator i = d->applicationTokens.begin(); i != d->applicationTokens.end(); ++i) {
|
||||
hr = (d->application.Get()->*i.key())(i.value());
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
}
|
||||
destroyScreen(d->mainScreen);
|
||||
Windows::Foundation::Uninitialize();
|
||||
}
|
||||
|
||||
bool QWinRTIntegration::succeeded() const
|
||||
{
|
||||
Q_D(const QWinRTIntegration);
|
||||
return d->mainScreen;
|
||||
}
|
||||
|
||||
QAbstractEventDispatcher *QWinRTIntegration::createEventDispatcher() const
|
||||
{
|
||||
return new QWinRTEventDispatcher;
|
||||
@ -112,28 +213,31 @@ QPlatformBackingStore *QWinRTIntegration::createPlatformBackingStore(QWindow *wi
|
||||
|
||||
QPlatformOpenGLContext *QWinRTIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
|
||||
{
|
||||
QWinRTScreen *screen = static_cast<QWinRTScreen *>(context->screen()->handle());
|
||||
return new QWinRTEGLContext(context->format(), context->handle(), screen->eglDisplay(), screen->eglSurface(), screen->eglConfig());
|
||||
return new QWinRTEGLContext(context);
|
||||
}
|
||||
|
||||
QPlatformFontDatabase *QWinRTIntegration::fontDatabase() const
|
||||
{
|
||||
return m_fontDatabase;
|
||||
Q_D(const QWinRTIntegration);
|
||||
return d->fontDatabase;
|
||||
}
|
||||
|
||||
QPlatformInputContext *QWinRTIntegration::inputContext() const
|
||||
{
|
||||
return m_screen->inputContext();
|
||||
Q_D(const QWinRTIntegration);
|
||||
return d->inputContext.data();
|
||||
}
|
||||
|
||||
QPlatformServices *QWinRTIntegration::services() const
|
||||
{
|
||||
return m_services;
|
||||
Q_D(const QWinRTIntegration);
|
||||
return d->platformServices;
|
||||
}
|
||||
|
||||
Qt::KeyboardModifiers QWinRTIntegration::queryKeyboardModifiers() const
|
||||
{
|
||||
return m_screen->keyboardModifiers();
|
||||
Q_D(const QWinRTIntegration);
|
||||
return d->mainScreen->keyboardModifiers();
|
||||
}
|
||||
|
||||
QStringList QWinRTIntegration::themeNames() const
|
||||
@ -149,4 +253,45 @@ name) const
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// System-level integration points
|
||||
|
||||
#ifdef Q_OS_WINPHONE
|
||||
HRESULT QWinRTIntegration::onBackButtonPressed(IInspectable *, IBackPressedEventArgs *args)
|
||||
{
|
||||
Q_D(QWinRTIntegration);
|
||||
|
||||
QKeyEvent backPress(QEvent::KeyPress, Qt::Key_Back, Qt::NoModifier);
|
||||
QKeyEvent backRelease(QEvent::KeyRelease, Qt::Key_Back, Qt::NoModifier);
|
||||
backPress.setAccepted(false);
|
||||
backRelease.setAccepted(false);
|
||||
|
||||
QWindow *window = d->mainScreen->topWindow();
|
||||
QObject *receiver = window ? static_cast<QObject *>(window)
|
||||
: static_cast<QObject *>(QCoreApplication::instance());
|
||||
|
||||
// If the event is ignored, the app go to the background
|
||||
QCoreApplication::sendEvent(receiver, &backPress);
|
||||
QCoreApplication::sendEvent(receiver, &backRelease);
|
||||
args->put_Handled(backPress.isAccepted() || backRelease.isAccepted());
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
#endif // Q_OS_WINPHONE
|
||||
|
||||
HRESULT QWinRTIntegration::onSuspended(IInspectable *, ISuspendingEventArgs *)
|
||||
{
|
||||
QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationSuspended);
|
||||
QWindowSystemInterface::flushWindowSystemEvents();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT QWinRTIntegration::onResume(IInspectable *, IInspectable *)
|
||||
{
|
||||
// First the system invokes onResume and then changes
|
||||
// the visibility of the screen to be active.
|
||||
QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationHidden);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -39,11 +39,33 @@
|
||||
|
||||
#include <qpa/qplatformintegration.h>
|
||||
|
||||
namespace ABI {
|
||||
namespace Windows {
|
||||
namespace ApplicationModel {
|
||||
struct ISuspendingEventArgs;
|
||||
}
|
||||
namespace Foundation {
|
||||
struct IAsyncAction;
|
||||
}
|
||||
#ifdef Q_OS_WINPHONE
|
||||
namespace Phone {
|
||||
namespace UI {
|
||||
namespace Input {
|
||||
struct IBackPressedEventArgs;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
struct IAsyncInfo;
|
||||
struct IInspectable;
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QAbstractEventDispatcher;
|
||||
class QWinRTScreen;
|
||||
|
||||
class QWinRTIntegrationPrivate;
|
||||
class QWinRTIntegration : public QPlatformIntegration
|
||||
{
|
||||
private:
|
||||
@ -53,10 +75,12 @@ public:
|
||||
|
||||
static QWinRTIntegration *create()
|
||||
{
|
||||
QWinRTIntegration *integration = new QWinRTIntegration;
|
||||
return integration->m_success ? integration : 0;
|
||||
QScopedPointer<QWinRTIntegration> integration(new QWinRTIntegration);
|
||||
return integration->succeeded() ? integration.take() : nullptr;
|
||||
}
|
||||
|
||||
bool succeeded() const;
|
||||
|
||||
bool hasCapability(QPlatformIntegration::Capability cap) const;
|
||||
QVariant styleHint(StyleHint hint) const;
|
||||
|
||||
@ -71,11 +95,16 @@ public:
|
||||
|
||||
QStringList themeNames() const;
|
||||
QPlatformTheme *createPlatformTheme(const QString &name) const;
|
||||
|
||||
private:
|
||||
bool m_success;
|
||||
QWinRTScreen *m_screen;
|
||||
QPlatformFontDatabase *m_fontDatabase;
|
||||
QPlatformServices *m_services;
|
||||
#ifdef Q_OS_WINPHONE
|
||||
HRESULT onBackButtonPressed(IInspectable *, ABI::Windows::Phone::UI::Input::IBackPressedEventArgs *args);
|
||||
#endif
|
||||
HRESULT onSuspended(IInspectable *, ABI::Windows::ApplicationModel::ISuspendingEventArgs *);
|
||||
HRESULT onResume(IInspectable *, IInspectable *);
|
||||
|
||||
QScopedPointer<QWinRTIntegrationPrivate> d_ptr;
|
||||
Q_DECLARE_PRIVATE(QWinRTIntegration)
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -36,26 +36,18 @@
|
||||
|
||||
#include "qwinrtscreen.h"
|
||||
|
||||
#define EGL_EGLEXT_PROTOTYPES
|
||||
#include <EGL/eglext.h>
|
||||
#include <d3d11.h>
|
||||
#include <dxgi1_2.h>
|
||||
#ifndef Q_OS_WINPHONE
|
||||
#include <dxgi1_3.h>
|
||||
#endif
|
||||
|
||||
#include "qwinrtbackingstore.h"
|
||||
#include "qwinrtinputcontext.h"
|
||||
#include "qwinrtcursor.h"
|
||||
#include "qwinrteglcontext.h"
|
||||
#include <private/qeventdispatcher_winrt_p.h>
|
||||
|
||||
#include <QtGui/QSurfaceFormat>
|
||||
#include <QtGui/QGuiApplication>
|
||||
#include <QtPlatformSupport/private/qeglconvenience_p.h>
|
||||
#include <qpa/qwindowsysteminterface.h>
|
||||
#include <QtCore/qt_windows.h>
|
||||
#include <QtCore/qfunctions_winrt.h>
|
||||
|
||||
#include <functional>
|
||||
#include <wrl.h>
|
||||
#include <windows.system.h>
|
||||
#include <Windows.Applicationmodel.h>
|
||||
@ -64,12 +56,10 @@
|
||||
#include <windows.ui.h>
|
||||
#include <windows.ui.core.h>
|
||||
#include <windows.ui.input.h>
|
||||
#include <windows.ui.xaml.h>
|
||||
#include <windows.ui.viewmanagement.h>
|
||||
#include <windows.graphics.display.h>
|
||||
#include <windows.foundation.h>
|
||||
#ifdef Q_OS_WINPHONE
|
||||
#include <windows.phone.ui.input.h>
|
||||
#endif
|
||||
|
||||
using namespace Microsoft::WRL;
|
||||
using namespace Microsoft::WRL::Wrappers;
|
||||
@ -77,17 +67,13 @@ using namespace ABI::Windows::ApplicationModel;
|
||||
using namespace ABI::Windows::ApplicationModel::Core;
|
||||
using namespace ABI::Windows::Foundation;
|
||||
using namespace ABI::Windows::System;
|
||||
using namespace ABI::Windows::UI;
|
||||
using namespace ABI::Windows::UI::Core;
|
||||
using namespace ABI::Windows::UI::Input;
|
||||
using namespace ABI::Windows::UI::ViewManagement;
|
||||
using namespace ABI::Windows::Devices::Input;
|
||||
using namespace ABI::Windows::Graphics::Display;
|
||||
#ifdef Q_OS_WINPHONE
|
||||
using namespace ABI::Windows::Phone::UI::Input;
|
||||
#endif
|
||||
|
||||
typedef IEventHandler<IInspectable*> ResumeHandler;
|
||||
typedef IEventHandler<SuspendingEventArgs*> SuspendHandler;
|
||||
typedef ITypedEventHandler<CoreWindow*, WindowActivatedEventArgs*> ActivatedHandler;
|
||||
typedef ITypedEventHandler<CoreWindow*, CoreWindowEventArgs*> ClosedHandler;
|
||||
typedef ITypedEventHandler<CoreWindow*, CharacterReceivedEventArgs*> CharacterReceivedHandler;
|
||||
@ -96,11 +82,7 @@ typedef ITypedEventHandler<CoreWindow*, KeyEventArgs*> KeyHandler;
|
||||
typedef ITypedEventHandler<CoreWindow*, PointerEventArgs*> PointerHandler;
|
||||
typedef ITypedEventHandler<CoreWindow*, WindowSizeChangedEventArgs*> SizeChangedHandler;
|
||||
typedef ITypedEventHandler<CoreWindow*, VisibilityChangedEventArgs*> VisibilityChangedHandler;
|
||||
typedef ITypedEventHandler<CoreWindow*, AutomationProviderRequestedEventArgs*> AutomationProviderRequestedHandler;
|
||||
typedef ITypedEventHandler<DisplayInformation*, IInspectable*> DisplayInformationHandler;
|
||||
#ifdef Q_OS_WINPHONE
|
||||
typedef IEventHandler<BackPressedEventArgs*> BackPressedHandler;
|
||||
#endif
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
@ -419,33 +401,23 @@ static inline Qt::Key qKeyFromCode(quint32 code, int mods)
|
||||
return static_cast<Qt::Key>(code & 0xff);
|
||||
}
|
||||
|
||||
typedef HRESULT (__stdcall ICoreApplication::*CoreApplicationCallbackRemover)(EventRegistrationToken);
|
||||
uint qHash(CoreApplicationCallbackRemover key) { void *ptr = *(void **)(&key); return qHash(ptr); }
|
||||
typedef HRESULT (__stdcall ICoreWindow::*CoreWindowCallbackRemover)(EventRegistrationToken);
|
||||
uint qHash(CoreWindowCallbackRemover key) { void *ptr = *(void **)(&key); return qHash(ptr); }
|
||||
typedef HRESULT (__stdcall IDisplayInformation::*DisplayCallbackRemover)(EventRegistrationToken);
|
||||
uint qHash(DisplayCallbackRemover key) { void *ptr = *(void **)(&key); return qHash(ptr); }
|
||||
#ifdef Q_OS_WINPHONE
|
||||
typedef HRESULT (__stdcall IHardwareButtonsStatics::*HardwareButtonsCallbackRemover)(EventRegistrationToken);
|
||||
uint qHash(HardwareButtonsCallbackRemover key) { void *ptr = *(void **)(&key); return qHash(ptr); }
|
||||
#endif
|
||||
|
||||
class QWinRTScreenPrivate
|
||||
{
|
||||
public:
|
||||
ComPtr<ICoreApplication> application;
|
||||
QTouchDevice *touchDevice;
|
||||
ComPtr<ICoreWindow> coreWindow;
|
||||
ComPtr<Xaml::IDependencyObject> canvas;
|
||||
ComPtr<IApplicationView> view;
|
||||
ComPtr<IDisplayInformation> displayInformation;
|
||||
#ifdef Q_OS_WINPHONE
|
||||
ComPtr<IHardwareButtonsStatics> hardwareButtons;
|
||||
#endif
|
||||
|
||||
QScopedPointer<QWinRTCursor> cursor;
|
||||
#ifdef Q_OS_WINPHONE
|
||||
QScopedPointer<QWinRTInputContext> inputContext;
|
||||
#else
|
||||
ComPtr<QWinRTInputContext> inputContext;
|
||||
#endif
|
||||
|
||||
QHash<quint32, QWindowSystemInterface::TouchPoint> touchPoints;
|
||||
|
||||
QSizeF logicalSize;
|
||||
QSurfaceFormat surfaceFormat;
|
||||
@ -458,68 +430,30 @@ public:
|
||||
#ifndef Q_OS_WINPHONE
|
||||
QHash<quint32, QPair<Qt::Key, QString>> activeKeys;
|
||||
#endif
|
||||
QTouchDevice *touchDevice;
|
||||
QHash<quint32, QWindowSystemInterface::TouchPoint> touchPoints;
|
||||
|
||||
EGLDisplay eglDisplay;
|
||||
EGLSurface eglSurface;
|
||||
EGLConfig eglConfig;
|
||||
|
||||
QHash<CoreApplicationCallbackRemover, EventRegistrationToken> applicationTokens;
|
||||
QHash<CoreWindowCallbackRemover, EventRegistrationToken> windowTokens;
|
||||
QHash<DisplayCallbackRemover, EventRegistrationToken> displayTokens;
|
||||
#ifdef Q_OS_WINPHONE
|
||||
QHash<HardwareButtonsCallbackRemover, EventRegistrationToken> buttonsTokens;
|
||||
#endif
|
||||
};
|
||||
|
||||
QWinRTScreen::QWinRTScreen()
|
||||
// To be called from the XAML thread
|
||||
QWinRTScreen::QWinRTScreen(Xaml::IWindow *xamlWindow)
|
||||
: d_ptr(new QWinRTScreenPrivate)
|
||||
{
|
||||
Q_D(QWinRTScreen);
|
||||
d->orientation = Qt::PrimaryOrientation;
|
||||
d->touchDevice = Q_NULLPTR;
|
||||
d->eglDisplay = EGL_NO_DISPLAY;
|
||||
|
||||
// Obtain the WinRT Application, view, and window
|
||||
HRESULT hr;
|
||||
hr = RoGetActivationFactory(Wrappers::HString::MakeReference(RuntimeClass_Windows_ApplicationModel_Core_CoreApplication).Get(),
|
||||
IID_PPV_ARGS(&d->application));
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
hr = d->application->add_Suspending(Callback<SuspendHandler>(this, &QWinRTScreen::onSuspended).Get(), &d->applicationTokens[&ICoreApplication::remove_Resuming]);
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
hr = d->application->add_Resuming(Callback<ResumeHandler>(this, &QWinRTScreen::onResume).Get(), &d->applicationTokens[&ICoreApplication::remove_Resuming]);
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
|
||||
ComPtr<ICoreApplicationView> view;
|
||||
hr = d->application->GetCurrentView(&view);
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
hr = view->get_CoreWindow(&d->coreWindow);
|
||||
hr = xamlWindow->get_CoreWindow(&d->coreWindow);
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
hr = d->coreWindow->Activate();
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
|
||||
#ifdef Q_OS_WINPHONE
|
||||
d->inputContext.reset(new QWinRTInputContext(this));
|
||||
#else
|
||||
d->inputContext = Make<QWinRTInputContext>(this);
|
||||
#endif
|
||||
|
||||
Rect rect;
|
||||
hr = d->coreWindow->get_Bounds(&rect);
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
d->logicalSize = QSizeF(rect.Width, rect.Height);
|
||||
|
||||
d->surfaceFormat.setAlphaBufferSize(0);
|
||||
d->surfaceFormat.setRedBufferSize(8);
|
||||
d->surfaceFormat.setGreenBufferSize(8);
|
||||
d->surfaceFormat.setBlueBufferSize(8);
|
||||
d->surfaceFormat.setDepthBufferSize(24);
|
||||
d->surfaceFormat.setStencilBufferSize(8);
|
||||
d->surfaceFormat.setRenderableType(QSurfaceFormat::OpenGLES);
|
||||
d->surfaceFormat.setSamples(1);
|
||||
d->surfaceFormat.setSwapBehavior(QSurfaceFormat::DoubleBuffer);
|
||||
|
||||
hr = d->coreWindow->add_KeyDown(Callback<KeyHandler>(this, &QWinRTScreen::onKeyDown).Get(), &d->windowTokens[&ICoreWindow::remove_KeyDown]);
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
hr = d->coreWindow->add_KeyUp(Callback<KeyHandler>(this, &QWinRTScreen::onKeyUp).Get(), &d->windowTokens[&ICoreWindow::remove_KeyUp]);
|
||||
@ -538,24 +472,14 @@ QWinRTScreen::QWinRTScreen()
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
hr = d->coreWindow->add_PointerWheelChanged(Callback<PointerHandler>(this, &QWinRTScreen::onPointerUpdated).Get(), &d->windowTokens[&ICoreWindow::remove_PointerWheelChanged]);
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
#ifndef Q_OS_WINPHONE
|
||||
hr = d->coreWindow->add_SizeChanged(Callback<SizeChangedHandler>(this, &QWinRTScreen::onSizeChanged).Get(), &d->windowTokens[&ICoreWindow::remove_SizeChanged]);
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
#endif
|
||||
hr = d->coreWindow->add_Activated(Callback<ActivatedHandler>(this, &QWinRTScreen::onActivated).Get(), &d->windowTokens[&ICoreWindow::remove_Activated]);
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
hr = d->coreWindow->add_Closed(Callback<ClosedHandler>(this, &QWinRTScreen::onClosed).Get(), &d->windowTokens[&ICoreWindow::remove_Closed]);
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
hr = d->coreWindow->add_VisibilityChanged(Callback<VisibilityChangedHandler>(this, &QWinRTScreen::onVisibilityChanged).Get(), &d->windowTokens[&ICoreWindow::remove_VisibilityChanged]);
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
hr = d->coreWindow->add_AutomationProviderRequested(Callback<AutomationProviderRequestedHandler>(this, &QWinRTScreen::onAutomationProviderRequested).Get(), &d->windowTokens[&ICoreWindow::remove_AutomationProviderRequested]);
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
#ifdef Q_OS_WINPHONE
|
||||
hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Phone_UI_Input_HardwareButtons).Get(), IID_PPV_ARGS(&d->hardwareButtons));
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
hr = d->hardwareButtons->add_BackPressed(Callback<BackPressedHandler>(this, &QWinRTScreen::onBackButtonPressed).Get(), &d->buttonsTokens[&IHardwareButtonsStatics::remove_BackPressed]);
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
#endif // Q_OS_WINPHONE
|
||||
|
||||
// Orientation handling
|
||||
ComPtr<IDisplayInformationStatics> displayInformationStatics;
|
||||
@ -583,45 +507,34 @@ QWinRTScreen::QWinRTScreen()
|
||||
d->orientation = d->nativeOrientation;
|
||||
onOrientationChanged(Q_NULLPTR, Q_NULLPTR);
|
||||
|
||||
d->eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
||||
if (d->eglDisplay == EGL_NO_DISPLAY)
|
||||
qCritical("Failed to initialize EGL display: 0x%x", eglGetError());
|
||||
ComPtr<IApplicationViewStatics2> applicationViewStatics;
|
||||
hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_ViewManagement_ApplicationView).Get(),
|
||||
IID_PPV_ARGS(&applicationViewStatics));
|
||||
RETURN_VOID_IF_FAILED("Could not get ApplicationViewStatics");
|
||||
|
||||
if (!eglInitialize(d->eglDisplay, NULL, NULL))
|
||||
qCritical("Failed to initialize EGL: 0x%x", eglGetError());
|
||||
hr = applicationViewStatics->GetForCurrentView(&d->view);
|
||||
RETURN_VOID_IF_FAILED("Could not access currentView");
|
||||
|
||||
// Check that the device properly supports depth/stencil rendering, and disable them if not
|
||||
ComPtr<ID3D11Device> d3dDevice;
|
||||
const EGLBoolean ok = eglQuerySurfacePointerANGLE(d->eglDisplay, EGL_NO_SURFACE, EGL_DEVICE_EXT, (void **)d3dDevice.GetAddressOf());
|
||||
if (ok && d3dDevice) {
|
||||
ComPtr<IDXGIDevice> dxgiDevice;
|
||||
hr = d3dDevice.As(&dxgiDevice);
|
||||
if (SUCCEEDED(hr)) {
|
||||
ComPtr<IDXGIAdapter> dxgiAdapter;
|
||||
hr = dxgiDevice->GetAdapter(&dxgiAdapter);
|
||||
if (SUCCEEDED(hr)) {
|
||||
ComPtr<IDXGIAdapter2> dxgiAdapter2;
|
||||
hr = dxgiAdapter.As(&dxgiAdapter2);
|
||||
if (SUCCEEDED(hr)) {
|
||||
DXGI_ADAPTER_DESC2 desc;
|
||||
hr = dxgiAdapter2->GetDesc2(&desc);
|
||||
if (SUCCEEDED(hr)) {
|
||||
// The following GPUs do not render properly with depth/stencil
|
||||
if ((desc.VendorId == 0x4d4f4351 && desc.DeviceId == 0x32303032)) { // Qualcomm Adreno 225
|
||||
d->surfaceFormat.setDepthBufferSize(-1);
|
||||
d->surfaceFormat.setStencilBufferSize(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Create a canvas and set it as the window content. Eventually, this should have its own method so multiple "screens" can be added
|
||||
ComPtr<Xaml::Controls::ICanvas> canvas;
|
||||
hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_UI_Xaml_Controls_Canvas).Get(), &canvas);
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
ComPtr<Xaml::IFrameworkElement> frameworkElement;
|
||||
hr = canvas.As(&frameworkElement);
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
hr = frameworkElement->put_Width(d->logicalSize.width());
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
hr = frameworkElement->put_Height(d->logicalSize.height());
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
ComPtr<Xaml::IUIElement> uiElement;
|
||||
hr = canvas.As(&uiElement);
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
hr = xamlWindow->put_Content(uiElement.Get());
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
hr = canvas.As(&d->canvas);
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
|
||||
d->eglConfig = q_configFromGLFormat(d->eglDisplay, d->surfaceFormat);
|
||||
d->surfaceFormat = q_glFormatFromConfig(d->eglDisplay, d->eglConfig, d->surfaceFormat);
|
||||
d->eglSurface = eglCreateWindowSurface(d->eglDisplay, d->eglConfig, d->coreWindow.Get(), NULL);
|
||||
if (d->eglSurface == EGL_NO_SURFACE)
|
||||
qCritical("Failed to create EGL window surface: 0x%x", eglGetError());
|
||||
d->cursor.reset(new QWinRTCursor);
|
||||
}
|
||||
|
||||
QWinRTScreen::~QWinRTScreen()
|
||||
@ -629,16 +542,20 @@ QWinRTScreen::~QWinRTScreen()
|
||||
Q_D(QWinRTScreen);
|
||||
|
||||
// Unregister callbacks
|
||||
for (QHash<CoreApplicationCallbackRemover, EventRegistrationToken>::const_iterator i = d->applicationTokens.begin(); i != d->applicationTokens.end(); ++i)
|
||||
(d->application.Get()->*i.key())(i.value());
|
||||
for (QHash<CoreWindowCallbackRemover, EventRegistrationToken>::const_iterator i = d->windowTokens.begin(); i != d->windowTokens.end(); ++i)
|
||||
(d->coreWindow.Get()->*i.key())(i.value());
|
||||
for (QHash<DisplayCallbackRemover, EventRegistrationToken>::const_iterator i = d->displayTokens.begin(); i != d->displayTokens.end(); ++i)
|
||||
(d->displayInformation.Get()->*i.key())(i.value());
|
||||
#ifdef Q_OS_WINPHONE
|
||||
for (QHash<HardwareButtonsCallbackRemover, EventRegistrationToken>::const_iterator i = d->buttonsTokens.begin(); i != d->buttonsTokens.end(); ++i)
|
||||
(d->hardwareButtons.Get()->*i.key())(i.value());
|
||||
#endif
|
||||
HRESULT hr;
|
||||
hr = QEventDispatcherWinRT::runOnXamlThread([this, d]() {
|
||||
HRESULT hr;
|
||||
for (QHash<CoreWindowCallbackRemover, EventRegistrationToken>::const_iterator i = d->windowTokens.begin(); i != d->windowTokens.end(); ++i) {
|
||||
hr = (d->coreWindow.Get()->*i.key())(i.value());
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
}
|
||||
for (QHash<DisplayCallbackRemover, EventRegistrationToken>::const_iterator i = d->displayTokens.begin(); i != d->displayTokens.end(); ++i) {
|
||||
hr = (d->displayInformation.Get()->*i.key())(i.value());
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
}
|
||||
return hr;
|
||||
});
|
||||
RETURN_VOID_IF_FAILED("Failed to unregister screen event callbacks");
|
||||
}
|
||||
|
||||
QRect QWinRTScreen::geometry() const
|
||||
@ -657,12 +574,6 @@ QImage::Format QWinRTScreen::format() const
|
||||
return QImage::Format_ARGB32_Premultiplied;
|
||||
}
|
||||
|
||||
QSurfaceFormat QWinRTScreen::surfaceFormat() const
|
||||
{
|
||||
Q_D(const QWinRTScreen);
|
||||
return d->surfaceFormat;
|
||||
}
|
||||
|
||||
QSizeF QWinRTScreen::physicalSize() const
|
||||
{
|
||||
Q_D(const QWinRTScreen);
|
||||
@ -682,21 +593,9 @@ qreal QWinRTScreen::scaleFactor() const
|
||||
return d->scaleFactor;
|
||||
}
|
||||
|
||||
QWinRTInputContext *QWinRTScreen::inputContext() const
|
||||
{
|
||||
Q_D(const QWinRTScreen);
|
||||
#ifdef Q_OS_WINPHONE
|
||||
return d->inputContext.data();
|
||||
#else
|
||||
return d->inputContext.Get();
|
||||
#endif
|
||||
}
|
||||
|
||||
QPlatformCursor *QWinRTScreen::cursor() const
|
||||
{
|
||||
Q_D(const QWinRTScreen);
|
||||
if (!d->cursor)
|
||||
const_cast<QWinRTScreenPrivate *>(d)->cursor.reset(new QWinRTCursor);
|
||||
return d->cursor.data();
|
||||
}
|
||||
|
||||
@ -744,22 +643,10 @@ ICoreWindow *QWinRTScreen::coreWindow() const
|
||||
return d->coreWindow.Get();
|
||||
}
|
||||
|
||||
EGLDisplay QWinRTScreen::eglDisplay() const
|
||||
Xaml::IDependencyObject *QWinRTScreen::canvas() const
|
||||
{
|
||||
Q_D(const QWinRTScreen);
|
||||
return d->eglDisplay;
|
||||
}
|
||||
|
||||
EGLSurface QWinRTScreen::eglSurface() const
|
||||
{
|
||||
Q_D(const QWinRTScreen);
|
||||
return d->eglSurface;
|
||||
}
|
||||
|
||||
EGLConfig QWinRTScreen::eglConfig() const
|
||||
{
|
||||
Q_D(const QWinRTScreen);
|
||||
return d->eglConfig;
|
||||
return d->canvas.Get();
|
||||
}
|
||||
|
||||
QWindow *QWinRTScreen::topWindow() const
|
||||
@ -809,6 +696,20 @@ void QWinRTScreen::lower(QWindow *window)
|
||||
handleExpose();
|
||||
}
|
||||
|
||||
void QWinRTScreen::updateWindowTitle()
|
||||
{
|
||||
Q_D(QWinRTScreen);
|
||||
|
||||
QWindow *window = topWindow();
|
||||
if (!window)
|
||||
return;
|
||||
|
||||
const QString title = window->title();
|
||||
HStringReference titleRef(reinterpret_cast<LPCWSTR>(title.utf16()), title.length());
|
||||
HRESULT hr = d->view->put_Title(titleRef.Get());
|
||||
RETURN_VOID_IF_FAILED("Unable to set window title");
|
||||
}
|
||||
|
||||
void QWinRTScreen::handleExpose()
|
||||
{
|
||||
Q_D(QWinRTScreen);
|
||||
@ -1055,17 +956,6 @@ HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *, IPointerEventArgs *args)
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT QWinRTScreen::onAutomationProviderRequested(ICoreWindow *, IAutomationProviderRequestedEventArgs *args)
|
||||
{
|
||||
#ifndef Q_OS_WINPHONE
|
||||
Q_D(const QWinRTScreen);
|
||||
args->put_AutomationProvider(d->inputContext.Get());
|
||||
#else
|
||||
Q_UNUSED(args)
|
||||
#endif
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT QWinRTScreen::onSizeChanged(ICoreWindow *, IWindowSizeChangedEventArgs *)
|
||||
{
|
||||
Q_D(QWinRTScreen);
|
||||
@ -1075,18 +965,14 @@ HRESULT QWinRTScreen::onSizeChanged(ICoreWindow *, IWindowSizeChangedEventArgs *
|
||||
hr = d->coreWindow->get_Bounds(&size);
|
||||
RETURN_OK_IF_FAILED("Failed to get window bounds");
|
||||
QSizeF logicalSize = QSizeF(size.Width, size.Height);
|
||||
#ifndef Q_OS_WINPHONE // This handler is called from orientation changed, in which case we should always update the size
|
||||
if (d->logicalSize == logicalSize)
|
||||
return S_OK;
|
||||
#endif
|
||||
|
||||
d->logicalSize = logicalSize;
|
||||
if (d->eglDisplay) {
|
||||
const QRect newGeometry = geometry();
|
||||
QWindowSystemInterface::handleScreenGeometryChange(screen(), newGeometry, newGeometry);
|
||||
QPlatformScreen::resizeMaximizedWindows();
|
||||
handleExpose();
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@ -1110,31 +996,6 @@ HRESULT QWinRTScreen::onActivated(ICoreWindow *, IWindowActivatedEventArgs *args
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT QWinRTScreen::onSuspended(IInspectable *, ISuspendingEventArgs *)
|
||||
{
|
||||
#ifndef Q_OS_WINPHONE
|
||||
Q_D(QWinRTScreen);
|
||||
ComPtr<ID3D11Device> d3dDevice;
|
||||
const EGLBoolean ok = eglQuerySurfacePointerANGLE(d->eglDisplay, EGL_NO_SURFACE, EGL_DEVICE_EXT, (void **)d3dDevice.GetAddressOf());
|
||||
if (ok && d3dDevice) {
|
||||
ComPtr<IDXGIDevice3> dxgiDevice;
|
||||
if (SUCCEEDED(d3dDevice.As(&dxgiDevice)))
|
||||
dxgiDevice->Trim();
|
||||
}
|
||||
#endif
|
||||
QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationSuspended);
|
||||
QWindowSystemInterface::flushWindowSystemEvents();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT QWinRTScreen::onResume(IInspectable *, IInspectable *)
|
||||
{
|
||||
// First the system invokes onResume and then changes
|
||||
// the visibility of the screen to be active.
|
||||
QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationHidden);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT QWinRTScreen::onClosed(ICoreWindow *, ICoreWindowEventArgs *)
|
||||
{
|
||||
foreach (QWindow *w, QGuiApplication::topLevelWindows())
|
||||
@ -1165,10 +1026,6 @@ HRESULT QWinRTScreen::onOrientationChanged(IDisplayInformation *, IInspectable *
|
||||
d->orientation = newOrientation;
|
||||
QWindowSystemInterface::handleScreenOrientationChange(screen(), d->orientation);
|
||||
}
|
||||
|
||||
#ifdef Q_OS_WINPHONE // The size changed handler is ignored in favor of this callback
|
||||
onSizeChanged(Q_NULLPTR, Q_NULLPTR);
|
||||
#endif
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@ -1205,27 +1062,4 @@ HRESULT QWinRTScreen::onDpiChanged(IDisplayInformation *, IInspectable *)
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
#ifdef Q_OS_WINPHONE
|
||||
HRESULT QWinRTScreen::onBackButtonPressed(IInspectable *, IBackPressedEventArgs *args)
|
||||
{
|
||||
Q_D(QWinRTScreen);
|
||||
|
||||
QKeyEvent backPress(QEvent::KeyPress, Qt::Key_Back, Qt::NoModifier);
|
||||
QKeyEvent backRelease(QEvent::KeyRelease, Qt::Key_Back, Qt::NoModifier);
|
||||
backPress.setAccepted(false);
|
||||
backRelease.setAccepted(false);
|
||||
|
||||
QObject *receiver = d->visibleWindows.isEmpty()
|
||||
? static_cast<QObject *>(QGuiApplication::instance())
|
||||
: static_cast<QObject *>(d->visibleWindows.first());
|
||||
|
||||
// If the event is ignored, the app will suspend
|
||||
QGuiApplication::sendEvent(receiver, &backPress);
|
||||
QGuiApplication::sendEvent(receiver, &backRelease);
|
||||
args->put_Handled(backPress.isAccepted() || backRelease.isAccepted());
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
#endif // Q_OS_WINPHONE
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -40,8 +40,6 @@
|
||||
#include <qpa/qplatformscreen.h>
|
||||
#include <qpa/qwindowsysteminterface.h>
|
||||
|
||||
#include <EGL/egl.h>
|
||||
|
||||
namespace ABI {
|
||||
namespace Windows {
|
||||
namespace ApplicationModel {
|
||||
@ -59,21 +57,16 @@ namespace ABI {
|
||||
struct IWindowActivatedEventArgs;
|
||||
struct IWindowSizeChangedEventArgs;
|
||||
}
|
||||
namespace Xaml {
|
||||
struct IDependencyObject;
|
||||
struct IWindow;
|
||||
}
|
||||
}
|
||||
namespace Graphics {
|
||||
namespace Display {
|
||||
struct IDisplayInformation;
|
||||
}
|
||||
}
|
||||
#ifdef Q_OS_WINPHONE
|
||||
namespace Phone {
|
||||
namespace UI {
|
||||
namespace Input {
|
||||
struct IBackPressedEventArgs;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
struct IInspectable;
|
||||
@ -81,23 +74,20 @@ struct IInspectable;
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QTouchDevice;
|
||||
class QWinRTEGLContext;
|
||||
class QWinRTCursor;
|
||||
class QWinRTInputContext;
|
||||
class QWinRTScreenPrivate;
|
||||
class QWinRTScreen : public QPlatformScreen
|
||||
{
|
||||
public:
|
||||
explicit QWinRTScreen();
|
||||
explicit QWinRTScreen(ABI::Windows::UI::Xaml::IWindow *xamlWindow);
|
||||
~QWinRTScreen();
|
||||
QRect geometry() const;
|
||||
int depth() const;
|
||||
QImage::Format format() const;
|
||||
QSurfaceFormat surfaceFormat() const;
|
||||
QSizeF physicalSize() const Q_DECL_OVERRIDE;
|
||||
QDpi logicalDpi() const Q_DECL_OVERRIDE;
|
||||
qreal scaleFactor() const;
|
||||
QWinRTInputContext *inputContext() const;
|
||||
QPlatformCursor *cursor() const;
|
||||
Qt::KeyboardModifiers keyboardModifiers() const;
|
||||
|
||||
@ -110,10 +100,10 @@ public:
|
||||
void raise(QWindow *window);
|
||||
void lower(QWindow *window);
|
||||
|
||||
void updateWindowTitle();
|
||||
|
||||
ABI::Windows::UI::Core::ICoreWindow *coreWindow() const;
|
||||
EGLDisplay eglDisplay() const; // To opengl context
|
||||
EGLSurface eglSurface() const; // To window
|
||||
EGLConfig eglConfig() const;
|
||||
ABI::Windows::UI::Xaml::IDependencyObject *canvas() const;
|
||||
|
||||
private:
|
||||
void handleExpose();
|
||||
@ -127,20 +117,13 @@ private:
|
||||
HRESULT onSizeChanged(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IWindowSizeChangedEventArgs *);
|
||||
|
||||
HRESULT onActivated(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IWindowActivatedEventArgs *);
|
||||
HRESULT onSuspended(IInspectable *, ABI::Windows::ApplicationModel::ISuspendingEventArgs *);
|
||||
HRESULT onResume(IInspectable *, IInspectable *);
|
||||
|
||||
HRESULT onClosed(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::ICoreWindowEventArgs *);
|
||||
HRESULT onVisibilityChanged(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IVisibilityChangedEventArgs *);
|
||||
HRESULT onAutomationProviderRequested(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IAutomationProviderRequestedEventArgs *);
|
||||
|
||||
HRESULT onOrientationChanged(ABI::Windows::Graphics::Display::IDisplayInformation *, IInspectable *);
|
||||
HRESULT onDpiChanged(ABI::Windows::Graphics::Display::IDisplayInformation *, IInspectable *);
|
||||
|
||||
#ifdef Q_OS_WINPHONE
|
||||
HRESULT onBackButtonPressed(IInspectable *, ABI::Windows::Phone::UI::Input::IBackPressedEventArgs *args);
|
||||
#endif
|
||||
|
||||
QScopedPointer<QWinRTScreenPrivate> d_ptr;
|
||||
Q_DECLARE_PRIVATE(QWinRTScreen)
|
||||
};
|
||||
|
@ -36,47 +36,138 @@
|
||||
|
||||
#include "qwinrtwindow.h"
|
||||
#include "qwinrtscreen.h"
|
||||
#include <private/qeventdispatcher_winrt_p.h>
|
||||
|
||||
#include <qpa/qwindowsysteminterface.h>
|
||||
#include <qpa/qplatformscreen.h>
|
||||
#include <QtGui/QGuiApplication>
|
||||
#include <QtGui/QWindow>
|
||||
#include <QtGui/QOpenGLContext>
|
||||
#include <EGL/egl.h>
|
||||
#define EGL_EGLEXT_PROTOTYPES
|
||||
#include <EGL/eglext.h>
|
||||
|
||||
#include <qfunctions_winrt.h>
|
||||
#include <windows.ui.viewmanagement.h>
|
||||
#include <qpa/qplatformscreen.h>
|
||||
#include <qpa/qwindowsysteminterface.h>
|
||||
#include <QtGui/QGuiApplication>
|
||||
#include <QtGui/QOpenGLContext>
|
||||
#include <QtGui/QWindow>
|
||||
#include <QtPlatformSupport/private/qeglconvenience_p.h>
|
||||
|
||||
#include <functional>
|
||||
#include <wrl.h>
|
||||
#include <windows.foundation.h>
|
||||
#include <windows.foundation.collections.h>
|
||||
#include <windows.ui.xaml.h>
|
||||
#include <windows.ui.xaml.controls.h>
|
||||
#include <windows.ui.viewmanagement.h>
|
||||
|
||||
using namespace ABI::Windows::UI::ViewManagement;
|
||||
using namespace Microsoft::WRL;
|
||||
using namespace Microsoft::WRL::Wrappers;
|
||||
using namespace ABI::Windows::Foundation;
|
||||
using namespace ABI::Windows::Foundation::Collections;
|
||||
using namespace ABI::Windows::UI;
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QWinRTWindowPrivate
|
||||
{
|
||||
public:
|
||||
QWinRTScreen *screen;
|
||||
|
||||
QSurfaceFormat surfaceFormat;
|
||||
QString windowTitle;
|
||||
|
||||
ComPtr<Xaml::Controls::ISwapChainPanel> swapChainPanel;
|
||||
};
|
||||
|
||||
QWinRTWindow::QWinRTWindow(QWindow *window)
|
||||
: QPlatformWindow(window)
|
||||
, m_screen(static_cast<QWinRTScreen*>(screen()))
|
||||
, d_ptr(new QWinRTWindowPrivate)
|
||||
{
|
||||
Q_D(QWinRTWindow);
|
||||
|
||||
d->screen = static_cast<QWinRTScreen *>(screen());
|
||||
setWindowFlags(window->flags());
|
||||
setWindowState(window->windowState());
|
||||
setWindowTitle(window->title());
|
||||
handleContentOrientationChange(window->contentOrientation());
|
||||
|
||||
d->surfaceFormat.setAlphaBufferSize(0);
|
||||
d->surfaceFormat.setRedBufferSize(8);
|
||||
d->surfaceFormat.setGreenBufferSize(8);
|
||||
d->surfaceFormat.setBlueBufferSize(8);
|
||||
d->surfaceFormat.setDepthBufferSize(24);
|
||||
d->surfaceFormat.setStencilBufferSize(8);
|
||||
d->surfaceFormat.setRenderableType(QSurfaceFormat::OpenGLES);
|
||||
d->surfaceFormat.setSamples(1);
|
||||
d->surfaceFormat.setSwapBehavior(QSurfaceFormat::DoubleBuffer);
|
||||
|
||||
HRESULT hr;
|
||||
hr = QEventDispatcherWinRT::runOnXamlThread([this, d]() {
|
||||
// Create a new swapchain and place it inside the canvas
|
||||
HRESULT hr;
|
||||
hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_UI_Xaml_Controls_SwapChainPanel).Get(),
|
||||
&d->swapChainPanel);
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
ComPtr<Xaml::IUIElement> uiElement;
|
||||
hr = d->swapChainPanel.As(&uiElement);
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
|
||||
ComPtr<Xaml::IDependencyObject> canvas = d->screen->canvas();
|
||||
ComPtr<Xaml::Controls::IPanel> panel;
|
||||
hr = canvas.As(&panel);
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
ComPtr<IVector<Xaml::UIElement *>> children;
|
||||
hr = panel->get_Children(&children);
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
hr = children->Append(uiElement.Get());
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
return S_OK;
|
||||
});
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
|
||||
setGeometry(window->geometry());
|
||||
}
|
||||
|
||||
QWinRTWindow::~QWinRTWindow()
|
||||
{
|
||||
m_screen->removeWindow(window());
|
||||
Q_D(QWinRTWindow);
|
||||
|
||||
HRESULT hr;
|
||||
hr = QEventDispatcherWinRT::runOnXamlThread([d]() {
|
||||
HRESULT hr;
|
||||
ComPtr<Xaml::IDependencyObject> canvas = d->screen->canvas();
|
||||
ComPtr<Xaml::Controls::IPanel> panel;
|
||||
hr = canvas.As(&panel);
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
ComPtr<IVector<Xaml::UIElement *>> children;
|
||||
hr = panel->get_Children(&children);
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
|
||||
ComPtr<Xaml::IUIElement> uiElement;
|
||||
hr = d->swapChainPanel.As(&uiElement);
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
quint32 index;
|
||||
boolean found;
|
||||
hr = children->IndexOf(uiElement.Get(), &index, &found);
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
if (found) {
|
||||
hr = children->RemoveAt(index);
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
}
|
||||
return S_OK;
|
||||
});
|
||||
RETURN_VOID_IF_FAILED("Failed to completely destroy window resources, likely because the application is shutting down");
|
||||
}
|
||||
|
||||
QSurfaceFormat QWinRTWindow::format() const
|
||||
{
|
||||
return m_screen->surfaceFormat();
|
||||
Q_D(const QWinRTWindow);
|
||||
return d->surfaceFormat;
|
||||
}
|
||||
|
||||
bool QWinRTWindow::isActive() const
|
||||
{
|
||||
return m_screen->topWindow() == window();
|
||||
Q_D(const QWinRTWindow);
|
||||
return d->screen->topWindow() == window();
|
||||
}
|
||||
|
||||
bool QWinRTWindow::isExposed() const
|
||||
@ -87,55 +178,70 @@ bool QWinRTWindow::isExposed() const
|
||||
|
||||
void QWinRTWindow::setGeometry(const QRect &rect)
|
||||
{
|
||||
Q_D(QWinRTWindow);
|
||||
|
||||
if (window()->isTopLevel()) {
|
||||
QPlatformWindow::setGeometry(m_screen->geometry());
|
||||
QPlatformWindow::setGeometry(d->screen->geometry());
|
||||
QWindowSystemInterface::handleGeometryChange(window(), geometry());
|
||||
} else {
|
||||
QPlatformWindow::setGeometry(rect);
|
||||
QWindowSystemInterface::handleGeometryChange(window(), rect);
|
||||
}
|
||||
|
||||
HRESULT hr;
|
||||
hr = QEventDispatcherWinRT::runOnXamlThread([this, d]() {
|
||||
HRESULT hr;
|
||||
ComPtr<Xaml::IFrameworkElement> frameworkElement;
|
||||
hr = d->swapChainPanel.As(&frameworkElement);
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
const QSizeF size = QSizeF(geometry().size()) / d->screen->scaleFactor();
|
||||
hr = frameworkElement->put_Width(size.width());
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
hr = frameworkElement->put_Height(size.height());
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
return S_OK;
|
||||
});
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
}
|
||||
|
||||
void QWinRTWindow::setVisible(bool visible)
|
||||
{
|
||||
Q_D(QWinRTWindow);
|
||||
if (!window()->isTopLevel())
|
||||
return;
|
||||
if (visible)
|
||||
m_screen->addWindow(window());
|
||||
d->screen->addWindow(window());
|
||||
else
|
||||
m_screen->removeWindow(window());
|
||||
d->screen->removeWindow(window());
|
||||
}
|
||||
|
||||
void QWinRTWindow::setWindowTitle(const QString &title)
|
||||
{
|
||||
ComPtr<IApplicationViewStatics2> statics;
|
||||
HRESULT hr;
|
||||
|
||||
hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_ViewManagement_ApplicationView).Get(),
|
||||
IID_PPV_ARGS(&statics));
|
||||
RETURN_VOID_IF_FAILED("Could not get ApplicationViewStatics");
|
||||
|
||||
ComPtr<IApplicationView> view;
|
||||
hr = statics->GetForCurrentView(&view);
|
||||
RETURN_VOID_IF_FAILED("Could not access currentView");
|
||||
|
||||
HStringReference str(reinterpret_cast<LPCWSTR>(title.utf16()), title.length());
|
||||
hr = view->put_Title(str.Get());
|
||||
RETURN_VOID_IF_FAILED("Unable to set window title");
|
||||
Q_D(QWinRTWindow);
|
||||
d->windowTitle = title;
|
||||
d->screen->updateWindowTitle();
|
||||
}
|
||||
|
||||
void QWinRTWindow::raise()
|
||||
{
|
||||
Q_D(QWinRTWindow);
|
||||
if (!window()->isTopLevel())
|
||||
return;
|
||||
m_screen->raise(window());
|
||||
d->screen->raise(window());
|
||||
}
|
||||
|
||||
void QWinRTWindow::lower()
|
||||
{
|
||||
Q_D(QWinRTWindow);
|
||||
if (!window()->isTopLevel())
|
||||
return;
|
||||
m_screen->lower(window());
|
||||
d->screen->lower(window());
|
||||
}
|
||||
|
||||
WId QWinRTWindow::winId() const
|
||||
{
|
||||
Q_D(const QWinRTWindow);
|
||||
return WId(d->swapChainPanel.Get());
|
||||
}
|
||||
|
||||
qreal QWinRTWindow::devicePixelRatio() const
|
||||
|
@ -42,8 +42,7 @@
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QWinRTScreen;
|
||||
|
||||
class QWinRTWindowPrivate;
|
||||
class QWinRTWindow : public QPlatformWindow
|
||||
{
|
||||
public:
|
||||
@ -59,10 +58,13 @@ public:
|
||||
void raise();
|
||||
void lower();
|
||||
|
||||
WId winId() const Q_DECL_OVERRIDE;
|
||||
|
||||
qreal devicePixelRatio() const Q_DECL_OVERRIDE;
|
||||
|
||||
private:
|
||||
QWinRTScreen *m_screen;
|
||||
QScopedPointer<QWinRTWindowPrivate> d_ptr;
|
||||
Q_DECLARE_PRIVATE(QWinRTWindow)
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -237,7 +237,11 @@ static QVariant::Type qDecodeMYSQLType(int mysqltype, uint flags)
|
||||
QVariant::Type type;
|
||||
switch (mysqltype) {
|
||||
case FIELD_TYPE_TINY :
|
||||
type = static_cast<QVariant::Type>((flags & UNSIGNED_FLAG) ? QMetaType::UChar : QMetaType::Char);
|
||||
break;
|
||||
case FIELD_TYPE_SHORT :
|
||||
type = static_cast<QVariant::Type>((flags & UNSIGNED_FLAG) ? QMetaType::UShort : QMetaType::Short);
|
||||
break;
|
||||
case FIELD_TYPE_LONG :
|
||||
case FIELD_TYPE_INT24 :
|
||||
type = (flags & UNSIGNED_FLAG) ? QVariant::UInt : QVariant::Int;
|
||||
@ -316,14 +320,12 @@ static bool qIsBlob(int t)
|
||||
|
||||
static bool qIsInteger(int t)
|
||||
{
|
||||
return t == MYSQL_TYPE_TINY
|
||||
|| t == MYSQL_TYPE_SHORT
|
||||
|| t == MYSQL_TYPE_LONG
|
||||
|| t == MYSQL_TYPE_LONGLONG
|
||||
|| t == MYSQL_TYPE_INT24;
|
||||
return t == QMetaType::Char || t == QMetaType::UChar
|
||||
|| t == QMetaType::Short || t == QMetaType::UShort
|
||||
|| t == QMetaType::Int || t == QMetaType::UInt
|
||||
|| t == QMetaType::LongLong || t == QMetaType::ULongLong;
|
||||
}
|
||||
|
||||
|
||||
void QMYSQLResultPrivate::bindBlobs()
|
||||
{
|
||||
int i;
|
||||
@ -371,14 +373,9 @@ bool QMYSQLResultPrivate::bindInValues()
|
||||
// after mysql_stmt_exec() in QMYSQLResult::exec()
|
||||
fieldInfo->length = 0;
|
||||
hasBlobs = true;
|
||||
} else if (qIsInteger(f.type)) {
|
||||
fieldInfo->length = 8;
|
||||
} else {
|
||||
// fieldInfo->length specifies the display width, which may be too
|
||||
// small to hold valid integer values (see
|
||||
// http://dev.mysql.com/doc/refman/5.0/en/numeric-types.html ), so
|
||||
// always use the MAX_BIGINT_WIDTH for integer types
|
||||
if (qIsInteger(fieldInfo->type)) {
|
||||
fieldInfo->length = MAX_BIGINT_WIDTH;
|
||||
}
|
||||
fieldInfo->type = MYSQL_TYPE_STRING;
|
||||
}
|
||||
bind = &inBinds[i];
|
||||
@ -598,6 +595,9 @@ QVariant QMYSQLResult::data(int field)
|
||||
if (f.nullIndicator)
|
||||
return QVariant(f.type);
|
||||
|
||||
if (qIsInteger(f.type))
|
||||
return QVariant(f.type, f.outField);
|
||||
|
||||
if (f.type != QVariant::ByteArray)
|
||||
val = toUnicode(d->driver->d_func()->tc, f.outField, f.bufLength);
|
||||
} else {
|
||||
@ -605,18 +605,24 @@ QVariant QMYSQLResult::data(int field)
|
||||
// NULL value
|
||||
return QVariant(f.type);
|
||||
}
|
||||
|
||||
fieldLength = mysql_fetch_lengths(d->result)[field];
|
||||
|
||||
if (f.type != QVariant::ByteArray)
|
||||
val = toUnicode(d->driver->d_func()->tc, d->row[field], fieldLength);
|
||||
}
|
||||
|
||||
switch(f.type) {
|
||||
switch (static_cast<int>(f.type)) {
|
||||
case QVariant::LongLong:
|
||||
return QVariant(val.toLongLong());
|
||||
case QVariant::ULongLong:
|
||||
return QVariant(val.toULongLong());
|
||||
case QMetaType::Char:
|
||||
case QMetaType::Short:
|
||||
case QVariant::Int:
|
||||
return QVariant(val.toInt());
|
||||
case QMetaType::UChar:
|
||||
case QMetaType::UShort:
|
||||
case QVariant::UInt:
|
||||
return QVariant(val.toUInt());
|
||||
case QVariant::Double: {
|
||||
|
@ -40,7 +40,6 @@
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class Config;
|
||||
class Node;
|
||||
class QString;
|
||||
class QDocDatabase;
|
||||
|
||||
|
@ -157,11 +157,11 @@ QString CppCodeMarker::markedUpSynopsis(const Node *node,
|
||||
synopsis += "(";
|
||||
if (!func->parameters().isEmpty()) {
|
||||
//synopsis += QLatin1Char(' ');
|
||||
QList<Parameter>::ConstIterator p = func->parameters().constBegin();
|
||||
QVector<Parameter>::ConstIterator p = func->parameters().constBegin();
|
||||
while (p != func->parameters().constEnd()) {
|
||||
if (p != func->parameters().constBegin())
|
||||
synopsis += ", ";
|
||||
synopsis += typified((*p).leftType());
|
||||
synopsis += typified((*p).dataType());
|
||||
if (style != Subpage && !(*p).name().isEmpty())
|
||||
synopsis +=
|
||||
"<@param>" + protect((*p).name()) + "</@param>";
|
||||
@ -328,11 +328,11 @@ QString CppCodeMarker::markedUpQmlItem(const Node* node, bool summary)
|
||||
synopsis = name;
|
||||
synopsis += QLatin1Char('(');
|
||||
if (!func->parameters().isEmpty()) {
|
||||
QList<Parameter>::ConstIterator p = func->parameters().constBegin();
|
||||
QVector<Parameter>::ConstIterator p = func->parameters().constBegin();
|
||||
while (p != func->parameters().constEnd()) {
|
||||
if (p != func->parameters().constBegin())
|
||||
synopsis += ", ";
|
||||
synopsis += typified((*p).leftType());
|
||||
synopsis += typified((*p).dataType());
|
||||
if (!(*p).name().isEmpty()) {
|
||||
if (!synopsis.endsWith(QLatin1Char('(')))
|
||||
synopsis += QLatin1Char(' ');
|
||||
|
@ -54,6 +54,7 @@ static bool inMacroCommand_ = false;
|
||||
static bool parsingHeaderFile_ = false;
|
||||
QStringList CppCodeParser::exampleFiles;
|
||||
QStringList CppCodeParser::exampleDirs;
|
||||
CppCodeParser* CppCodeParser::cppParser_ = 0;
|
||||
|
||||
/*!
|
||||
The constructor initializes some regular expressions
|
||||
@ -63,6 +64,7 @@ CppCodeParser::CppCodeParser()
|
||||
: varComment("/\\*\\s*([a-zA-Z_0-9]+)\\s*\\*/"), sep("(?:<[^>]+>)?::")
|
||||
{
|
||||
reset();
|
||||
cppParser_ = this;
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -374,12 +376,12 @@ Node* CppCodeParser::processTopicCommand(const Doc& doc,
|
||||
}
|
||||
else {
|
||||
func->setMetaness(FunctionNode::MacroWithParams);
|
||||
QList<Parameter> params = func->parameters();
|
||||
QVector<Parameter> params = func->parameters();
|
||||
for (int i = 0; i < params.size(); ++i) {
|
||||
Parameter ¶m = params[i];
|
||||
if (param.name().isEmpty() && !param.leftType().isEmpty()
|
||||
&& param.leftType() != "...")
|
||||
param = Parameter("", "", param.leftType());
|
||||
if (param.name().isEmpty() && !param.dataType().isEmpty()
|
||||
&& param.dataType() != "...")
|
||||
param = Parameter("", "", param.dataType());
|
||||
}
|
||||
func->setParameters(params);
|
||||
}
|
||||
@ -685,10 +687,10 @@ bool CppCodeParser::splitQmlPropertyArg(const QString& arg,
|
||||
<type> <QML-type>::<name>(<param>, <param>, ...)
|
||||
<type> <QML-module>::<QML-type>::<name>(<param>, <param>, ...)
|
||||
|
||||
This function splits the argument into one of those two
|
||||
forms, sets \a module, \a qmlTypeName, and \a name, and returns
|
||||
true. If the argument doesn't match either form, an error
|
||||
message is emitted and false is returned.
|
||||
This function splits the \a{arg}ument into one of those
|
||||
two forms, sets \a type, \a module, and \a qmlTypeName,
|
||||
and returns true. If the argument doesn't match either
|
||||
form, an error message is emitted and false is returned.
|
||||
|
||||
\note The two QML types \e{Component} and \e{QtObject} never
|
||||
have a module qualifier.
|
||||
@ -698,22 +700,22 @@ bool CppCodeParser::splitQmlMethodArg(const QString& arg,
|
||||
QString& module,
|
||||
QString& qmlTypeName)
|
||||
{
|
||||
QStringList colonSplit(arg.split("::"));
|
||||
if (colonSplit.size() > 1) {
|
||||
QStringList blankSplit = colonSplit[0].split(QLatin1Char(' '));
|
||||
if (blankSplit.size() > 1) {
|
||||
type = blankSplit[0];
|
||||
if (colonSplit.size() > 2) {
|
||||
module = blankSplit[1];
|
||||
qmlTypeName = colonSplit[1];
|
||||
QString name;
|
||||
int leftParen = arg.indexOf(QChar('('));
|
||||
if (leftParen > 0)
|
||||
name = arg.left(leftParen);
|
||||
else
|
||||
name = arg;
|
||||
int firstBlank = name.indexOf(QChar(' '));
|
||||
if (firstBlank > 0) {
|
||||
type = name.left(firstBlank);
|
||||
name = name.right(name.length() - firstBlank - 1);
|
||||
}
|
||||
else {
|
||||
module.clear();
|
||||
qmlTypeName = blankSplit[1];
|
||||
}
|
||||
}
|
||||
else {
|
||||
else
|
||||
type.clear();
|
||||
|
||||
QStringList colonSplit(name.split("::"));
|
||||
if (colonSplit.size() > 1) {
|
||||
if (colonSplit.size() > 2) {
|
||||
module = colonSplit[0];
|
||||
qmlTypeName = colonSplit[1];
|
||||
@ -722,7 +724,6 @@ bool CppCodeParser::splitQmlMethodArg(const QString& arg,
|
||||
module.clear();
|
||||
qmlTypeName = colonSplit[0];
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
QString msg = "Unrecognizable QML module/component qualifier for " + arg;
|
||||
@ -1308,23 +1309,23 @@ bool CppCodeParser::matchDataType(CodeChunk *dataType, QString *var)
|
||||
|
||||
/*!
|
||||
Parse the next function parameter, if there is one, and
|
||||
append it to parameter list \a p. Return true if a parameter
|
||||
is parsed and appended to \a p. Otherwise return false.
|
||||
append it to parameter vector \a pvect. Return true if
|
||||
a parameter is parsed and appended to \a pvect.
|
||||
Otherwise return false.
|
||||
*/
|
||||
bool CppCodeParser::matchParameter(ParsedParameterList& pplist)
|
||||
bool CppCodeParser::matchParameter(QVector<Parameter>& pvect, bool& isQPrivateSignal)
|
||||
{
|
||||
ParsedParameter pp;
|
||||
if (match(Tok_QPrivateSignal)) {
|
||||
pp.qPrivateSignal_ = true;
|
||||
pplist.append(pp);
|
||||
isQPrivateSignal = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
Parameter p;
|
||||
CodeChunk chunk;
|
||||
if (!matchDataType(&chunk, &pp.name_)) {
|
||||
if (!matchDataType(&chunk, &p.name_)) {
|
||||
return false;
|
||||
}
|
||||
pp.dataType_ = chunk.toString();
|
||||
p.dataType_ = chunk.toString();
|
||||
chunk.clear();
|
||||
match(Tok_Comment);
|
||||
if (match(Tok_Equal)) {
|
||||
@ -1336,8 +1337,8 @@ bool CppCodeParser::matchParameter(ParsedParameterList& pplist)
|
||||
readToken();
|
||||
}
|
||||
}
|
||||
pp.defaultValue_ = chunk.toString();
|
||||
pplist.append(pp);
|
||||
p.defaultValue_ = chunk.toString();
|
||||
pvect.append(p);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1542,10 +1543,11 @@ bool CppCodeParser::matchFunctionDecl(Aggregate *parent,
|
||||
readToken();
|
||||
|
||||
// A left paren was seen. Parse the parameters
|
||||
ParsedParameterList pplist;
|
||||
bool isQPrivateSignal = false;
|
||||
QVector<Parameter> pvect;
|
||||
if (tok != Tok_RightParen) {
|
||||
do {
|
||||
if (!matchParameter(pplist))
|
||||
if (!matchParameter(pvect, isQPrivateSignal))
|
||||
return false;
|
||||
} while (match(Tok_Comma));
|
||||
}
|
||||
@ -1629,13 +1631,10 @@ bool CppCodeParser::matchFunctionDecl(Aggregate *parent,
|
||||
func->setStatic(matched_static);
|
||||
func->setConst(matchedConst);
|
||||
func->setVirtualness(virtuality);
|
||||
if (!pplist.isEmpty()) {
|
||||
foreach (const ParsedParameter& pp, pplist) {
|
||||
if (pp.qPrivateSignal_)
|
||||
if (isQPrivateSignal)
|
||||
func->setPrivateSignal();
|
||||
else
|
||||
func->addParameter(Parameter(pp.dataType_, "", pp.name_, pp.defaultValue_));
|
||||
}
|
||||
if (!pvect.isEmpty()) {
|
||||
func->setParameters(pvect);
|
||||
}
|
||||
}
|
||||
if (parentPathPtr != 0)
|
||||
@ -2416,6 +2415,34 @@ bool CppCodeParser::makeFunctionNode(const QString& signature,
|
||||
return ok;
|
||||
}
|
||||
|
||||
/*!
|
||||
This function uses a Tokenizer to parse the \a parameters of a
|
||||
function into the parameter vector \a {pvect}.
|
||||
*/
|
||||
bool CppCodeParser::parseParameters(const QString& parameters,
|
||||
QVector<Parameter>& pvect,
|
||||
bool& isQPrivateSignal)
|
||||
{
|
||||
Tokenizer* outerTokenizer = tokenizer;
|
||||
int outerTok = tok;
|
||||
|
||||
QByteArray latin1 = parameters.toLatin1();
|
||||
Tokenizer stringTokenizer(Location(), latin1);
|
||||
stringTokenizer.setParsingFnOrMacro(true);
|
||||
tokenizer = &stringTokenizer;
|
||||
readToken();
|
||||
|
||||
inMacroCommand_ = false;
|
||||
do {
|
||||
if (!matchParameter(pvect, isQPrivateSignal))
|
||||
return false;
|
||||
} while (match(Tok_Comma));
|
||||
|
||||
tokenizer = outerTokenizer;
|
||||
tok = outerTok;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
Create a new FunctionNode for a QML method or signal, as
|
||||
specified by \a type, as a child of \a parent. \a sig is
|
||||
|
@ -51,16 +51,6 @@ class CppCodeParser : public CodeParser
|
||||
{
|
||||
Q_DECLARE_TR_FUNCTIONS(QDoc::CppCodeParser)
|
||||
|
||||
struct ParsedParameter {
|
||||
bool qPrivateSignal_;
|
||||
QString dataType_;
|
||||
QString name_;
|
||||
QString defaultValue_;
|
||||
ParsedParameter() : qPrivateSignal_(false) { }
|
||||
};
|
||||
friend class QTypeInfo<ParsedParameter>;
|
||||
typedef QVector<ParsedParameter> ParsedParameterList;
|
||||
|
||||
struct ExtraFuncData {
|
||||
Aggregate* root; // Used as the parent.
|
||||
Node::NodeType type; // The node type: Function, etc.
|
||||
@ -74,6 +64,7 @@ class CppCodeParser : public CodeParser
|
||||
public:
|
||||
CppCodeParser();
|
||||
~CppCodeParser();
|
||||
static CppCodeParser* cppParser() { return cppParser_; }
|
||||
|
||||
virtual void initializeParser(const Config& config) Q_DECL_OVERRIDE;
|
||||
virtual void terminateParser() Q_DECL_OVERRIDE;
|
||||
@ -84,6 +75,7 @@ public:
|
||||
virtual void parseSourceFile(const Location& location, const QString& filePath) Q_DECL_OVERRIDE;
|
||||
virtual void doneParsingHeaderFiles() Q_DECL_OVERRIDE;
|
||||
virtual void doneParsingSourceFiles() Q_DECL_OVERRIDE;
|
||||
bool parseParameters(const QString& parameters, QVector<Parameter>& pvect, bool& isQPrivateSignal);
|
||||
|
||||
protected:
|
||||
const QSet<QString>& topicCommands();
|
||||
@ -126,7 +118,7 @@ protected:
|
||||
bool matchTemplateAngles(CodeChunk *type = 0);
|
||||
bool matchTemplateHeader();
|
||||
bool matchDataType(CodeChunk *type, QString *var = 0);
|
||||
bool matchParameter(ParsedParameterList& pplist);
|
||||
bool matchParameter(QVector<Parameter>& pvect, bool& isQPrivateSignal);
|
||||
bool matchFunctionDecl(Aggregate *parent,
|
||||
QStringList *parentPathPtr,
|
||||
FunctionNode **funcPtr,
|
||||
@ -184,10 +176,10 @@ protected:
|
||||
|
||||
static QStringList exampleFiles;
|
||||
static QStringList exampleDirs;
|
||||
static CppCodeParser* cppParser_;
|
||||
QString exampleNameFilter;
|
||||
QString exampleImageFilter;
|
||||
};
|
||||
Q_DECLARE_TYPEINFO(CppCodeParser::ParsedParameter, Q_MOVABLE_TYPE);
|
||||
|
||||
#define COMMAND_ABSTRACT Doc::alias("abstract")
|
||||
#define COMMAND_CLASS Doc::alias("class")
|
||||
|
@ -1839,8 +1839,13 @@
|
||||
\li \c {\l QWidget} - The name of a class documented with the \l
|
||||
{class-command} {\\class} command.
|
||||
|
||||
\li \c {\l QWidget::sizeHint()} - The name of a member function,
|
||||
documented with or without an \l {fn-command} {\\fn} command.
|
||||
\li \c {\l QWidget::sizeHint()} - The signature of a function without
|
||||
parameters. If a matching function without parameters can't be found,
|
||||
the link is satisfied with the first matching function found.
|
||||
|
||||
\li \c {\l QWidget::removeAction(QAction* action)} - The signature
|
||||
of a function with parameters. If an exact match is not found, the
|
||||
link is not satisfied and qdoc reports a \e {Can't link to...} error.
|
||||
|
||||
\li \c {\l <QtGlobal>} - The subject of a \l {headerfile-command}
|
||||
{\\headerfile} command.
|
||||
|
@ -804,9 +804,9 @@ void Generator::generateBody(const Node *node, CodeMarker *marker)
|
||||
else if (node->type() == Node::Function) {
|
||||
const FunctionNode *func = static_cast<const FunctionNode *>(node);
|
||||
QSet<QString> definedParams;
|
||||
QList<Parameter>::ConstIterator p = func->parameters().constBegin();
|
||||
QVector<Parameter>::ConstIterator p = func->parameters().constBegin();
|
||||
while (p != func->parameters().constEnd()) {
|
||||
if ((*p).name().isEmpty() && (*p).leftType() != QLatin1String("...")
|
||||
if ((*p).name().isEmpty() && (*p).dataType() != QLatin1String("...")
|
||||
&& func->name() != QLatin1String("operator++")
|
||||
&& func->name() != QLatin1String("operator--")) {
|
||||
node->doc().location().warning(tr("Missing parameter name"));
|
||||
@ -836,7 +836,7 @@ void Generator::generateBody(const Node *node, CodeMarker *marker)
|
||||
else if (!(*a).isEmpty() && !documentedParams.contains(*a)) {
|
||||
bool needWarning = (func->status() > Node::Obsolete);
|
||||
if (func->overloadNumber() > 0) {
|
||||
FunctionNode *primaryFunc = func->parent()->findFunctionNode(func->name());
|
||||
FunctionNode *primaryFunc = func->parent()->findFunctionNode(func->name(), QString());
|
||||
if (primaryFunc) {
|
||||
foreach (const Parameter ¶m,
|
||||
primaryFunc->parameters()) {
|
||||
@ -1504,7 +1504,7 @@ void Generator::generateOverloadedSignal(const Node* node, CodeMarker* marker)
|
||||
if (i != 0)
|
||||
code += ", ";
|
||||
const Parameter &p = func->parameters().at(i);
|
||||
code += p.leftType() + p.rightType();
|
||||
code += p.dataType() + p.rightType();
|
||||
}
|
||||
|
||||
code += ")";
|
||||
@ -1516,7 +1516,7 @@ void Generator::generateOverloadedSignal(const Node* node, CodeMarker* marker)
|
||||
if (i != 0)
|
||||
code += ", ";
|
||||
const Parameter &p = func->parameters().at(i);
|
||||
code += p.leftType();
|
||||
code += p.dataType();
|
||||
if (code[code.size()-1].isLetterOrNumber())
|
||||
code += " ";
|
||||
code += p.name() + p.rightType();
|
||||
@ -2049,14 +2049,14 @@ void Generator::supplementAlsoList(const Node *node, QList<Text> &alsoList)
|
||||
if (func->name().startsWith("set") && func->name().size() >= 4) {
|
||||
alternateName = func->name()[3].toLower();
|
||||
alternateName += func->name().mid(4);
|
||||
alternateFunc = func->parent()->findFunctionNode(alternateName);
|
||||
alternateFunc = func->parent()->findFunctionNode(alternateName, QString());
|
||||
|
||||
if (!alternateFunc) {
|
||||
alternateName = "is" + func->name().mid(3);
|
||||
alternateFunc = func->parent()->findFunctionNode(alternateName);
|
||||
alternateFunc = func->parent()->findFunctionNode(alternateName, QString());
|
||||
if (!alternateFunc) {
|
||||
alternateName = "has" + func->name().mid(3);
|
||||
alternateFunc = func->parent()->findFunctionNode(alternateName);
|
||||
alternateFunc = func->parent()->findFunctionNode(alternateName, QString());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2064,7 +2064,7 @@ void Generator::supplementAlsoList(const Node *node, QList<Text> &alsoList)
|
||||
alternateName = "set";
|
||||
alternateName += func->name()[0].toUpper();
|
||||
alternateName += func->name().mid(1);
|
||||
alternateFunc = func->parent()->findFunctionNode(alternateName);
|
||||
alternateFunc = func->parent()->findFunctionNode(alternateName, QString());
|
||||
}
|
||||
|
||||
if (alternateFunc && alternateFunc->access() != Node::Private) {
|
||||
|
@ -34,11 +34,12 @@
|
||||
#include "node.h"
|
||||
#include "tree.h"
|
||||
#include "codemarker.h"
|
||||
#include "codeparser.h"
|
||||
#include "cppcodeparser.h"
|
||||
#include <quuid.h>
|
||||
#include "qdocdatabase.h"
|
||||
#include <qdebug.h>
|
||||
#include "generator.h"
|
||||
#include "tokenizer.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
@ -810,9 +811,56 @@ Node* Aggregate::findChildNode(const QString& name, NodeType type)
|
||||
Find a function node that is a child of this nose, such
|
||||
that the function node has the specified \a name.
|
||||
*/
|
||||
FunctionNode *Aggregate::findFunctionNode(const QString& name) const
|
||||
FunctionNode *Aggregate::findFunctionNode(const QString& name, const QString& params) const
|
||||
{
|
||||
return static_cast<FunctionNode *>(primaryFunctionMap_.value(name));
|
||||
FunctionNode* pfn = static_cast<FunctionNode*>(primaryFunctionMap_.value(name));
|
||||
FunctionNode* fn = pfn;
|
||||
if (fn) {
|
||||
const QVector<Parameter>* funcParams = &(fn->parameters());
|
||||
if (params.isEmpty() && funcParams->isEmpty())
|
||||
return fn;
|
||||
bool isQPrivateSignal = false; // Not used in the search
|
||||
QVector<Parameter> testParams;
|
||||
if (!params.isEmpty()) {
|
||||
CppCodeParser* cppParser = CppCodeParser::cppParser();
|
||||
cppParser->parseParameters(params, testParams, isQPrivateSignal);
|
||||
}
|
||||
NodeList funcs = secondaryFunctionMap_.value(name);
|
||||
int i = -1;
|
||||
while (fn) {
|
||||
if (testParams.size() == funcParams->size()) {
|
||||
if (testParams.isEmpty())
|
||||
return fn;
|
||||
bool different = false;
|
||||
for (int j=0; j<testParams.size(); j++) {
|
||||
if (testParams.at(j).dataType() != funcParams->at(j).dataType()) {
|
||||
different = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!different)
|
||||
return fn;
|
||||
}
|
||||
if (++i < funcs.size()) {
|
||||
fn = static_cast<FunctionNode*>(funcs.at(i));
|
||||
funcParams = &(fn->parameters());
|
||||
}
|
||||
else
|
||||
fn = 0;
|
||||
}
|
||||
if (!fn && !testParams.empty())
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
Most \l commands that link to functions don't include
|
||||
the parameter declarations in the function signature,
|
||||
so if the \l is meant to go to a function that does
|
||||
have parameters, the algorithm above won't find it.
|
||||
Therefore we must return the pointer to the function
|
||||
in the primary function map in the cases where the
|
||||
parameters should have been specified in the \l command.
|
||||
*/
|
||||
return (fn ? fn : pfn);
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -1090,20 +1138,20 @@ void Aggregate::setIncludes(const QStringList& includes)
|
||||
*/
|
||||
bool Aggregate::isSameSignature(const FunctionNode *f1, const FunctionNode *f2)
|
||||
{
|
||||
if (f1->parameters().count() != f2->parameters().count())
|
||||
if (f1->parameters().size() != f2->parameters().size())
|
||||
return false;
|
||||
if (f1->isConst() != f2->isConst())
|
||||
return false;
|
||||
|
||||
QList<Parameter>::ConstIterator p1 = f1->parameters().constBegin();
|
||||
QList<Parameter>::ConstIterator p2 = f2->parameters().constBegin();
|
||||
QVector<Parameter>::ConstIterator p1 = f1->parameters().constBegin();
|
||||
QVector<Parameter>::ConstIterator p2 = f2->parameters().constBegin();
|
||||
while (p2 != f2->parameters().constEnd()) {
|
||||
if ((*p1).hasType() && (*p2).hasType()) {
|
||||
if ((*p1).rightType() != (*p2).rightType())
|
||||
return false;
|
||||
|
||||
QString t1 = p1->leftType();
|
||||
QString t2 = p2->leftType();
|
||||
QString t1 = p1->dataType();
|
||||
QString t2 = p2->dataType();
|
||||
|
||||
if (t1.length() < t2.length())
|
||||
qSwap(t1, t2);
|
||||
@ -1751,33 +1799,40 @@ void TypedefNode::setAssociatedEnum(const EnumNode *enume)
|
||||
|
||||
/*!
|
||||
Constructs this parameter from the left and right types
|
||||
\a leftType and rightType, the parameter \a name, and the
|
||||
\a dataType and rightType, the parameter \a name, and the
|
||||
\a defaultValue. In practice, \a rightType is not used,
|
||||
and I don't know what is was meant for.
|
||||
*/
|
||||
Parameter::Parameter(const QString& leftType,
|
||||
Parameter::Parameter(const QString& dataType,
|
||||
const QString& rightType,
|
||||
const QString& name,
|
||||
const QString& defaultValue)
|
||||
: leftType_(leftType), rightType_(rightType), name_(name), defaultValue_(defaultValue)
|
||||
: dataType_(dataType),
|
||||
rightType_(rightType),
|
||||
name_(name),
|
||||
defaultValue_(defaultValue)
|
||||
{
|
||||
// nothing.
|
||||
}
|
||||
|
||||
/*!
|
||||
The standard copy constructor copies the strings from \a p.
|
||||
Standard copy constructor copies \p.
|
||||
*/
|
||||
Parameter::Parameter(const Parameter& p)
|
||||
: leftType_(p.leftType_), rightType_(p.rightType_), name_(p.name_), defaultValue_(p.defaultValue_)
|
||||
: dataType_(p.dataType_),
|
||||
rightType_(p.rightType_),
|
||||
name_(p.name_),
|
||||
defaultValue_(p.defaultValue_)
|
||||
{
|
||||
// nothing.
|
||||
}
|
||||
|
||||
/*!
|
||||
Assigning Parameter \a p to this Parameter copies the
|
||||
strings across.
|
||||
standard assignment operator assigns \p.
|
||||
*/
|
||||
Parameter& Parameter::operator=(const Parameter& p)
|
||||
{
|
||||
leftType_ = p.leftType_;
|
||||
dataType_ = p.dataType_;
|
||||
rightType_ = p.rightType_;
|
||||
name_ = p.name_;
|
||||
defaultValue_ = p.defaultValue_;
|
||||
@ -1791,7 +1846,7 @@ Parameter& Parameter::operator=(const Parameter& p)
|
||||
*/
|
||||
QString Parameter::reconstruct(bool value) const
|
||||
{
|
||||
QString p = leftType_ + rightType_;
|
||||
QString p = dataType_ + rightType_;
|
||||
if (!p.endsWith(QChar('*')) && !p.endsWith(QChar('&')) && !p.endsWith(QChar(' ')))
|
||||
p += QLatin1Char(' ');
|
||||
p += name_;
|
||||
@ -1902,8 +1957,8 @@ void FunctionNode::addParameter(const Parameter& parameter)
|
||||
*/
|
||||
void FunctionNode::borrowParameterNames(const FunctionNode *source)
|
||||
{
|
||||
QList<Parameter>::Iterator t = parameters_.begin();
|
||||
QList<Parameter>::ConstIterator s = source->parameters_.constBegin();
|
||||
QVector<Parameter>::Iterator t = parameters_.begin();
|
||||
QVector<Parameter>::ConstIterator s = source->parameters_.constBegin();
|
||||
while (s != source->parameters_.constEnd() && t != parameters_.end()) {
|
||||
if (!(*s).name().isEmpty())
|
||||
(*t).setName((*s).name());
|
||||
@ -1958,7 +2013,7 @@ bool FunctionNode::hasActiveAssociatedProperty() const
|
||||
QStringList FunctionNode::parameterNames() const
|
||||
{
|
||||
QStringList names;
|
||||
QList<Parameter>::ConstIterator p = parameters().constBegin();
|
||||
QVector<Parameter>::ConstIterator p = parameters().constBegin();
|
||||
while (p != parameters().constEnd()) {
|
||||
names << (*p).name();
|
||||
++p;
|
||||
@ -1975,7 +2030,7 @@ QString FunctionNode::rawParameters(bool names, bool values) const
|
||||
{
|
||||
QString raw;
|
||||
foreach (const Parameter ¶meter, parameters()) {
|
||||
raw += parameter.leftType() + parameter.rightType();
|
||||
raw += parameter.dataType() + parameter.rightType();
|
||||
if (names)
|
||||
raw += parameter.name();
|
||||
if (values)
|
||||
@ -1991,7 +2046,7 @@ QString FunctionNode::rawParameters(bool names, bool values) const
|
||||
QStringList FunctionNode::reconstructParameters(bool values) const
|
||||
{
|
||||
QStringList reconstructedParameters;
|
||||
QList<Parameter>::ConstIterator p = parameters().constBegin();
|
||||
QVector<Parameter>::ConstIterator p = parameters().constBegin();
|
||||
while (p != parameters().constEnd()) {
|
||||
reconstructedParameters << (*p).reconstruct(values);
|
||||
++p;
|
||||
|
@ -376,7 +376,7 @@ public:
|
||||
Node* findChildNode(const QString& name, Node::Genus genus) const;
|
||||
Node* findChildNode(const QString& name, NodeType type);
|
||||
virtual void findChildren(const QString& name, NodeList& nodes) const Q_DECL_OVERRIDE;
|
||||
FunctionNode* findFunctionNode(const QString& name) const;
|
||||
FunctionNode* findFunctionNode(const QString& name, const QString& params) const;
|
||||
FunctionNode* findFunctionNode(const FunctionNode* clone) const;
|
||||
void addInclude(const QString &include);
|
||||
void setIncludes(const QStringList &includes);
|
||||
@ -815,12 +815,11 @@ inline void EnumNode::setFlagsType(TypedefNode* t)
|
||||
t->setAssociatedEnum(this);
|
||||
}
|
||||
|
||||
|
||||
class Parameter
|
||||
{
|
||||
public:
|
||||
Parameter() {}
|
||||
Parameter(const QString& leftType,
|
||||
Parameter(const QString& dataType,
|
||||
const QString& rightType = QString(),
|
||||
const QString& name = QString(),
|
||||
const QString& defaultValue = QString());
|
||||
@ -830,21 +829,24 @@ public:
|
||||
|
||||
void setName(const QString& name) { name_ = name; }
|
||||
|
||||
bool hasType() const { return leftType_.length() + rightType_.length() > 0; }
|
||||
const QString& leftType() const { return leftType_; }
|
||||
bool hasType() const { return dataType_.length() + rightType_.length() > 0; }
|
||||
const QString& dataType() const { return dataType_; }
|
||||
const QString& rightType() const { return rightType_; }
|
||||
const QString& name() const { return name_; }
|
||||
const QString& defaultValue() const { return defaultValue_; }
|
||||
|
||||
QString reconstruct(bool value = false) const;
|
||||
|
||||
private:
|
||||
QString leftType_;
|
||||
QString rightType_;
|
||||
public:
|
||||
QString dataType_;
|
||||
QString rightType_; // mws says remove this 04/08/2015
|
||||
QString name_;
|
||||
QString defaultValue_;
|
||||
};
|
||||
|
||||
//friend class QTypeInfo<Parameter>;
|
||||
//Q_DECLARE_TYPEINFO(Parameter, Q_MOVABLE_TYPE);
|
||||
|
||||
class FunctionNode : public LeafNode
|
||||
{
|
||||
public:
|
||||
@ -874,7 +876,7 @@ public:
|
||||
void setOverloadNumber(unsigned char n) { overloadNumber_ = n; }
|
||||
void setReimplemented(bool b);
|
||||
void addParameter(const Parameter& parameter);
|
||||
inline void setParameters(const QList<Parameter>& parameters);
|
||||
inline void setParameters(const QVector<Parameter>& parameters);
|
||||
void borrowParameterNames(const FunctionNode* source);
|
||||
void setReimplementedFrom(FunctionNode* from);
|
||||
|
||||
@ -907,7 +909,7 @@ public:
|
||||
virtual bool isJsMethod() const Q_DECL_OVERRIDE {
|
||||
return (type() == Node::QmlMethod) && (genus() == Node::JS);
|
||||
}
|
||||
const QList<Parameter>& parameters() const { return parameters_; }
|
||||
const QVector<Parameter>& parameters() const { return parameters_; }
|
||||
void clearParams() { parameters_.clear(); }
|
||||
QStringList parameterNames() const;
|
||||
QString rawParameters(bool names = false, bool values = false) const;
|
||||
@ -957,7 +959,7 @@ private:
|
||||
bool privateSignal_: 1;
|
||||
bool overload_ : 1;
|
||||
unsigned char overloadNumber_;
|
||||
QList<Parameter> parameters_;
|
||||
QVector<Parameter> parameters_;
|
||||
const FunctionNode* reimplementedFrom_;
|
||||
PropNodeList associatedProperties_;
|
||||
QList<FunctionNode*> reimplementedBy_;
|
||||
@ -1030,7 +1032,7 @@ private:
|
||||
const PropertyNode* overrides_;
|
||||
};
|
||||
|
||||
inline void FunctionNode::setParameters(const QList<Parameter> &p)
|
||||
inline void FunctionNode::setParameters(const QVector<Parameter> &p)
|
||||
{
|
||||
parameters_ = p;
|
||||
}
|
||||
|
@ -380,6 +380,30 @@ QString QDocForest::getLinkCounts(QStringList& strings, QVector<int>& counts)
|
||||
return depends;
|
||||
}
|
||||
|
||||
/*!
|
||||
*/
|
||||
const Node* QDocForest::findFunctionNode(const QString& target,
|
||||
const Node* relative,
|
||||
Node::Genus genus)
|
||||
{
|
||||
QString function, params;
|
||||
int length = target.length();
|
||||
if (target.endsWith(QChar(')'))) {
|
||||
int position = target.lastIndexOf(QChar('('));
|
||||
params = target.mid(position+1, length-position-2);
|
||||
function = target.left(position);
|
||||
}
|
||||
else
|
||||
function = target;
|
||||
foreach (Tree* t, searchOrder()) {
|
||||
const Node* n = t->findFunctionNode(function, params, relative, genus);
|
||||
if (n)
|
||||
return n;
|
||||
relative = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*! \class QDocDatabase
|
||||
This class provides exclusive access to the qdoc database,
|
||||
which consists of a forrest of trees and a lot of maps and
|
||||
@ -1342,8 +1366,16 @@ void QDocDatabase::resolveNamespaces()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
/*!
|
||||
*/
|
||||
const Node* QDocDatabase::findFunctionNode(const QString& target,
|
||||
const Node* relative,
|
||||
Node::Genus genus)
|
||||
{
|
||||
return forest_.findFunctionNode(target, relative, genus);
|
||||
}
|
||||
#endif
|
||||
/*!
|
||||
This function is called for autolinking to a \a type,
|
||||
which could be a function return type or a parameter
|
||||
@ -1641,6 +1673,8 @@ const Node* QDocDatabase::findNodeForAtom(const Atom* a, const Node* relative, Q
|
||||
Atom* atom = const_cast<Atom*>(a);
|
||||
QStringList targetPath = atom->string().split("#");
|
||||
QString first = targetPath.first().trimmed();
|
||||
if (Generator::debugging())
|
||||
qDebug() << " first:" << first;
|
||||
|
||||
Tree* domain = 0;
|
||||
Node::Genus genus = Node::DontCare;
|
||||
@ -1659,8 +1693,14 @@ const Node* QDocDatabase::findNodeForAtom(const Atom* a, const Node* relative, Q
|
||||
else if (domain) {
|
||||
if (first.endsWith(".html"))
|
||||
node = domain->findNodeByNameAndType(QStringList(first), Node::Document);
|
||||
else if (first.endsWith("()"))
|
||||
node = domain->findFunctionNode(first, 0, genus);
|
||||
else if (first.endsWith(QChar(')'))) {
|
||||
QString function, params;
|
||||
int length = first.length();
|
||||
int position = first.lastIndexOf(QChar('('));
|
||||
params = first.mid(position+1, length-position-2);
|
||||
function = first.left(position);
|
||||
node = domain->findFunctionNode(function, params, 0, genus);
|
||||
}
|
||||
else {
|
||||
int flags = SearchBaseClasses | SearchEnumValues;
|
||||
QStringList nodePath = first.split("::");
|
||||
@ -1683,8 +1723,11 @@ const Node* QDocDatabase::findNodeForAtom(const Atom* a, const Node* relative, Q
|
||||
if (!node && first.contains("/"))
|
||||
return findNodeForTarget(targetPath, relative, genus, ref);
|
||||
}
|
||||
else if (first.endsWith("()"))
|
||||
else if (first.endsWith(QChar(')'))) {
|
||||
node = findFunctionNode(first, relative, genus);
|
||||
if (Generator::debugging())
|
||||
qDebug() << " node:" << node;
|
||||
}
|
||||
else {
|
||||
node = findNodeForTarget(targetPath, relative, genus, ref);
|
||||
return node;
|
||||
|
@ -141,15 +141,8 @@ class QDocForest
|
||||
|
||||
const Node* findFunctionNode(const QString& target,
|
||||
const Node* relative,
|
||||
Node::Genus genus) {
|
||||
foreach (Tree* t, searchOrder()) {
|
||||
const Node* n = t->findFunctionNode(target, relative, genus);
|
||||
if (n)
|
||||
return n;
|
||||
relative = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
Node::Genus genus);
|
||||
|
||||
const Node* findNodeForTarget(QStringList& targetPath,
|
||||
const Node* relative,
|
||||
Node::Genus genus,
|
||||
|
@ -1238,7 +1238,7 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
|
||||
for (int i = 0; i < functionNode->parameters().size(); ++i) {
|
||||
Parameter parameter = functionNode->parameters()[i];
|
||||
writer.writeStartElement("parameter");
|
||||
writer.writeAttribute("left", parameter.leftType());
|
||||
writer.writeAttribute("left", parameter.dataType());
|
||||
writer.writeAttribute("right", parameter.rightType());
|
||||
writer.writeAttribute("name", parameter.name());
|
||||
writer.writeAttribute("default", parameter.defaultValue());
|
||||
|
@ -675,7 +675,7 @@ bool QmlDocVisitor::visit(QQmlJS::AST::UiPublicMember *member)
|
||||
QString name = member->name.toString();
|
||||
FunctionNode *qmlSignal = new FunctionNode(Node::QmlSignal, current, name, false);
|
||||
|
||||
QList<Parameter> parameters;
|
||||
QVector<Parameter> parameters;
|
||||
for (QQmlJS::AST::UiParameterList *it = member->parameters; it; it = it->next) {
|
||||
if (!it->type.isEmpty() && !it->name.isEmpty())
|
||||
parameters.append(Parameter(it->type.toString(), QString(), it->name.toString()));
|
||||
@ -754,7 +754,7 @@ bool QmlDocVisitor::visit(QQmlJS::AST::FunctionDeclaration* fd)
|
||||
}
|
||||
if (overloads > 1)
|
||||
qmlMethod->setOverloadFlag(true);
|
||||
QList<Parameter> parameters;
|
||||
QVector<Parameter> parameters;
|
||||
QQmlJS::AST::FormalParameterList* formals = fd->formals;
|
||||
if (formals) {
|
||||
QQmlJS::AST::FormalParameterList* fpl = formals;
|
||||
|
@ -33,6 +33,7 @@
|
||||
|
||||
#include "config.h"
|
||||
#include "tokenizer.h"
|
||||
#include "generator.h"
|
||||
|
||||
#include <qfile.h>
|
||||
#include <qhash.h>
|
||||
|
@ -220,6 +220,7 @@ QmlTypeNode* Tree::findQmlTypeNode(const QStringList& path)
|
||||
used as the starting point.
|
||||
*/
|
||||
const FunctionNode* Tree::findFunctionNode(const QStringList& path,
|
||||
const QString& params,
|
||||
const Node* relative,
|
||||
int findFlags,
|
||||
Node::Genus genus) const
|
||||
@ -234,7 +235,7 @@ const FunctionNode* Tree::findFunctionNode(const QStringList& path,
|
||||
qcn = static_cast<QmlTypeNode*>(n);
|
||||
}
|
||||
if (qcn)
|
||||
return static_cast<const FunctionNode*>(qcn->findFunctionNode(path[2]));
|
||||
return static_cast<const FunctionNode*>(qcn->findFunctionNode(path[2], params));
|
||||
}
|
||||
|
||||
if (!relative)
|
||||
@ -254,7 +255,7 @@ const FunctionNode* Tree::findFunctionNode(const QStringList& path,
|
||||
|
||||
const Node* next;
|
||||
if (i == path.size() - 1)
|
||||
next = ((const Aggregate*) node)->findFunctionNode(path.at(i));
|
||||
next = ((const Aggregate*) node)->findFunctionNode(path.at(i), params);
|
||||
else
|
||||
next = ((const Aggregate*) node)->findChildNode(path.at(i), genus);
|
||||
|
||||
@ -262,7 +263,7 @@ const FunctionNode* Tree::findFunctionNode(const QStringList& path,
|
||||
NodeList baseClasses = allBaseClasses(static_cast<const ClassNode*>(node));
|
||||
foreach (const Node* baseClass, baseClasses) {
|
||||
if (i == path.size() - 1)
|
||||
next = static_cast<const Aggregate*>(baseClass)->findFunctionNode(path.at(i));
|
||||
next = static_cast<const Aggregate*>(baseClass)->findFunctionNode(path.at(i), params);
|
||||
else
|
||||
next = static_cast<const Aggregate*>(baseClass)->findChildNode(path.at(i), genus);
|
||||
|
||||
@ -1452,13 +1453,17 @@ void Tree::insertQmlType(const QString& key, QmlTypeNode* n)
|
||||
Split \a target on "::" and find the function node with that
|
||||
path.
|
||||
*/
|
||||
const Node* Tree::findFunctionNode(const QString& target, const Node* relative, Node::Genus genus)
|
||||
const Node* Tree::findFunctionNode(const QString& target,
|
||||
const QString& params,
|
||||
const Node* relative,
|
||||
Node::Genus genus) const
|
||||
{
|
||||
QString t = target;
|
||||
if (t.endsWith("()"))
|
||||
if (t.endsWith("()")) {
|
||||
t.chop(2);
|
||||
}
|
||||
QStringList path = t.split("::");
|
||||
const FunctionNode* fn = findFunctionNode(path, relative, SearchBaseClasses, genus);
|
||||
const FunctionNode* fn = findFunctionNode(path, params, relative, SearchBaseClasses, genus);
|
||||
if (fn && fn->metaness() != FunctionNode::MacroWithoutParams)
|
||||
return fn;
|
||||
return 0;
|
||||
|
@ -107,7 +107,10 @@ class Tree
|
||||
ClassNode* findClassNode(const QStringList& path, const Node* start = 0) const;
|
||||
NamespaceNode* findNamespaceNode(const QStringList& path) const;
|
||||
FunctionNode* findFunctionNode(const QStringList& parentPath, const FunctionNode* clone);
|
||||
const Node* findFunctionNode(const QString& target, const Node* relative, Node::Genus genus);
|
||||
const Node* findFunctionNode(const QString& target,
|
||||
const QString& params,
|
||||
const Node* relative,
|
||||
Node::Genus genus) const;
|
||||
|
||||
Node* findNodeRecursive(const QStringList& path,
|
||||
int pathIndex,
|
||||
@ -163,6 +166,7 @@ class Tree
|
||||
NamespaceNode *root() { return &root_; }
|
||||
|
||||
const FunctionNode *findFunctionNode(const QStringList &path,
|
||||
const QString& params,
|
||||
const Node *relative = 0,
|
||||
int findFlags = 0,
|
||||
Node::Genus genus = Node::DontCare) const;
|
||||
|
@ -159,23 +159,6 @@ public:
|
||||
QWindow dummyTransparentWindow;
|
||||
#endif
|
||||
|
||||
#ifdef Q_DEAD_CODE_FROM_QT4_MAC
|
||||
void openCocoaColorPanel(const QColor &initial,
|
||||
QWidget *parent, const QString &title, QColorDialog::ColorDialogOptions options);
|
||||
void closeCocoaColorPanel();
|
||||
void releaseCocoaColorPanelDelegate();
|
||||
void setCocoaPanelColor(const QColor &color);
|
||||
|
||||
inline void done(int result) { q_func()->done(result); }
|
||||
inline QColorDialog *colorDialog() { return q_func(); }
|
||||
|
||||
void *delegate;
|
||||
|
||||
static bool sharedColorPanelAvailable;
|
||||
|
||||
void _q_macRunNativeAppModalPanel();
|
||||
void mac_nativeDialogModalHelp();
|
||||
#endif
|
||||
private:
|
||||
virtual void initHelper(QPlatformDialogHelper *h) Q_DECL_OVERRIDE;
|
||||
virtual void helperPrepareShow(QPlatformDialogHelper *h) Q_DECL_OVERRIDE;
|
||||
@ -1731,9 +1714,6 @@ void QColorDialogPrivate::init(const QColor &initial)
|
||||
if (!nativeDialogInUse)
|
||||
initWidgets();
|
||||
|
||||
#ifdef Q_DEAD_CODE_FROM_QT4_MAC
|
||||
delegate = 0;
|
||||
#endif
|
||||
#ifdef Q_OS_WIN32
|
||||
dummyTransparentWindow.resize(1, 1);
|
||||
dummyTransparentWindow.setFlags(Qt::Tool | Qt::FramelessWindowHint);
|
||||
@ -2135,11 +2115,6 @@ QColorDialog::ColorDialogOptions QColorDialog::options() const
|
||||
\sa color, colorSelected()
|
||||
*/
|
||||
|
||||
#ifdef Q_DEAD_CODE_FROM_QT4_MAC
|
||||
// can only have one Cocoa color panel active
|
||||
bool QColorDialogPrivate::sharedColorPanelAvailable = true;
|
||||
#endif
|
||||
|
||||
/*!
|
||||
\fn void QColorDialog::colorSelected(const QColor &color);
|
||||
|
||||
@ -2166,23 +2141,6 @@ void QColorDialog::setVisible(bool visible)
|
||||
if (visible)
|
||||
d->selectedQColor = QColor();
|
||||
|
||||
#if defined(Q_DEAD_CODE_FROM_QT4_MAC)
|
||||
if (visible) {
|
||||
if (d->delegate || (QColorDialogPrivate::sharedColorPanelAvailable &&
|
||||
!(testAttribute(Qt::WA_DontShowOnScreen) || (d->opts & DontUseNativeDialog)))){
|
||||
d->openCocoaColorPanel(currentColor(), parentWidget(), windowTitle(), options());
|
||||
QColorDialogPrivate::sharedColorPanelAvailable = false;
|
||||
setAttribute(Qt::WA_DontShowOnScreen);
|
||||
}
|
||||
setWindowFlags(windowModality() == Qt::WindowModal ? Qt::Sheet : DefaultWindowFlags);
|
||||
} else {
|
||||
if (d->delegate) {
|
||||
d->closeCocoaColorPanel();
|
||||
setAttribute(Qt::WA_DontShowOnScreen, false);
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
||||
if (d->nativeDialogInUse) {
|
||||
d->setNativeDialogVisible(visible);
|
||||
// Set WA_DontShowOnScreen so that QDialog::setVisible(visible) below
|
||||
@ -2191,7 +2149,6 @@ void QColorDialog::setVisible(bool visible)
|
||||
} else {
|
||||
setAttribute(Qt::WA_DontShowOnScreen, false);
|
||||
}
|
||||
#endif
|
||||
|
||||
QDialog::setVisible(visible);
|
||||
}
|
||||
@ -2267,13 +2224,7 @@ QRgb QColorDialog::getRgba(QRgb initial, bool *ok, QWidget *parent)
|
||||
|
||||
QColorDialog::~QColorDialog()
|
||||
{
|
||||
#if defined(Q_DEAD_CODE_FROM_QT4_MAC)
|
||||
Q_D(QColorDialog);
|
||||
if (d->delegate) {
|
||||
d->releaseCocoaColorPanelDelegate();
|
||||
QColorDialogPrivate::sharedColorPanelAvailable = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -3101,6 +3101,53 @@ void QDockAreaLayout::tabifyDockWidget(QDockWidget *first, QDockWidget *second)
|
||||
remove(index);
|
||||
}
|
||||
|
||||
void QDockAreaLayout::resizeDocks(const QList<QDockWidget *> &docks,
|
||||
const QList<int> &sizes, Qt::Orientation o)
|
||||
{
|
||||
if (docks.count() != sizes.count()) {
|
||||
qWarning("QMainWidget::resizeDocks: size of the lists are not the same");
|
||||
return;
|
||||
}
|
||||
int count = docks.count();
|
||||
fallbackToSizeHints = false;
|
||||
for (int i = 0; i < count; ++i) {
|
||||
QList<int> path = indexOf(docks[i]);
|
||||
if (path.isEmpty()) {
|
||||
qWarning("QMainWidget::resizeDocks: one QDockWidget is not part of the layout");
|
||||
continue;
|
||||
}
|
||||
int size = sizes[i];
|
||||
if (size <= 0) {
|
||||
qWarning("QMainWidget::resizeDocks: all sizes need to be larger than 0");
|
||||
size = 1;
|
||||
}
|
||||
|
||||
while (path.size() > 1) {
|
||||
QDockAreaLayoutInfo *info = this->info(path);
|
||||
if (!info->tabbed && info->o == o) {
|
||||
info->item_list[path.last()].size = size;
|
||||
int totalSize = 0;
|
||||
foreach (const QDockAreaLayoutItem &item, info->item_list) {
|
||||
if (!item.skip()) {
|
||||
if (totalSize != 0)
|
||||
totalSize += sep;
|
||||
totalSize += item.size == -1 ? pick(o, item.sizeHint()) : item.size;
|
||||
}
|
||||
}
|
||||
size = totalSize;
|
||||
}
|
||||
path.removeLast();
|
||||
}
|
||||
|
||||
const int dockNum = path.first();
|
||||
Q_ASSERT(dockNum < QInternal::DockCount);
|
||||
QRect &r = this->docks[dockNum].rect;
|
||||
QSize s = r.size();
|
||||
rpick(o, s) = size;
|
||||
r.setSize(s);
|
||||
}
|
||||
}
|
||||
|
||||
void QDockAreaLayout::splitDockWidget(QDockWidget *after,
|
||||
QDockWidget *dockWidget,
|
||||
Qt::Orientation orientation)
|
||||
|
@ -268,6 +268,7 @@ public:
|
||||
void splitDockWidget(QDockWidget *after, QDockWidget *dockWidget,
|
||||
Qt::Orientation orientation);
|
||||
void tabifyDockWidget(QDockWidget *first, QDockWidget *second);
|
||||
void resizeDocks(const QList<QDockWidget *> &docks, const QList<int> &sizes, Qt::Orientation o);
|
||||
|
||||
void apply(bool animate);
|
||||
|
||||
|
@ -1237,6 +1237,35 @@ void QMainWindow::removeDockWidget(QDockWidget *dockwidget)
|
||||
Qt::DockWidgetArea QMainWindow::dockWidgetArea(QDockWidget *dockwidget) const
|
||||
{ return d_func()->layout->dockWidgetArea(dockwidget); }
|
||||
|
||||
|
||||
/*!
|
||||
\since 5.6
|
||||
Resizes the dock widgets in the list \a docks to the corresponding size in
|
||||
pixels from the list \a sizes. If \a orientation is Qt::Horizontal, adjusts
|
||||
the width, otherwise adjusts the height of the dock widgets.
|
||||
The sizes will be adjusted such that the maximum and the minimum sizes are
|
||||
respected and the QMainWindow itself will not be resized.
|
||||
Any additional/missing space is distributed amongst the widgets according
|
||||
to the relative weight of the sizes.
|
||||
|
||||
Example:
|
||||
\code
|
||||
resizeDocks({blueWidget, yellowWidget}, {20 , 40}, Qt::Horizontal);
|
||||
\endcode
|
||||
If the blue and the yellow widget are nested on the same level they will be
|
||||
resized such that the yellowWidget is twice as big as the blueWidget
|
||||
|
||||
If some widgets are grouped in tabs, only one widget per group should be
|
||||
specified. Widgets not in the list might be changed to repect the constraints.
|
||||
*/
|
||||
void QMainWindow::resizeDocks(const QList<QDockWidget *> &docks,
|
||||
const QList<int> &sizes, Qt::Orientation orientation)
|
||||
{
|
||||
d_func()->layout->layoutState.dockAreaLayout.resizeDocks(docks, sizes, orientation);
|
||||
d_func()->layout->invalidate();
|
||||
}
|
||||
|
||||
|
||||
#endif // QT_NO_DOCKWIDGET
|
||||
|
||||
/*!
|
||||
|
@ -165,6 +165,9 @@ public:
|
||||
bool restoreDockWidget(QDockWidget *dockwidget);
|
||||
|
||||
Qt::DockWidgetArea dockWidgetArea(QDockWidget *dockwidget) const;
|
||||
|
||||
void resizeDocks(const QList<QDockWidget *> &docks,
|
||||
const QList<int> &sizes, Qt::Orientation orientation);
|
||||
#endif // QT_NO_DOCKWIDGET
|
||||
|
||||
QByteArray saveState(int version = 0) const;
|
||||
|
@ -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,134 +109,76 @@ 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);
|
||||
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;
|
||||
}
|
||||
HRESULT __stdcall SetWindow(ABI::Windows::UI::Core::ICoreWindow *) { return S_OK; }
|
||||
HRESULT __stdcall Load(HSTRING) { return S_OK; }
|
||||
HRESULT __stdcall Run()
|
||||
|
||||
private:
|
||||
HRESULT __stdcall OnActivated(IActivatedEventArgs *args) Q_DECL_OVERRIDE
|
||||
{
|
||||
bool develMode = false;
|
||||
bool debugWait = false;
|
||||
foreach (const QByteArray &arg, m_argv) {
|
||||
if (arg == "-qdevel")
|
||||
develMode = true;
|
||||
if (arg == "-qdebug")
|
||||
debugWait = true;
|
||||
return base->OnActivated(args);
|
||||
}
|
||||
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, ¶ms);
|
||||
// Install the develMode message handler
|
||||
#ifndef Q_OS_WINPHONE
|
||||
defaultMessageHandler = qInstallMessageHandler(devMessageHandler);
|
||||
|
||||
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();
|
||||
}
|
||||
// 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; }
|
||||
|
||||
private:
|
||||
// Activation handler
|
||||
HRESULT onActivated(Core::ICoreApplicationView *, Activation::IActivatedEventArgs *args)
|
||||
{
|
||||
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()));
|
||||
}
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
int m_argc;
|
||||
QVector<char *> m_argv;
|
||||
bool m_deleteArgv0;
|
||||
EventRegistrationToken m_activationToken;
|
||||
};
|
||||
|
||||
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)
|
||||
{
|
||||
return (*frameworkView = Make<AppContainer>(m_argc, m_argv).Detach()) ? S_OK : E_OUTOFMEMORY;
|
||||
}
|
||||
private:
|
||||
int m_argc;
|
||||
char **m_argv;
|
||||
};
|
||||
|
||||
// Main entry point for Appx containers
|
||||
int __stdcall WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
|
||||
{
|
||||
#if _MSC_VER < 1900
|
||||
int argc = 0;
|
||||
char **argv, **env;
|
||||
_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;
|
||||
if (!commandLine.isEmpty())
|
||||
args.append(commandLine.data());
|
||||
|
||||
bool quote = false;
|
||||
bool escape = false;
|
||||
for (int i = 0; i < commandLine.size(); ++i) {
|
||||
@ -260,11 +208,100 @@ int __stdcall WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
|
||||
break;
|
||||
}
|
||||
}
|
||||
int argc = args.size();
|
||||
char **argv = args.data();
|
||||
char **env = Q_NULLPTR;
|
||||
#endif // _MSC_VER >= 1900
|
||||
|
||||
bool develMode = false;
|
||||
bool debugWait = false;
|
||||
foreach (const char *arg, args) {
|
||||
if (strcmp(arg, "-qdevel") == 0)
|
||||
develMode = true;
|
||||
if (strcmp(arg, "-qdebug") == 0)
|
||||
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, ¶ms);
|
||||
// Install the develMode message handler
|
||||
#ifndef Q_OS_WINPHONE
|
||||
defaultMessageHandler = qInstallMessageHandler(devMessageHandler);
|
||||
#endif
|
||||
}
|
||||
// Wait for debugger before continuing
|
||||
if (debugWait) {
|
||||
while (!IsDebuggerPresent())
|
||||
WaitForSingleObjectEx(GetCurrentThread(), 1, true);
|
||||
}
|
||||
|
||||
ResumeThread(mainThread);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT __stdcall OnFileActivated(IFileActivatedEventArgs *args) Q_DECL_OVERRIDE
|
||||
{
|
||||
Q_UNUSED(args);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT __stdcall OnSearchActivated(ISearchActivatedEventArgs *args) Q_DECL_OVERRIDE
|
||||
{
|
||||
Q_UNUSED(args);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT __stdcall OnShareTargetActivated(IShareTargetActivatedEventArgs *args) Q_DECL_OVERRIDE
|
||||
{
|
||||
Q_UNUSED(args);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
int argc = 0;
|
||||
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;
|
||||
#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);
|
||||
}
|
||||
|
@ -122,6 +122,7 @@ private slots:
|
||||
void removeFileWhileProcessIsRunning();
|
||||
void fileWriterProcess();
|
||||
void switchReadChannels();
|
||||
void discardUnwantedOutput();
|
||||
void setWorkingDirectory();
|
||||
void setNonExistentWorkingDirectory();
|
||||
#endif // not Q_OS_WINCE
|
||||
@ -2228,6 +2229,25 @@ void tst_QProcess::switchReadChannels()
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef Q_OS_WINCE
|
||||
// Reading and writing to a process is not supported on Qt/CE
|
||||
void tst_QProcess::discardUnwantedOutput()
|
||||
{
|
||||
QProcess process;
|
||||
|
||||
process.setProgram("testProcessEcho2/testProcessEcho2");
|
||||
process.start(QIODevice::WriteOnly);
|
||||
process.write("Hello, World");
|
||||
process.closeWriteChannel();
|
||||
QVERIFY(process.waitForFinished(5000));
|
||||
|
||||
process.setReadChannel(QProcess::StandardOutput);
|
||||
QCOMPARE(process.bytesAvailable(), Q_INT64_C(0));
|
||||
process.setReadChannel(QProcess::StandardError);
|
||||
QCOMPARE(process.bytesAvailable(), Q_INT64_C(0));
|
||||
}
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef Q_OS_WINCE
|
||||
// Q_OS_WIN - setWorkingDirectory will chdir before starting the process on unices
|
||||
|
@ -1079,7 +1079,7 @@ static bool canSendUnixFd(DBusConnection *connection)
|
||||
# if DBUS_VERSION-0 >= 0x010400
|
||||
can_send_type = dbus_connection_can_send_type;
|
||||
# endif
|
||||
#else
|
||||
#elif !defined(QT_NO_LIBRARY)
|
||||
// run-time check if the next functions are available
|
||||
can_send_type = (can_send_type_t)qdbus_resolve_conditionally("dbus_connection_can_send_type");
|
||||
#endif
|
||||
|
@ -94,7 +94,11 @@ static void addFixedTypes()
|
||||
// the library recognizes this as valid type first.
|
||||
// The following function was added for Unix FD support, so if it is
|
||||
// present, so is support for Unix FDs.
|
||||
# ifndef QT_NO_LIBRARY
|
||||
bool supportsUnixFds = qdbus_resolve_conditionally("dbus_connection_can_send_type");
|
||||
# else
|
||||
bool supportsUnixFds = false;
|
||||
# endif
|
||||
# else
|
||||
bool supportsUnixFds = true;
|
||||
# endif
|
||||
|
@ -107,6 +107,7 @@ private slots:
|
||||
void premultiply();
|
||||
void unpremultiply_sse4();
|
||||
void qrgba64();
|
||||
void qrgba64MemoryLayout();
|
||||
void qrgba64Premultiply();
|
||||
void qrgba64Equivalence();
|
||||
|
||||
@ -1495,6 +1496,24 @@ void tst_QColor::qrgba64()
|
||||
QCOMPARE(rgb64.green(), quint16(0x4422));
|
||||
}
|
||||
|
||||
void tst_QColor::qrgba64MemoryLayout()
|
||||
{
|
||||
QRgba64 rgb64 = QRgba64::fromRgba64(0x0123, 0x4567, 0x89ab, 0xcdef);
|
||||
QCOMPARE(rgb64.red(), quint16(0x0123));
|
||||
QCOMPARE(rgb64.green(), quint16(0x4567));
|
||||
QCOMPARE(rgb64.blue(), quint16(0x89ab));
|
||||
QCOMPARE(rgb64.alpha(), quint16(0xcdef));
|
||||
|
||||
// Check in-memory order, so it can be used by things like SSE
|
||||
Q_STATIC_ASSERT(sizeof(QRgba64) == sizeof(quint64));
|
||||
quint16 memory[4];
|
||||
memcpy(memory, &rgb64, sizeof(QRgba64));
|
||||
QCOMPARE(memory[0], quint16(0x0123));
|
||||
QCOMPARE(memory[1], quint16(0x4567));
|
||||
QCOMPARE(memory[2], quint16(0x89ab));
|
||||
QCOMPARE(memory[3], quint16(0xcdef));
|
||||
}
|
||||
|
||||
void tst_QColor::qrgba64Premultiply()
|
||||
{
|
||||
// Tests that qPremultiply(qUnpremultiply(rgba64)) returns rgba64.
|
||||
|
@ -4882,8 +4882,12 @@ void tst_QPainter::blendARGBonRGB_data()
|
||||
<< QPainter::CompositionMode_SourceOver << qRgba(85, 0, 0, 85) << 85;
|
||||
QTest::newRow("ARGB source RGB30") << QImage::Format_RGB30 << QImage::Format_ARGB32
|
||||
<< QPainter::CompositionMode_Source << qRgba(255, 0, 0, 85) << 85;
|
||||
QTest::newRow("ARGB source RGB30") << QImage::Format_RGB30 << QImage::Format_ARGB32
|
||||
<< QPainter::CompositionMode_Source << qRgba(255, 0, 0, 120) << 85;
|
||||
QTest::newRow("ARGB_PM source RGB30") << QImage::Format_RGB30 << QImage::Format_ARGB32_Premultiplied
|
||||
<< QPainter::CompositionMode_Source << qRgba(85, 0, 0, 85) << 85;
|
||||
QTest::newRow("ARGB_PM source RGB30") << QImage::Format_RGB30 << QImage::Format_ARGB32_Premultiplied
|
||||
<< QPainter::CompositionMode_Source << qRgba(180, 0, 0, 180) << 170;
|
||||
QTest::newRow("ARGB source-in RGB30") << QImage::Format_RGB30 << QImage::Format_ARGB32
|
||||
<< QPainter::CompositionMode_SourceIn << qRgba(255, 0, 0, 85) << 85;
|
||||
QTest::newRow("ARGB_PM source-in RGB30") << QImage::Format_RGB30 << QImage::Format_ARGB32_Premultiplied
|
||||
|
@ -47,6 +47,7 @@
|
||||
#include <QtCore/QVariant>
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QTextStream>
|
||||
#include <QtCore/QJsonDocument>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
@ -107,6 +108,7 @@ private slots:
|
||||
void testConfiguration();
|
||||
void testGlConfiguration();
|
||||
void testBugList();
|
||||
void testDefaultWindowsBlacklist();
|
||||
};
|
||||
|
||||
static void dumpConfiguration(QTextStream &str)
|
||||
@ -284,6 +286,20 @@ void tst_QOpenGlConfig::testBugList()
|
||||
msgSetMismatch(expectedFeatures, actualFeatures));
|
||||
}
|
||||
|
||||
void tst_QOpenGlConfig::testDefaultWindowsBlacklist()
|
||||
{
|
||||
if (qGuiApp->platformName() != QStringLiteral("windows"))
|
||||
QSKIP("Only applicable to Windows");
|
||||
|
||||
QFile f(QStringLiteral(":/qt-project.org/windows/openglblacklists/default.json"));
|
||||
QVERIFY(f.open(QIODevice::ReadOnly | QIODevice::Text));
|
||||
QJsonParseError err;
|
||||
QJsonDocument doc = QJsonDocument::fromJson(f.readAll(), &err);
|
||||
QVERIFY2(err.error == 0,
|
||||
QStringLiteral("Failed to parse built-in Windows GPU blacklist. %1 : %2")
|
||||
.arg(err.offset).arg(err.errorString()).toLatin1());
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QOpenGlConfig)
|
||||
|
||||
#include "tst_qopenglconfig.moc"
|
||||
|
@ -241,6 +241,10 @@ private slots:
|
||||
|
||||
void aggregateFunctionTypes_data() { generic_data(); }
|
||||
void aggregateFunctionTypes();
|
||||
|
||||
void integralTypesMysql_data() { generic_data("QMYSQL"); }
|
||||
void integralTypesMysql();
|
||||
|
||||
private:
|
||||
// returns all database connections
|
||||
void generic_data(const QString &engine=QString());
|
||||
@ -3974,5 +3978,65 @@ void tst_QSqlQuery::aggregateFunctionTypes()
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void runIntegralTypesMysqlTest(QSqlDatabase &db, const QString &tableName, const QString &type, const bool withPreparedStatement,
|
||||
const T min = std::numeric_limits<T>::min(), const T max = std::numeric_limits<T>::max())
|
||||
{
|
||||
QSqlQuery q(db);
|
||||
QVERIFY_SQL(q, exec("DROP TABLE IF EXISTS " + tableName));
|
||||
QVERIFY_SQL(q, exec("CREATE TABLE " + tableName + " (id " + type + ")"));
|
||||
|
||||
const int steps = 20;
|
||||
const T increment = max / steps - min / steps;
|
||||
|
||||
// insert some values
|
||||
QVector<T> values;
|
||||
values.resize(steps);
|
||||
T v = min;
|
||||
if (withPreparedStatement) {
|
||||
QVERIFY_SQL(q, prepare("INSERT INTO " + tableName + " (id) VALUES (?)"));
|
||||
}
|
||||
for (int i = 0; i < values.size(); ++i) {
|
||||
if (withPreparedStatement) {
|
||||
q.bindValue(0, v);
|
||||
QVERIFY_SQL(q, exec());
|
||||
} else {
|
||||
QVERIFY_SQL(q, exec("INSERT INTO " + tableName + " (id) VALUES (" + QString::number(v) + ")"));
|
||||
}
|
||||
values[i] = v;
|
||||
v += increment;
|
||||
}
|
||||
|
||||
// ensure we can read them back properly
|
||||
QVERIFY_SQL(q, exec("SELECT id FROM " + tableName));
|
||||
QVector<T> actualValues;
|
||||
actualValues.reserve(values.size());
|
||||
while (q.next()) {
|
||||
actualValues << q.value(0).value<T>();
|
||||
}
|
||||
QCOMPARE(actualValues, values);
|
||||
}
|
||||
|
||||
void tst_QSqlQuery::integralTypesMysql()
|
||||
{
|
||||
QFETCH(QString, dbName);
|
||||
QSqlDatabase db = QSqlDatabase::database(dbName);
|
||||
CHECK_DATABASE(db);
|
||||
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
const bool withPreparedStatement = (i == 1);
|
||||
runIntegralTypesMysqlTest<char>(db, "tinyIntTest", "TINYINT", withPreparedStatement);
|
||||
runIntegralTypesMysqlTest<unsigned char>(db, "unsignedTinyIntTest", "TINYINT UNSIGNED", withPreparedStatement);
|
||||
runIntegralTypesMysqlTest<char>(db, "smallIntTest", "SMALLINT", withPreparedStatement);
|
||||
runIntegralTypesMysqlTest<unsigned char>(db, "unsignedSmallIntTest", "SMALLINT UNSIGNED", withPreparedStatement);
|
||||
runIntegralTypesMysqlTest<int>(db, "mediumIntTest", "MEDIUMINT", withPreparedStatement, -(1 << 23), (1 << 23) - 1);
|
||||
runIntegralTypesMysqlTest<unsigned int>(db, "unsignedMediumIntTest", "MEDIUMINT UNSIGNED", withPreparedStatement, 0, (1 << 24) - 1);
|
||||
runIntegralTypesMysqlTest<int>(db, "intTest", "INT", withPreparedStatement);
|
||||
runIntegralTypesMysqlTest<unsigned int>(db, "unsignedIntTest", "INT UNSIGNED", withPreparedStatement);
|
||||
runIntegralTypesMysqlTest<long long>(db, "bigIntTest", "BIGINT", withPreparedStatement);
|
||||
runIntegralTypesMysqlTest<unsigned long long>(db, "unsignedBigIntTest", "BIGINT UNSIGNED", withPreparedStatement);
|
||||
}
|
||||
}
|
||||
|
||||
QTEST_MAIN( tst_QSqlQuery )
|
||||
#include "tst_qsqlquery.moc"
|
||||
|
@ -149,6 +149,8 @@ private slots:
|
||||
void toggleUnifiedTitleAndToolBarOnMac();
|
||||
#endif
|
||||
void QTBUG21378_animationFinished();
|
||||
void resizeDocks();
|
||||
void resizeDocks_data();
|
||||
};
|
||||
|
||||
|
||||
@ -1950,5 +1952,96 @@ void tst_QMainWindow::QTBUG21378_animationFinished()
|
||||
delete mwClickTimer;
|
||||
QVERIFY(true);
|
||||
}
|
||||
|
||||
Q_DECLARE_METATYPE(Qt::Orientation)
|
||||
|
||||
void tst_QMainWindow::resizeDocks_data()
|
||||
{
|
||||
QTest::addColumn<Qt::Orientation>("orientation");
|
||||
QTest::addColumn<QStringList>("docks");
|
||||
QTest::addColumn<QList<int> >("sizes");
|
||||
|
||||
QTest::newRow("1") << Qt::Horizontal
|
||||
<< (QStringList() << "blue" << "orange" << "green" << "gray")
|
||||
<< (QList<int>() << 190 << 190 << 320 << 160);
|
||||
|
||||
QTest::newRow("2") << Qt::Vertical
|
||||
<< (QStringList() << "yellow" << "orange")
|
||||
<< (QList<int>() << 147 << 133 );
|
||||
|
||||
|
||||
QTest::newRow("3") << Qt::Horizontal
|
||||
<< (QStringList() << "blue" << "yellow")
|
||||
<< (QList<int>() << 190 << 600);
|
||||
}
|
||||
|
||||
void tst_QMainWindow::resizeDocks()
|
||||
{
|
||||
AddList addList;
|
||||
addList
|
||||
<< AddDockWidget("blue", Qt::LeftDockWidgetArea)
|
||||
<< AddDockWidget("red", Qt::TopDockWidgetArea)
|
||||
<< AddDockWidget("pink", "red")
|
||||
<< AddDockWidget("yellow", Qt::RightDockWidgetArea)
|
||||
<< AddDockWidget("orange", Qt::RightDockWidgetArea)
|
||||
<< AddDockWidget("green", "orange", Qt::Horizontal)
|
||||
<< AddDockWidget("gray", "orange", Qt::Horizontal);
|
||||
/*
|
||||
+--------------------------------+
|
||||
| red/pink |
|
||||
+------+-+-----------------------+
|
||||
| | | yellow |
|
||||
| blue + +--------+------+-------+
|
||||
| | | orange | gray | green |
|
||||
+------+-+--------+------+-------+
|
||||
|
||||
*/
|
||||
|
||||
QMainWindow mw(0, Qt::BypassWindowManagerHint);
|
||||
mw.setDockNestingEnabled(true);
|
||||
mw.resize(1800, 600);
|
||||
|
||||
foreach (const AddDockWidget &i, addList)
|
||||
i.apply(&mw);
|
||||
|
||||
foreach (QDockWidget *dw, mw.findChildren<QDockWidget *>())
|
||||
dw->setStyleSheet( "* { background-color: " + dw->objectName() +" }");
|
||||
|
||||
mw.setCentralWidget(new QTextEdit);
|
||||
|
||||
mw.show();
|
||||
QTest::qWaitForWindowExposed(&mw);
|
||||
|
||||
QFETCH(Qt::Orientation, orientation);
|
||||
QFETCH(QStringList, docks);
|
||||
QFETCH(QList<int>, sizes);
|
||||
|
||||
QList<QDockWidget *> list;
|
||||
foreach (const QString &name, docks) {
|
||||
QDockWidget *d = mw.findChild<QDockWidget *>(name);
|
||||
QVERIFY(d);
|
||||
list << d;
|
||||
}
|
||||
|
||||
mw.resizeDocks(list, sizes, orientation);
|
||||
|
||||
qApp->processEvents();
|
||||
|
||||
int totalFromList = 0;
|
||||
int actualTotal = 0;
|
||||
for (int i = 0; i < docks.count(); ++i) {
|
||||
totalFromList += sizes[i];
|
||||
QSize s = list[i]->size();
|
||||
actualTotal += (orientation == Qt::Horizontal) ? s.width() : s.height();
|
||||
// qDebug() << list[i] << list[i]->size() << sizes[i];
|
||||
}
|
||||
|
||||
for (int i = 0; i < docks.count(); ++i) {
|
||||
QSize s = list[i]->size();
|
||||
int value = (orientation == Qt::Horizontal) ? s.width() : s.height();
|
||||
QCOMPARE(value, qRound(sizes[i]*actualTotal/double(totalFromList)));
|
||||
}
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QMainWindow)
|
||||
#include "tst_qmainwindow.moc"
|
||||
|
@ -55,6 +55,8 @@ public slots:
|
||||
private slots:
|
||||
void benchmark_data() { generic_data(); }
|
||||
void benchmark();
|
||||
void benchmarkSelectPrepared_data() { generic_data(); }
|
||||
void benchmarkSelectPrepared();
|
||||
|
||||
private:
|
||||
// returns all database connections
|
||||
@ -264,4 +266,42 @@ void tst_QSqlQuery::benchmark()
|
||||
tst_Databases::safeDropTable( db, tableName );
|
||||
}
|
||||
|
||||
void tst_QSqlQuery::benchmarkSelectPrepared()
|
||||
{
|
||||
QFETCH( QString, dbName );
|
||||
QSqlDatabase db = QSqlDatabase::database(dbName);
|
||||
CHECK_DATABASE(db);
|
||||
if (tst_Databases::getMySqlVersion(db).section(QChar('.'), 0, 0).toInt() < 5)
|
||||
QSKIP("Test requires MySQL >= 5.0");
|
||||
|
||||
QSqlQuery q(db);
|
||||
const QString tableName(qTableName("benchmark", __FILE__, db));
|
||||
|
||||
tst_Databases::safeDropTable(db, tableName);
|
||||
|
||||
QVERIFY_SQL(q, exec("CREATE TABLE " + tableName + "(id INT NOT NULL)"));
|
||||
|
||||
const int NUM_ROWS = 1000;
|
||||
int expectedSum = 0;
|
||||
QString fillQuery = "INSERT INTO " + tableName + " VALUES (0)";
|
||||
for (int i = 1; i < NUM_ROWS; ++i) {
|
||||
fillQuery += ", (" + QString::number(i) + ")";
|
||||
expectedSum += i;
|
||||
}
|
||||
QVERIFY_SQL(q, exec(fillQuery));
|
||||
|
||||
QVERIFY_SQL(q, prepare("SELECT id FROM "+tableName));
|
||||
QBENCHMARK {
|
||||
QVERIFY_SQL(q, exec());
|
||||
int sum = 0;
|
||||
|
||||
while (q.next())
|
||||
sum += q.value(0).toInt();
|
||||
|
||||
QCOMPARE(sum, expectedSum);
|
||||
}
|
||||
|
||||
tst_Databases::safeDropTable(db, tableName);
|
||||
}
|
||||
|
||||
#include "main.moc"
|
||||
|
Loading…
x
Reference in New Issue
Block a user