summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/windows
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms/windows')
-rw-r--r--src/plugins/platforms/windows/accessible/iaccessible2.cpp8
-rw-r--r--src/plugins/platforms/windows/main.cpp6
-rw-r--r--src/plugins/platforms/windows/qtwindows_additional.h4
-rw-r--r--src/plugins/platforms/windows/qtwindowsglobal.h10
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.cpp45
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.h5
-rw-r--r--src/plugins/platforms/windows/qwindowsdialoghelpers.cpp235
-rw-r--r--src/plugins/platforms/windows/qwindowsdialoghelpers.h1
-rw-r--r--src/plugins/platforms/windows/qwindowsfontdatabase.cpp4
-rw-r--r--src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp4
-rw-r--r--src/plugins/platforms/windows/qwindowsfontengine.cpp17
-rw-r--r--src/plugins/platforms/windows/qwindowsfontengine.h1
-rw-r--r--src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp141
-rw-r--r--src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h2
-rw-r--r--src/plugins/platforms/windows/qwindowsglcontext.cpp10
-rw-r--r--src/plugins/platforms/windows/qwindowstabletsupport.cpp473
-rw-r--r--src/plugins/platforms/windows/qwindowstabletsupport.h142
-rw-r--r--src/plugins/platforms/windows/qwindowstheme.cpp121
-rw-r--r--src/plugins/platforms/windows/qwindowstheme.h3
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.cpp75
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.h1
-rw-r--r--src/plugins/platforms/windows/windows.pro6
22 files changed, 1069 insertions, 245 deletions
diff --git a/src/plugins/platforms/windows/accessible/iaccessible2.cpp b/src/plugins/platforms/windows/accessible/iaccessible2.cpp
index 7a28fd9074..a0f2c1812f 100644
--- a/src/plugins/platforms/windows/accessible/iaccessible2.cpp
+++ b/src/plugins/platforms/windows/accessible/iaccessible2.cpp
@@ -1207,10 +1207,14 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_rowColumnExtents(long *row,
{
QAccessibleInterface *accessible = accessibleInterface();
accessibleDebugClientCalls(accessible);
- if (!accessible)
+ if (!accessible || !tableCellInterface())
return E_FAIL;
- tableCellInterface()->rowColumnExtents((int*)row, (int*)column, (int*)rowExtents, (int*)columnExtents, (bool*)isSelected);
+ *row = (long)tableCellInterface()->rowIndex();
+ *column = (long)tableCellInterface()->columnIndex();
+ *rowExtents = (long)tableCellInterface()->rowExtent();
+ *columnExtents = (long)tableCellInterface()->columnExtent();
+ *isSelected = tableCellInterface()->isSelected();
return S_OK;
}
diff --git a/src/plugins/platforms/windows/main.cpp b/src/plugins/platforms/windows/main.cpp
index e5c3269a6c..ffd87af193 100644
--- a/src/plugins/platforms/windows/main.cpp
+++ b/src/plugins/platforms/windows/main.cpp
@@ -105,12 +105,12 @@ QT_BEGIN_NAMESPACE
class QWindowsIntegrationPlugin : public QPlatformIntegrationPlugin
{
Q_OBJECT
- Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.1" FILE "windows.json")
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.2" FILE "windows.json")
public:
- QPlatformIntegration *create(const QString&, const QStringList&);
+ QPlatformIntegration *create(const QString&, const QStringList&, int &, char **);
};
-QPlatformIntegration *QWindowsIntegrationPlugin::create(const QString& system, const QStringList& paramList)
+QPlatformIntegration *QWindowsIntegrationPlugin::create(const QString& system, const QStringList& paramList, int &, char **)
{
if (system.compare(system, QStringLiteral("windows"), Qt::CaseInsensitive) == 0)
return new QWindowsIntegration(paramList);
diff --git a/src/plugins/platforms/windows/qtwindows_additional.h b/src/plugins/platforms/windows/qtwindows_additional.h
index 49ddf3106b..4c08a664d8 100644
--- a/src/plugins/platforms/windows/qtwindows_additional.h
+++ b/src/plugins/platforms/windows/qtwindows_additional.h
@@ -49,6 +49,10 @@
# define WM_THEMECHANGED 0x031A
#endif
+#ifndef WM_DWMCOMPOSITIONCHANGED
+# define WM_DWMCOMPOSITIONCHANGED 0x31E
+#endif
+
#ifndef GWL_HWNDPARENT
# define GWL_HWNDPARENT (-8)
#endif
diff --git a/src/plugins/platforms/windows/qtwindowsglobal.h b/src/plugins/platforms/windows/qtwindowsglobal.h
index 238817e85c..e9eb50799e 100644
--- a/src/plugins/platforms/windows/qtwindowsglobal.h
+++ b/src/plugins/platforms/windows/qtwindowsglobal.h
@@ -83,6 +83,7 @@ enum WindowsEventType // Simplify event types
CalculateSize = WindowEventFlag + 16,
FocusInEvent = WindowEventFlag + 17,
FocusOutEvent = WindowEventFlag + 18,
+ WhatsThisEvent = WindowEventFlag + 19,
MouseEvent = MouseEventFlag + 1,
MouseWheelEvent = MouseEventFlag + 2,
CursorEvent = MouseEventFlag + 3,
@@ -104,6 +105,7 @@ enum WindowsEventType // Simplify event types
InputMethodCloseCandidateWindowEvent = InputMethodEventFlag + 5,
InputMethodRequest = InputMethodEventFlag + 6,
ThemeChanged = ThemingEventFlag + 1,
+ CompositionSettingsChanged = ThemingEventFlag + 2,
DisplayChangedEvent = 437,
SettingChangedEvent = DisplayChangedEvent + 1,
ContextMenu = 123,
@@ -200,10 +202,18 @@ inline QtWindows::WindowsEventType windowsEventType(UINT message, WPARAM wParamI
return QtWindows::DisplayChangedEvent;
case WM_THEMECHANGED:
return QtWindows::ThemeChanged;
+ case WM_DWMCOMPOSITIONCHANGED:
+ return QtWindows::CompositionSettingsChanged;
#ifndef QT_NO_CONTEXTMENU
case WM_CONTEXTMENU:
return QtWindows::ContextMenu;
#endif
+ case WM_SYSCOMMAND:
+#ifndef Q_OS_WINCE
+ if ((wParamIn & 0xfff0) == SC_CONTEXTHELP)
+ return QtWindows::WhatsThisEvent;
+#endif
+ break;
default:
break;
}
diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp
index 5114e9d524..8dab1e2b1c 100644
--- a/src/plugins/platforms/windows/qwindowscontext.cpp
+++ b/src/plugins/platforms/windows/qwindowscontext.cpp
@@ -47,6 +47,7 @@
#include "qtwindowsglobal.h"
#include "qwindowsmime.h"
#include "qwindowsinputcontext.h"
+#include "qwindowstabletsupport.h"
#ifndef QT_NO_ACCESSIBILITY
#include "accessible/qwindowsaccessibility.h"
#endif
@@ -83,6 +84,7 @@ int QWindowsContext::verboseOLE = 0;
int QWindowsContext::verboseInputMethods = 0;
int QWindowsContext::verboseDialogs = 0;
int QWindowsContext::verboseTheming = 0;
+int QWindowsContext::verboseTablet = 0;
// Get verbosity of components from "foo:2,bar:3"
static inline int componentVerbose(const char *v, const char *keyWord)
@@ -216,6 +218,7 @@ bool QWindowsUser32DLL::initTouch()
QWindowsShell32DLL::QWindowsShell32DLL()
: sHCreateItemFromParsingName(0)
, sHGetStockIconInfo(0)
+ , sHGetImageList(0)
{
}
@@ -224,6 +227,7 @@ void QWindowsShell32DLL::init()
QSystemLibrary library(QStringLiteral("shell32"));
sHCreateItemFromParsingName = (SHCreateItemFromParsingName)(library.resolve("SHCreateItemFromParsingName"));
sHGetStockIconInfo = (SHGetStockIconInfo)library.resolve("SHGetStockIconInfo");
+ sHGetImageList = (SHGetImageList)library.resolve("SHGetImageList");
}
QWindowsUser32DLL QWindowsContext::user32dll;
@@ -259,17 +263,20 @@ struct QWindowsContextPrivate {
QWindowsMimeConverter m_mimeConverter;
QWindowsScreenManager m_screenManager;
QSharedPointer<QWindowCreationContext> m_creationContext;
+#if !defined(QT_NO_TABLETEVENT) && !defined(Q_OS_WINCE)
+ QScopedPointer<QWindowsTabletSupport> m_tabletSupport;
+#endif
const HRESULT m_oleInitializeResult;
const QByteArray m_eventType;
QWindow *m_lastActiveWindow;
bool m_asyncExpose;
};
-QWindowsContextPrivate::QWindowsContextPrivate() :
- m_systemInfo(0),
- m_oleInitializeResult(OleInitialize(NULL)),
- m_eventType(QByteArrayLiteral("windows_generic_MSG")),
- m_lastActiveWindow(0), m_asyncExpose(0)
+QWindowsContextPrivate::QWindowsContextPrivate()
+ : m_systemInfo(0)
+ , m_oleInitializeResult(OleInitialize(NULL))
+ , m_eventType(QByteArrayLiteral("windows_generic_MSG"))
+ , m_lastActiveWindow(0), m_asyncExpose(0)
{
const QSysInfo::WinVersion ver = QSysInfo::windowsVersion();
#ifndef Q_OS_WINCE
@@ -310,7 +317,13 @@ QWindowsContext::QWindowsContext() :
QWindowsContext::verboseInputMethods = componentVerbose(v, "im");
QWindowsContext::verboseDialogs = componentVerbose(v, "dialogs");
QWindowsContext::verboseTheming = componentVerbose(v, "theming");
+ QWindowsContext::verboseTablet = componentVerbose(v, "tablet");
}
+#if !defined(QT_NO_TABLETEVENT) && !defined(Q_OS_WINCE)
+ d->m_tabletSupport.reset(QWindowsTabletSupport::create());
+ if (QWindowsContext::verboseTablet)
+ qDebug() << "Tablet support: " << (d->m_tabletSupport.isNull() ? QStringLiteral("None") : d->m_tabletSupport->description());
+#endif
}
QWindowsContext::~QWindowsContext()
@@ -631,6 +644,15 @@ QWindowsScreenManager &QWindowsContext::screenManager()
return d->m_screenManager;
}
+QWindowsTabletSupport *QWindowsContext::tabletSupport() const
+{
+#if !defined(QT_NO_TABLETEVENT) && !defined(Q_OS_WINCE)
+ return d->m_tabletSupport.data();
+#else
+ return 0;
+#endif
+}
+
/*!
\brief Convenience to create a non-visible, message-only dummy
window for example used as clipboard watcher or for GL.
@@ -864,8 +886,15 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
theme->windowsThemeChanged(platformWindow->window());
return true;
}
+ case QtWindows::CompositionSettingsChanged:
+ platformWindow->handleCompositionSettingsChanged();
+ return true;
#ifndef Q_OS_WINCE
case QtWindows::ActivateWindowEvent:
+#ifndef QT_NO_TABLETEVENT
+ if (!d->m_tabletSupport.isNull())
+ d->m_tabletSupport->notifyActivate();
+#endif // !QT_NO_TABLETEVENT
if (platformWindow->testFlag(QWindowsWindow::BlockedByModal))
if (const QWindow *modalWindow = QGuiApplication::modalWindow())
QWindowsWindow::baseWindowOf(modalWindow)->alertWindow();
@@ -875,6 +904,12 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
case QtWindows::ContextMenu:
return handleContextMenuEvent(platformWindow->window(), msg);
#endif
+ case QtWindows::WhatsThisEvent: {
+#ifndef QT_NO_WHATSTHIS
+ QWindowSystemInterface::handleEnterWhatsThisEvent();
+ return true;
+#endif
+ } break;
default:
break;
}
diff --git a/src/plugins/platforms/windows/qwindowscontext.h b/src/plugins/platforms/windows/qwindowscontext.h
index 6b80075379..173df58570 100644
--- a/src/plugins/platforms/windows/qwindowscontext.h
+++ b/src/plugins/platforms/windows/qwindowscontext.h
@@ -56,6 +56,7 @@ QT_BEGIN_NAMESPACE
class QWindow;
class QPlatformScreen;
class QWindowsScreenManager;
+class QWindowsTabletSupport;
class QWindowsWindow;
class QWindowsMimeConverter;
struct QWindowCreationContext;
@@ -107,9 +108,11 @@ struct QWindowsShell32DLL
typedef HRESULT (WINAPI *SHCreateItemFromParsingName)(PCWSTR, IBindCtx *, const GUID&, void **);
typedef HRESULT (WINAPI *SHGetStockIconInfo)(int , int , _SHSTOCKICONINFO *);
+ typedef HRESULT (WINAPI *SHGetImageList)(int, REFIID , void **);
SHCreateItemFromParsingName sHCreateItemFromParsingName;
SHGetStockIconInfo sHGetStockIconInfo;
+ SHGetImageList sHGetImageList;
};
#endif // Q_OS_WINCE
@@ -135,6 +138,7 @@ public:
static int verboseInputMethods;
static int verboseDialogs;
static int verboseTheming;
+ static int verboseTablet;
explicit QWindowsContext();
~QWindowsContext();
@@ -185,6 +189,7 @@ public:
QWindowsMimeConverter &mimeConverter() const;
QWindowsScreenManager &screenManager();
+ QWindowsTabletSupport *tabletSupport() const;
#ifndef Q_OS_WINCE
static QWindowsUser32DLL user32dll;
static QWindowsShell32DLL shell32dll;
diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
index 9a7d03c0c2..0e6c49aedb 100644
--- a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
+++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
@@ -39,6 +39,8 @@
**
****************************************************************************/
+#define QT_NO_URL_CAST_FROM_STRING 1
+
#include "qwindowsdialoghelpers.h"
#include "qwindowscontext.h"
@@ -64,6 +66,8 @@
#include <QtCore/QMutexLocker>
#include <QtCore/private/qsystemlibrary_p.h>
+#include <algorithm>
+
#include "qtwindows_additional.h"
#define STRICT_TYPED_ITEMIDS
@@ -613,24 +617,6 @@ void QWindowsDialogHelperBase<BaseClass>::exec()
}
}
-static inline bool snapToDefaultButtonHint()
-{
- BOOL snapToDefault = false;
- if (SystemParametersInfo(SPI_GETSNAPTODEFBUTTON, 0, &snapToDefault, 0))
- return snapToDefault;
- return false;
-}
-
-template <class BaseClass>
-QVariant QWindowsDialogHelperBase<BaseClass>::styleHint(QPlatformDialogHelper::StyleHint hint) const
-{
- switch (hint) {
- case QPlatformDialogHelper::SnapToDefaultButton:
- return QVariant(snapToDefaultButtonHint());
- }
- return BaseClass::styleHint(hint);
-}
-
/*!
\class QWindowsFileDialogSharedData
\brief Explicitly shared file dialog parameters that are not in QFileDialogOptions.
@@ -651,34 +637,34 @@ public:
QWindowsFileDialogSharedData() : m_data(new Data) {}
void fromOptions(const QSharedPointer<QFileDialogOptions> &o);
- QString directory() const;
- void setDirectory(const QString &);
+ QUrl directory() const;
+ void setDirectory(const QUrl &);
QString selectedNameFilter() const;
void setSelectedNameFilter(const QString &);
- QStringList selectedFiles() const;
- void setSelectedFiles(const QStringList &);
+ QList<QUrl> selectedFiles() const;
+ void setSelectedFiles(const QList<QUrl> &);
QString selectedFile() const;
private:
class Data : public QSharedData {
public:
- QString directory;
+ QUrl directory;
QString selectedNameFilter;
- QStringList selectedFiles;
+ QList<QUrl> selectedFiles;
QMutex mutex;
};
QExplicitlySharedDataPointer<Data> m_data;
};
-inline QString QWindowsFileDialogSharedData::directory() const
+inline QUrl QWindowsFileDialogSharedData::directory() const
{
m_data->mutex.lock();
- const QString result = m_data->directory;
+ const QUrl result = m_data->directory;
m_data->mutex.unlock();
return result;
}
-inline void QWindowsFileDialogSharedData::setDirectory(const QString &d)
+inline void QWindowsFileDialogSharedData::setDirectory(const QUrl &d)
{
QMutexLocker (&m_data->mutex);
m_data->directory = d;
@@ -698,24 +684,24 @@ inline void QWindowsFileDialogSharedData::setSelectedNameFilter(const QString &f
m_data->selectedNameFilter = f;
}
-inline QStringList QWindowsFileDialogSharedData::selectedFiles() const
+inline QList<QUrl> QWindowsFileDialogSharedData::selectedFiles() const
{
m_data->mutex.lock();
- const QStringList result = m_data->selectedFiles;
+ const QList<QUrl> result = m_data->selectedFiles;
m_data->mutex.unlock();
return result;
}
inline QString QWindowsFileDialogSharedData::selectedFile() const
{
- const QStringList files = selectedFiles();
- return files.isEmpty() ? QString() : files.front();
+ const QList<QUrl> files = selectedFiles();
+ return files.isEmpty() ? QString() : files.front().toLocalFile();
}
-inline void QWindowsFileDialogSharedData::setSelectedFiles(const QStringList &f)
+inline void QWindowsFileDialogSharedData::setSelectedFiles(const QList<QUrl> &urls)
{
QMutexLocker (&m_data->mutex);
- m_data->selectedFiles = f;
+ m_data->selectedFiles = urls;
}
inline void QWindowsFileDialogSharedData::fromOptions(const QSharedPointer<QFileDialogOptions> &o)
@@ -779,7 +765,7 @@ public:
QWindowsNativeFileDialogEventHandler(QWindowsNativeFileDialogBase *nativeFileDialog) :
m_ref(1), m_nativeFileDialog(nativeFileDialog) {}
- ~QWindowsNativeFileDialogEventHandler() {}
+ virtual ~QWindowsNativeFileDialogEventHandler() {}
private:
long m_ref;
@@ -822,7 +808,7 @@ public:
virtual void setWindowTitle(const QString &title);
inline void setMode(QFileDialogOptions::FileMode mode, QFileDialogOptions::FileDialogOptions options);
inline void setDirectory(const QString &directory);
- inline void updateDirectory() { setDirectory(m_data.directory()); }
+ inline void updateDirectory() { setDirectory(m_data.directory().toLocalFile()); }
inline QString directory() const;
virtual void exec(HWND owner = 0);
virtual void setNameFilters(const QStringList &f);
@@ -837,10 +823,10 @@ public:
inline void setLabelText(QFileDialogOptions::DialogLabel l, const QString &text);
// Return the selected files for tracking in OnSelectionChanged().
- virtual QStringList selectedFiles() const = 0;
+ virtual QList<QUrl> selectedFiles() const = 0;
// Return the result for tracking in OnFileOk(). Differs from selection for
// example by appended default suffixes, etc.
- virtual QStringList dialogResult() const = 0;
+ virtual QList<QUrl> dialogResult() const = 0;
inline void onFolderChange(IShellItem *);
inline void onSelectionChange();
@@ -848,8 +834,8 @@ public:
inline bool onFileOk();
signals:
- void directoryEntered(const QString& directory);
- void currentChanged(const QString& file);
+ void directoryEntered(const QUrl &directory);
+ void currentChanged(const QUrl &file);
void filterSelected(const QString & filter);
public slots:
@@ -861,9 +847,9 @@ protected:
void setDefaultSuffixSys(const QString &s);
inline IFileDialog * fileDialog() const { return m_fileDialog; }
static QString itemPath(IShellItem *item);
- static QStringList libraryItemFolders(IShellItem *item);
+ static QList<QUrl> libraryItemFolders(IShellItem *item);
static QString libraryItemDefaultSaveFolder(IShellItem *item);
- static int itemPaths(IShellItemArray *items, QStringList *fileResult = 0);
+ static int itemPaths(IShellItemArray *items, QList<QUrl> *fileResult = 0);
static IShellItem *shellItem(const QString &path);
const QWindowsFileDialogSharedData &data() const { return m_data; }
@@ -1031,9 +1017,9 @@ static IShellLibrary *sHLoadLibraryFromItem(IShellItem *libraryItem, DWORD mode)
}
// Return all folders of a library-type item.
-QStringList QWindowsNativeFileDialogBase::libraryItemFolders(IShellItem *item)
+QList<QUrl> QWindowsNativeFileDialogBase::libraryItemFolders(IShellItem *item)
{
- QStringList result;
+ QList<QUrl> result;
if (IShellLibrary *library = sHLoadLibraryFromItem(item, STGM_READ | STGM_SHARE_DENY_WRITE)) {
IShellItemArray *itemArray = 0;
if (SUCCEEDED(library->GetFolders(LFF_FORCEFILESYSTEM, IID_IShellItemArray, reinterpret_cast<void **>(&itemArray)))) {
@@ -1062,9 +1048,9 @@ QString QWindowsNativeFileDialogBase::libraryItemDefaultSaveFolder(IShellItem *i
#else // !Q_OS_WINCE && __IShellLibrary_INTERFACE_DEFINED__
-QStringList QWindowsNativeFileDialogBase::libraryItemFolders(IShellItem *)
+QList<QUrl> QWindowsNativeFileDialogBase::libraryItemFolders(IShellItem *)
{
- return QStringList();
+ return QList<QUrl>();
}
QString QWindowsNativeFileDialogBase::libraryItemDefaultSaveFolder(IShellItem *)
@@ -1096,7 +1082,7 @@ QString QWindowsNativeFileDialogBase::itemPath(IShellItem *item)
}
int QWindowsNativeFileDialogBase::itemPaths(IShellItemArray *items,
- QStringList *result /* = 0 */)
+ QList<QUrl> *result /* = 0 */)
{
DWORD itemCount = 0;
if (result)
@@ -1108,7 +1094,7 @@ int QWindowsNativeFileDialogBase::itemPaths(IShellItemArray *items,
for (DWORD i = 0; i < itemCount; ++i) {
IShellItem *item = 0;
if (SUCCEEDED(items->GetItemAt(i, &item)))
- result->push_back(QWindowsNativeFileDialogBase::itemPath(item));
+ result->push_back(QUrl::fromLocalFile(QWindowsNativeFileDialogBase::itemPath(item)));
}
}
return itemCount;
@@ -1270,7 +1256,7 @@ QString QWindowsNativeFileDialogBase::selectedNameFilter() const
void QWindowsNativeFileDialogBase::onFolderChange(IShellItem *item)
{
if (item) {
- const QString directory = QWindowsNativeFileDialogBase::itemPath(item);
+ const QUrl directory = QUrl::fromLocalFile(QWindowsNativeFileDialogBase::itemPath(item));
m_data.setDirectory(directory);
emit directoryEntered(directory);
}
@@ -1278,7 +1264,7 @@ void QWindowsNativeFileDialogBase::onFolderChange(IShellItem *item)
void QWindowsNativeFileDialogBase::onSelectionChange()
{
- const QStringList current = selectedFiles();
+ const QList<QUrl> current = selectedFiles();
m_data.setSelectedFiles(current);
if (current.size() == 1)
emit currentChanged(current.front());
@@ -1338,8 +1324,8 @@ public:
explicit QWindowsNativeSaveFileDialog(const QWindowsFileDialogSharedData &data)
: QWindowsNativeFileDialogBase(data) {}
virtual void setNameFilters(const QStringList &f);
- virtual QStringList selectedFiles() const;
- virtual QStringList dialogResult() const;
+ virtual QList<QUrl> selectedFiles() const;
+ virtual QList<QUrl> dialogResult() const;
};
// Return the first suffix from the name filter "Foo files (*.foo;*.bar)" -> "foo".
@@ -1374,22 +1360,22 @@ void QWindowsNativeSaveFileDialog::setNameFilters(const QStringList &f)
} // m_hasDefaultSuffix
}
-QStringList QWindowsNativeSaveFileDialog::dialogResult() const
+QList<QUrl> QWindowsNativeSaveFileDialog::dialogResult() const
{
- QStringList result;
+ QList<QUrl> result;
IShellItem *item = 0;
if (SUCCEEDED(fileDialog()->GetResult(&item)) && item)
- result.push_back(QWindowsNativeFileDialogBase::itemPath(item));
+ result.push_back(QUrl::fromLocalFile(QWindowsNativeFileDialogBase::itemPath(item)));
return result;
}
-QStringList QWindowsNativeSaveFileDialog::selectedFiles() const
+QList<QUrl> QWindowsNativeSaveFileDialog::selectedFiles() const
{
- QStringList result;
+ QList<QUrl> result;
IShellItem *item = 0;
const HRESULT hr = fileDialog()->GetCurrentSelection(&item);
if (SUCCEEDED(hr) && item)
- result.push_back(QWindowsNativeSaveFileDialog::itemPath(item));
+ result.push_back(QUrl::fromLocalFile(QWindowsNativeSaveFileDialog::itemPath(item)));
return result;
}
@@ -1408,26 +1394,26 @@ class QWindowsNativeOpenFileDialog : public QWindowsNativeFileDialogBase
public:
explicit QWindowsNativeOpenFileDialog(const QWindowsFileDialogSharedData &data) :
QWindowsNativeFileDialogBase(data) {}
- virtual QStringList selectedFiles() const;
- virtual QStringList dialogResult() const;
+ virtual QList<QUrl> selectedFiles() const;
+ virtual QList<QUrl> dialogResult() const;
private:
inline IFileOpenDialog *openFileDialog() const
{ return static_cast<IFileOpenDialog *>(fileDialog()); }
};
-QStringList QWindowsNativeOpenFileDialog::dialogResult() const
+QList<QUrl> QWindowsNativeOpenFileDialog::dialogResult() const
{
- QStringList result;
+ QList<QUrl> result;
IShellItemArray *items = 0;
if (SUCCEEDED(openFileDialog()->GetResults(&items)) && items)
QWindowsNativeFileDialogBase::itemPaths(items, &result);
return result;
}
-QStringList QWindowsNativeOpenFileDialog::selectedFiles() const
+QList<QUrl> QWindowsNativeOpenFileDialog::selectedFiles() const
{
- QStringList result;
+ QList<QUrl> result;
IShellItemArray *items = 0;
const HRESULT hr = openFileDialog()->GetSelectedItems(&items);
if (SUCCEEDED(hr) && items)
@@ -1484,14 +1470,13 @@ public:
virtual bool supportsNonModalDialog(const QWindow * /* parent */ = 0) const { return false; }
virtual bool defaultNameFilterDisables() const
{ return true; }
- virtual void setDirectory(const QString &directory);
- virtual QString directory() const;
- virtual void selectFile(const QString &filename);
- virtual QStringList selectedFiles() const;
- virtual void setFilter();
- virtual void setNameFilters(const QStringList &filters);
- virtual void selectNameFilter(const QString &filter);
- virtual QString selectedNameFilter() const;
+ virtual void setDirectory(const QUrl &directory) Q_DECL_OVERRIDE;
+ virtual QUrl directory() const Q_DECL_OVERRIDE;
+ virtual void selectFile(const QUrl &filename) Q_DECL_OVERRIDE;
+ virtual QList<QUrl> selectedFiles() const Q_DECL_OVERRIDE;
+ virtual void setFilter() Q_DECL_OVERRIDE;
+ virtual void selectNameFilter(const QString &filter) Q_DECL_OVERRIDE;
+ virtual QString selectedNameFilter() const Q_DECL_OVERRIDE;
private:
virtual QWindowsNativeDialogBase *createNativeDialog();
@@ -1509,10 +1494,10 @@ QWindowsNativeDialogBase *QWindowsFileDialogHelper::createNativeDialog()
return 0;
QObject::connect(result, SIGNAL(accepted()), this, SIGNAL(accept()));
QObject::connect(result, SIGNAL(rejected()), this, SIGNAL(reject()));
- QObject::connect(result, SIGNAL(directoryEntered(QString)),
- this, SIGNAL(directoryEntered(QString)));
- QObject::connect(result, SIGNAL(currentChanged(QString)),
- this, SIGNAL(currentChanged(QString)));
+ QObject::connect(result, SIGNAL(directoryEntered(QUrl)),
+ this, SIGNAL(directoryEntered(QUrl)));
+ QObject::connect(result, SIGNAL(currentChanged(QUrl)),
+ this, SIGNAL(currentChanged(QUrl)));
QObject::connect(result, SIGNAL(filterSelected(QString)),
this, SIGNAL(filterSelected(QString)));
@@ -1532,11 +1517,16 @@ QWindowsNativeDialogBase *QWindowsFileDialogHelper::createNativeDialog()
result->setLabelText(QFileDialogOptions::Accept, opts->labelText(QFileDialogOptions::Accept));
result->updateDirectory();
result->updateSelectedNameFilter();
- const QStringList initialSelection = opts->initiallySelectedFiles();
+ const QList<QUrl> initialSelection = opts->initiallySelectedFiles();
if (initialSelection.size() > 0) {
- QFileInfo info(initialSelection.front());
- if (!info.isDir())
- result->selectFile(info.fileName());
+ const QUrl url = initialSelection.front();
+ if (url.isLocalFile()) {
+ QFileInfo info(url.toLocalFile());
+ if (!info.isDir())
+ result->selectFile(info.fileName());
+ } else {
+ result->selectFile(url.path()); // TODO url.fileName() once it exists
+ }
}
// No need to select initialNameFilter if mode is Dir
if (mode != QFileDialogOptions::Directory && mode != QFileDialogOptions::DirectoryOnly) {
@@ -1550,31 +1540,31 @@ QWindowsNativeDialogBase *QWindowsFileDialogHelper::createNativeDialog()
return result;
}
-void QWindowsFileDialogHelper::setDirectory(const QString &directory)
+void QWindowsFileDialogHelper::setDirectory(const QUrl &directory)
{
if (QWindowsContext::verboseDialogs)
- qDebug("%s %s" , __FUNCTION__, qPrintable(directory));
+ qDebug("%s %s" , __FUNCTION__, qPrintable(directory.toString()));
m_data.setDirectory(directory);
if (hasNativeDialog())
nativeFileDialog()->updateDirectory();
}
-QString QWindowsFileDialogHelper::directory() const
+QUrl QWindowsFileDialogHelper::directory() const
{
return m_data.directory();
}
-void QWindowsFileDialogHelper::selectFile(const QString &fileName)
+void QWindowsFileDialogHelper::selectFile(const QUrl &fileName)
{
if (QWindowsContext::verboseDialogs)
- qDebug("%s %s" , __FUNCTION__, qPrintable(fileName));
+ qDebug("%s %s" , __FUNCTION__, qPrintable(fileName.toString()));
if (QWindowsNativeFileDialogBase *nfd = nativeFileDialog())
- nfd->selectFile(fileName);
+ nfd->selectFile(fileName.toLocalFile()); // ## should use QUrl::fileName() once it exists
}
-QStringList QWindowsFileDialogHelper::selectedFiles() const
+QList<QUrl> QWindowsFileDialogHelper::selectedFiles() const
{
return m_data.selectedFiles();
}
@@ -1585,14 +1575,6 @@ void QWindowsFileDialogHelper::setFilter()
qDebug("%s" , __FUNCTION__);
}
-void QWindowsFileDialogHelper::setNameFilters(const QStringList &filters)
-{
- if (QWindowsContext::verboseDialogs)
- qDebug("%s" , __FUNCTION__);
- if (QWindowsNativeFileDialogBase *nfd = nativeFileDialog())
- nfd->setNameFilters(filters);
-}
-
void QWindowsFileDialogHelper::selectNameFilter(const QString &filter)
{
m_data.setSelectedNameFilter(filter);
@@ -1643,8 +1625,8 @@ private:
explicit QWindowsXpNativeFileDialog(const OptionsPtr &options, const QWindowsFileDialogSharedData &data);
void populateOpenFileName(OPENFILENAME *ofn, HWND owner) const;
- QStringList execExistingDir(HWND owner);
- QStringList execFileNames(HWND owner, int *selectedFilterIndex) const;
+ QList<QUrl> execExistingDir(HWND owner);
+ QList<QUrl> execFileNames(HWND owner, int *selectedFilterIndex) const;
const OptionsPtr m_options;
QString m_title;
@@ -1683,7 +1665,7 @@ QWindowsXpNativeFileDialog::QWindowsXpNativeFileDialog(const OptionsPtr &options
void QWindowsXpNativeFileDialog::exec(HWND owner)
{
int selectedFilterIndex = -1;
- const QStringList selectedFiles =
+ const QList<QUrl> selectedFiles =
m_options->fileMode() == QFileDialogOptions::DirectoryOnly ?
execExistingDir(owner) : execFileNames(owner, &selectedFilterIndex);
m_data.setSelectedFiles(selectedFiles);
@@ -1695,7 +1677,8 @@ void QWindowsXpNativeFileDialog::exec(HWND owner)
const QStringList nameFilters = m_options->nameFilters();
if (selectedFilterIndex >= 0 && selectedFilterIndex < nameFilters.size())
m_data.setSelectedNameFilter(nameFilters.at(selectedFilterIndex));
- m_data.setDirectory(QFileInfo(selectedFiles.front()).absolutePath());
+ QUrl firstFile = selectedFiles.front();
+ m_data.setDirectory(firstFile.adjusted(QUrl::RemoveFilename));
m_result = QPlatformDialogHelper::Accepted;
emit accepted();
}
@@ -1722,7 +1705,7 @@ int QWindowsXpNativeFileDialog::existingDirCallback(HWND hwnd, UINT uMsg, LPARAM
case BFFM_INITIALIZED: {
if (!m_title.isEmpty())
SetWindowText(hwnd, (wchar_t *)m_title.utf16());
- const QString initialFile = QDir::toNativeSeparators(m_data.directory());
+ const QString initialFile = QDir::toNativeSeparators(m_data.directory().toLocalFile());
if (!initialFile.isEmpty())
SendMessage(hwnd, BFFM_SETSELECTION, TRUE, LPARAM(initialFile.utf16()));
}
@@ -1738,7 +1721,7 @@ int QWindowsXpNativeFileDialog::existingDirCallback(HWND hwnd, UINT uMsg, LPARAM
return 0;
}
-QStringList QWindowsXpNativeFileDialog::execExistingDir(HWND owner)
+QList<QUrl> QWindowsXpNativeFileDialog::execExistingDir(HWND owner)
{
BROWSEINFO bi;
wchar_t initPath[MAX_PATH];
@@ -1750,12 +1733,12 @@ QStringList QWindowsXpNativeFileDialog::execExistingDir(HWND owner)
bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_STATUSTEXT | BIF_NEWDIALOGSTYLE;
bi.lpfn = xpFileDialogGetExistingDirCallbackProc;
bi.lParam = LPARAM(this);
- QStringList selectedFiles;
+ QList<QUrl> selectedFiles;
if (qt_LpItemIdList pItemIDList = SHBrowseForFolder(&bi)) {
wchar_t path[MAX_PATH];
path[0] = 0;
if (SHGetPathFromIDList(pItemIDList, path) && path[0])
- selectedFiles.push_back(QDir::cleanPath(QString::fromWCharArray(path)));
+ selectedFiles.push_back(QUrl::fromLocalFile(QDir::cleanPath(QString::fromWCharArray(path))));
IMalloc *pMalloc;
if (SHGetMalloc(&pMalloc) == NOERROR) {
pMalloc->Free(pItemIDList);
@@ -1807,7 +1790,7 @@ void QWindowsXpNativeFileDialog::populateOpenFileName(OPENFILENAME *ofn, HWND ow
QDir::toNativeSeparators(m_data.selectedFile()).remove(QLatin1Char('<')).
remove(QLatin1Char('>')).remove(QLatin1Char('"')).remove(QLatin1Char('|'));
ofn->lpstrFile = qStringToWCharArray(initiallySelectedFile, ofn->nMaxFile);
- ofn->lpstrInitialDir = qStringToWCharArray(QDir::toNativeSeparators(m_data.directory()));
+ ofn->lpstrInitialDir = qStringToWCharArray(QDir::toNativeSeparators(m_data.directory().toLocalFile()));
ofn->lpstrTitle = (wchar_t*)m_title.utf16();
// Determine lpstrDefExt. Note that the current MSDN docs document this
// member wrong. It should rather be documented as "the default extension
@@ -1832,25 +1815,27 @@ void QWindowsXpNativeFileDialog::populateOpenFileName(OPENFILENAME *ofn, HWND ow
ofn->Flags |= OFN_OVERWRITEPROMPT;
}
-QStringList QWindowsXpNativeFileDialog::execFileNames(HWND owner, int *selectedFilterIndex) const
+QList<QUrl> QWindowsXpNativeFileDialog::execFileNames(HWND owner, int *selectedFilterIndex) const
{
*selectedFilterIndex = -1;
OPENFILENAME ofn;
populateOpenFileName(&ofn, owner);
- QStringList result;
+ QList<QUrl> result;
const bool isSave = m_options->acceptMode() == QFileDialogOptions::AcceptSave;
if (isSave ? m_getSaveFileNameW(&ofn) : m_getOpenFileNameW(&ofn)) {
*selectedFilterIndex = ofn.nFilterIndex - 1;
- result.push_back(QDir::cleanPath(QString::fromWCharArray(ofn.lpstrFile)));
+ const QString dir = QDir::cleanPath(QString::fromWCharArray(ofn.lpstrFile));
+ result.push_back(QUrl::fromLocalFile(dir));
// For multiselection, the first item is the path followed
// by "\0<file1>\0<file2>\0\0".
if (ofn.Flags & (OFN_ALLOWMULTISELECT)) {
- wchar_t *ptr = ofn.lpstrFile + result.front().size() + 1;
+ wchar_t *ptr = ofn.lpstrFile + dir.size() + 1;
if (*ptr) {
- const QString path = result.takeAt(0) + QLatin1Char('/');
+ result.pop_front();
+ const QString path = dir + QLatin1Char('/');
while (*ptr) {
const QString fileName = QString::fromWCharArray(ptr);
- result.push_back(path + fileName);
+ result.push_back(QUrl::fromLocalFile(path + fileName));
ptr += fileName.size() + 1;
} // extract multiple files
} // has multiple files
@@ -1879,14 +1864,13 @@ public:
virtual bool supportsNonModalDialog(const QWindow * /* parent */ = 0) const { return false; }
virtual bool defaultNameFilterDisables() const
{ return true; }
- virtual void setDirectory(const QString &directory);
- virtual QString directory() const;
- virtual void selectFile(const QString &filename);
- virtual QStringList selectedFiles() const;
- virtual void setFilter() {}
- virtual void setNameFilters(const QStringList &);
- virtual void selectNameFilter(const QString &);
- virtual QString selectedNameFilter() const;
+ virtual void setDirectory(const QUrl &directory) Q_DECL_OVERRIDE;
+ virtual QUrl directory() const Q_DECL_OVERRIDE;
+ virtual void selectFile(const QUrl &url) Q_DECL_OVERRIDE;
+ virtual QList<QUrl> selectedFiles() const Q_DECL_OVERRIDE;
+ virtual void setFilter() Q_DECL_OVERRIDE {}
+ virtual void selectNameFilter(const QString &) Q_DECL_OVERRIDE;
+ virtual QString selectedNameFilter() const Q_DECL_OVERRIDE;
private:
virtual QWindowsNativeDialogBase *createNativeDialog();
@@ -1907,31 +1891,26 @@ QWindowsNativeDialogBase *QWindowsXpFileDialogHelper::createNativeDialog()
return 0;
}
-void QWindowsXpFileDialogHelper::setDirectory(const QString &directory)
+void QWindowsXpFileDialogHelper::setDirectory(const QUrl &directory)
{
m_data.setDirectory(directory); // Dialog cannot be updated at run-time.
}
-QString QWindowsXpFileDialogHelper::directory() const
+QUrl QWindowsXpFileDialogHelper::directory() const
{
return m_data.directory();
}
-void QWindowsXpFileDialogHelper::selectFile(const QString &filename)
+void QWindowsXpFileDialogHelper::selectFile(const QUrl &url)
{
- m_data.setSelectedFiles(QStringList(filename)); // Dialog cannot be updated at run-time.
+ m_data.setSelectedFiles(QList<QUrl>() << url); // Dialog cannot be updated at run-time.
}
-QStringList QWindowsXpFileDialogHelper::selectedFiles() const
+QList<QUrl> QWindowsXpFileDialogHelper::selectedFiles() const
{
return m_data.selectedFiles();
}
-void QWindowsXpFileDialogHelper::setNameFilters(const QStringList &)
-{
- // Dialog cannot be updated at run-time.
-}
-
void QWindowsXpFileDialogHelper::selectNameFilter(const QString &f)
{
m_data.setSelectedNameFilter(f); // Dialog cannot be updated at run-time.
@@ -1984,7 +1963,7 @@ private:
QWindowsNativeColorDialog::QWindowsNativeColorDialog(const SharedPointerColor &color) :
m_code(QPlatformDialogHelper::Rejected), m_color(color)
{
- qFill(m_customColors, m_customColors + 16, COLORREF(0));
+ std::fill(m_customColors, m_customColors + 16, COLORREF(0));
}
void QWindowsNativeColorDialog::exec(HWND owner)
diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.h b/src/plugins/platforms/windows/qwindowsdialoghelpers.h
index 7884f398f3..c0ee60cc1e 100644
--- a/src/plugins/platforms/windows/qwindowsdialoghelpers.h
+++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.h
@@ -72,7 +72,6 @@ public:
Qt::WindowModality windowModality,
QWindow *parent);
virtual void hide();
- virtual QVariant styleHint(QPlatformDialogHelper::StyleHint) const;
virtual bool supportsNonModalDialog(const QWindow * /* parent */ = 0) const { return true; }
diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp
index b7ccb5767e..a6bce6502b 100644
--- a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp
+++ b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp
@@ -838,8 +838,6 @@ error:
return i18n_name;
}
-Q_GUI_EXPORT void qt_registerAliasToFontFamily(const QString &familyName, const QString &alias);
-
static bool addFontToDatabase(const QString &familyName, uchar charSet,
const TEXTMETRIC *textmetric,
const FONTSIGNATURE *signature,
@@ -932,7 +930,7 @@ static bool addFontToDatabase(const QString &familyName, uchar charSet,
QFont::StyleItalic, stretch, antialias, scalable, size, fixed, writingSystems, 0);
if (!englishName.isEmpty())
- qt_registerAliasToFontFamily(familyName, englishName);
+ QPlatformFontDatabase::registerAliasToFontFamily(familyName, englishName);
return true;
}
diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp
index 7f97d58be4..6037c201ac 100644
--- a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp
+++ b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp
@@ -122,8 +122,6 @@ static FontFile * createFontFile(const QString &fileName, int index)
extern bool localizedName(const QString &name);
extern QString getEnglishName(const QString &familyName);
-Q_GUI_EXPORT void qt_registerAliasToFontFamily(const QString &familyName, const QString &alias);
-
static bool addFontToDatabase(const QString &familyName, uchar charSet,
const TEXTMETRIC *textmetric,
const FONTSIGNATURE *signature,
@@ -304,7 +302,7 @@ static bool addFontToDatabase(const QString &familyName, uchar charSet,
antialias, scalable, size, fixed, writingSystems, createFontFile(value, index));
if (!englishName.isEmpty())
- qt_registerAliasToFontFamily(faceName, englishName);
+ QPlatformFontDatabase::registerAliasToFontFamily(faceName, englishName);
return true;
}
diff --git a/src/plugins/platforms/windows/qwindowsfontengine.cpp b/src/plugins/platforms/windows/qwindowsfontengine.cpp
index 33ddcaffc5..64457f4b67 100644
--- a/src/plugins/platforms/windows/qwindowsfontengine.cpp
+++ b/src/plugins/platforms/windows/qwindowsfontengine.cpp
@@ -1133,8 +1133,10 @@ QWindowsNativeImage *QWindowsFontEngine::drawGDIGlyph(HFONT font, glyph_t glyph,
<< "If you need them anyway, start your application with -platform windows:fontengine=freetype.";
}
#endif // wince
- QWindowsNativeImage *ni = new QWindowsNativeImage(iw + 2 * margin + 4,
- ih + 2 * margin + 4,
+
+ // The padding here needs to be kept in sync with the values in alphaMapBoundingBox.
+ QWindowsNativeImage *ni = new QWindowsNativeImage(iw + 2 * margin,
+ ih + 2 * margin,
QWindowsNativeImage::systemFormat());
/*If cleartype is enabled we use the standard system format even on Windows CE
@@ -1167,6 +1169,17 @@ QWindowsNativeImage *QWindowsFontEngine::drawGDIGlyph(HFONT font, glyph_t glyph,
return ni;
}
+glyph_metrics_t QWindowsFontEngine::alphaMapBoundingBox(glyph_t glyph, QFixed, const QTransform &matrix, GlyphFormat format)
+{
+ int margin = 0;
+ if (format == QFontEngine::Format_A32 || format == QFontEngine::Format_ARGB)
+ margin = glyphMargin(QFontEngineGlyphCache::Raster_RGBMask);
+ glyph_metrics_t gm = boundingBox(glyph, matrix);
+ gm.width += margin * 2;
+ gm.height += margin * 2;
+ return gm;
+}
+
QImage QWindowsFontEngine::alphaMapForGlyph(glyph_t glyph, const QTransform &xform)
{
HFONT font = hfont;
diff --git a/src/plugins/platforms/windows/qwindowsfontengine.h b/src/plugins/platforms/windows/qwindowsfontengine.h
index 9e92a8fbff..60ff61fcb9 100644
--- a/src/plugins/platforms/windows/qwindowsfontengine.h
+++ b/src/plugins/platforms/windows/qwindowsfontengine.h
@@ -121,6 +121,7 @@ public:
virtual QImage alphaMapForGlyph(glyph_t t) { return alphaMapForGlyph(t, QTransform()); }
virtual QImage alphaMapForGlyph(glyph_t, const QTransform &xform);
virtual QImage alphaRGBMapForGlyph(glyph_t t, QFixed subPixelPosition, const QTransform &xform);
+ virtual glyph_metrics_t alphaMapBoundingBox(glyph_t glyph, QFixed, const QTransform &matrix, GlyphFormat);
virtual QFontEngine *cloneWithSize(qreal pixelSize) const;
virtual bool supportsTransformation(const QTransform &transform) const;
diff --git a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp
index c0f1b3a000..7407d88f8b 100644
--- a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp
+++ b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp
@@ -215,7 +215,9 @@ QWindowsFontEngineDirectWrite::QWindowsFontEngineDirectWrite(IDWriteFontFace *di
if (QWindowsContext::verboseFonts)
qDebug("%s %g", __FUNCTION__, pixelSize);
- d->directWriteFactory->AddRef();
+ Q_ASSERT(m_directWriteFontFace);
+
+ m_fontEngineData->directWriteFactory->AddRef();
m_directWriteFontFace->AddRef();
fontDef.pixelSize = pixelSize;
@@ -237,19 +239,17 @@ QWindowsFontEngineDirectWrite::~QWindowsFontEngineDirectWrite()
void QWindowsFontEngineDirectWrite::collectMetrics()
{
- if (m_directWriteFontFace != 0) {
- DWRITE_FONT_METRICS metrics;
-
- m_directWriteFontFace->GetMetrics(&metrics);
- m_unitsPerEm = metrics.designUnitsPerEm;
-
- m_lineThickness = DESIGN_TO_LOGICAL(metrics.underlineThickness);
- m_ascent = DESIGN_TO_LOGICAL(metrics.ascent);
- m_descent = DESIGN_TO_LOGICAL(metrics.descent);
- m_xHeight = DESIGN_TO_LOGICAL(metrics.xHeight);
- m_lineGap = DESIGN_TO_LOGICAL(metrics.lineGap);
- m_underlinePosition = DESIGN_TO_LOGICAL(metrics.underlinePosition);
- }
+ DWRITE_FONT_METRICS metrics;
+
+ m_directWriteFontFace->GetMetrics(&metrics);
+ m_unitsPerEm = metrics.designUnitsPerEm;
+
+ m_lineThickness = DESIGN_TO_LOGICAL(metrics.underlineThickness);
+ m_ascent = DESIGN_TO_LOGICAL(metrics.ascent);
+ m_descent = DESIGN_TO_LOGICAL(metrics.descent);
+ m_xHeight = DESIGN_TO_LOGICAL(metrics.xHeight);
+ m_lineGap = DESIGN_TO_LOGICAL(metrics.lineGap);
+ m_underlinePosition = DESIGN_TO_LOGICAL(metrics.underlinePosition);
}
QFixed QWindowsFontEngineDirectWrite::underlinePosition() const
@@ -272,31 +272,24 @@ bool QWindowsFontEngineDirectWrite::getSfntTableData(uint tag, uchar *buffer, ui
{
bool ret = false;
- if (m_directWriteFontFace) {
- DWORD t = qbswap<quint32>(tag);
-
- const void *tableData = 0;
- void *tableContext = 0;
- UINT32 tableSize;
- BOOL exists;
- HRESULT hr = m_directWriteFontFace->TryGetFontTable(
- t, &tableData, &tableSize, &tableContext, &exists
- );
-
- if (SUCCEEDED(hr)) {
- if (exists) {
- if (!buffer) {
- *length = tableSize;
- ret = true;
- } else if (*length >= tableSize) {
- memcpy(buffer, tableData, tableSize);
- ret = true;
- }
- }
- m_directWriteFontFace->ReleaseFontTable(tableContext);
- } else {
- qErrnoWarning("%s: TryGetFontTable failed", __FUNCTION__);
+ const void *tableData = 0;
+ UINT32 tableSize;
+ void *tableContext = 0;
+ BOOL exists;
+ HRESULT hr = m_directWriteFontFace->TryGetFontTable(qbswap<quint32>(tag)
+ &tableData, &tableSize,
+ &tableContext, &exists);
+ if (SUCCEEDED(hr)) {
+ if (exists) {
+ ret = true;
+ if (buffer && *length >= tableSize)
+ memcpy(buffer, tableData, tableSize);
+ else
+ *length = tableSize;
}
+ m_directWriteFontFace->ReleaseFontTable(tableContext);
+ } else {
+ qErrnoWarning("%s: TryGetFontTable failed", __FUNCTION__);
}
return ret;
@@ -327,43 +320,43 @@ inline unsigned int getChar(const QChar *str, int &i, const int len)
bool QWindowsFontEngineDirectWrite::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs,
int *nglyphs, QFontEngine::ShaperFlags flags) const
{
- if (m_directWriteFontFace != 0) {
- QVarLengthArray<UINT32> codePoints(len);
- for (int i=0; i<len; ++i) {
- codePoints[i] = getChar(str, i, len);
- if (flags & QFontEngine::RightToLeft)
- codePoints[i] = QChar::mirroredChar(codePoints[i]);
- }
+ if (*nglyphs < len) {
+ *nglyphs = len;
+ return false;
+ }
- QVarLengthArray<UINT16> glyphIndices(len);
- HRESULT hr = m_directWriteFontFace->GetGlyphIndicesW(codePoints.data(),
- len,
- glyphIndices.data());
+ QVarLengthArray<UINT32> codePoints(len);
+ int actualLength = 0;
+ if (flags & QFontEngine::RightToLeft) {
+ for (int i = 0; i < len; ++i)
+ codePoints[actualLength++] = QChar::mirroredChar(getChar(str, i, len));
+ } else {
+ for (int i = 0; i < len; ++i)
+ codePoints[actualLength++] = getChar(str, i, len);
+ }
- if (SUCCEEDED(hr)) {
- for (int i=0; i<len; ++i)
- glyphs->glyphs[i] = glyphIndices[i];
+ QVarLengthArray<UINT16> glyphIndices(actualLength);
+ HRESULT hr = m_directWriteFontFace->GetGlyphIndicesW(codePoints.data(), actualLength,
+ glyphIndices.data());
+ if (FAILED(hr)) {
+ qErrnoWarning("%s: GetGlyphIndicesW failed", __FUNCTION__);
+ return false;
+ }
- *nglyphs = len;
- glyphs->numGlyphs = len;
+ for (int i = 0; i < actualLength; ++i)
+ glyphs->glyphs[i] = glyphIndices.at(i);
- if (!(flags & GlyphIndicesOnly))
- recalcAdvances(glyphs, 0);
+ *nglyphs = actualLength;
+ glyphs->numGlyphs = actualLength;
- return true;
- } else {
- qErrnoWarning("%s: GetGlyphIndicesW failed", __FUNCTION__);
- }
- }
+ if (!(flags & GlyphIndicesOnly))
+ recalcAdvances(glyphs, 0);
- return false;
+ return true;
}
void QWindowsFontEngineDirectWrite::recalcAdvances(QGlyphLayout *glyphs, QFontEngine::ShaperFlags) const
{
- if (m_directWriteFontFace == 0)
- return;
-
QVarLengthArray<UINT16> glyphIndices(glyphs->numGlyphs);
// ### Caching?
@@ -391,9 +384,6 @@ void QWindowsFontEngineDirectWrite::recalcAdvances(QGlyphLayout *glyphs, QFontEn
void QWindowsFontEngineDirectWrite::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int nglyphs,
QPainterPath *path, QTextItem::RenderFlags flags)
{
- if (m_directWriteFontFace == 0)
- return;
-
QVarLengthArray<UINT16> glyphIndices(nglyphs);
QVarLengthArray<DWRITE_GLYPH_OFFSET> glyphOffsets(nglyphs);
QVarLengthArray<FLOAT> glyphAdvances(nglyphs);
@@ -439,9 +429,6 @@ glyph_metrics_t QWindowsFontEngineDirectWrite::boundingBox(const QGlyphLayout &g
glyph_metrics_t QWindowsFontEngineDirectWrite::boundingBox(glyph_t g)
{
- if (m_directWriteFontFace == 0)
- return glyph_metrics_t();
-
UINT16 glyphIndex = g;
DWRITE_GLYPH_METRICS glyphMetrics;
@@ -668,14 +655,14 @@ bool QWindowsFontEngineDirectWrite::canRender(const QChar *string, int len)
if (FAILED(hr)) {
qErrnoWarning("%s: GetGlyphIndices failed", __FUNCTION__);
return false;
- } else {
- for (int i=0; i<glyphIndices.size(); ++i) {
- if (glyphIndices.at(i) == 0)
- return false;
- }
+ }
- return true;
+ for (int i = 0; i < actualLength; ++i) {
+ if (glyphIndices.at(i) == 0)
+ return false;
}
+
+ return true;
}
QFontEngine::Type QWindowsFontEngineDirectWrite::type() const
diff --git a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h
index 106087f757..ab14cb49eb 100644
--- a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h
+++ b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h
@@ -107,8 +107,6 @@ public:
static QString fontNameSubstitute(const QString &familyName);
private:
- friend class QRawFontPrivate;
-
QImage imageForGlyph(glyph_t t, QFixed subPixelPosition, int margin, const QTransform &xform);
void collectMetrics();
diff --git a/src/plugins/platforms/windows/qwindowsglcontext.cpp b/src/plugins/platforms/windows/qwindowsglcontext.cpp
index f6dda04c13..d1ede39549 100644
--- a/src/plugins/platforms/windows/qwindowsglcontext.cpp
+++ b/src/plugins/platforms/windows/qwindowsglcontext.cpp
@@ -49,6 +49,8 @@
#include <QtGui/QGuiApplication>
#include <qpa/qplatformnativeinterface.h>
+#include <algorithm>
+
#include <wingdi.h>
#include <GL/gl.h>
@@ -377,7 +379,7 @@ static int choosePixelFormat(HDC hdc,
return 0;
int iAttributes[attribSize];
- qFill(iAttributes, iAttributes + attribSize, int(0));
+ std::fill(iAttributes, iAttributes + attribSize, int(0));
int i = 0;
iAttributes[i++] = WGL_ACCELERATION_ARB;
iAttributes[i++] = testFlag(additional.formatFlags, QWindowsGLDirectRendering) ?
@@ -505,8 +507,8 @@ static QSurfaceFormat
return result;
int iAttributes[attribSize];
int iValues[attribSize];
- qFill(iAttributes, iAttributes + attribSize, int(0));
- qFill(iValues, iValues + attribSize, int(0));
+ std::fill(iAttributes, iAttributes + attribSize, int(0));
+ std::fill(iValues, iValues + attribSize, int(0));
int i = 0;
const bool hasSampleBuffers = testFlag(staticContext.extensions, QOpenGLStaticContext::SampleBuffers);
@@ -567,7 +569,7 @@ static HGLRC createContext(const QOpenGLStaticContext &staticContext,
return 0;
int attributes[attribSize];
int attribIndex = 0;
- qFill(attributes, attributes + attribSize, int(0));
+ std::fill(attributes, attributes + attribSize, int(0));
// We limit the requested version by the version of the static context as
// wglCreateContextAttribsARB fails and returns NULL if the requested context
diff --git a/src/plugins/platforms/windows/qwindowstabletsupport.cpp b/src/plugins/platforms/windows/qwindowstabletsupport.cpp
new file mode 100644
index 0000000000..4a5d7b5a78
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowstabletsupport.cpp
@@ -0,0 +1,473 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowstabletsupport.h"
+
+#ifndef QT_NO_TABLETEVENT
+
+#include "qwindowscontext.h"
+#include "qwindowskeymapper.h"
+#include "qwindowswindow.h"
+
+#include <qpa/qwindowsysteminterface.h>
+
+#include <QtGui/QTabletEvent>
+#include <QtGui/QScreen>
+#include <QtGui/QGuiApplication>
+#include <QtGui/QWindow>
+#include <QtCore/QDebug>
+#include <QtCore/QScopedArrayPointer>
+#include <QtCore/QtMath>
+
+#include <private/qguiapplication_p.h>
+#include <QtCore/private/qsystemlibrary_p.h>
+
+// Note: The definition of the PACKET structure in pktdef.h depends on this define.
+#define PACKETDATA (PK_X | PK_Y | PK_BUTTONS | PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE | PK_ORIENTATION | PK_CURSOR | PK_Z)
+#include <pktdef.h>
+
+QT_BEGIN_NAMESPACE
+
+enum {
+ PacketMode = 0,
+ TabletPacketQSize = 128,
+ DeviceIdMask = 0xFF6, // device type mask && device color mask
+ CursorTypeBitMask = 0x0F06 // bitmask to find the specific cursor type (see Wacom FAQ)
+};
+
+extern "C" LRESULT QT_WIN_CALLBACK qWindowsTabletSupportWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ switch (message) {
+ case WT_PROXIMITY:
+ if (QWindowsContext::instance()->tabletSupport()->translateTabletProximityEvent(wParam, lParam))
+ return 0;
+ break;
+ case WT_PACKET:
+ if (QWindowsContext::instance()->tabletSupport()->translateTabletPacketEvent())
+ return 0;
+ break;
+ }
+ return DefWindowProc(hwnd, message, wParam, lParam);
+}
+
+
+// Scale tablet coordinates to screen coordinates.
+
+static inline int sign(int x)
+{
+ return x >= 0 ? 1 : -1;
+}
+
+inline QPointF QWindowsTabletDeviceData::scaleCoordinates(int coordX, int coordY, const QRect &targetArea) const
+{
+ const int targetX = targetArea.x();
+ const int targetY = targetArea.y();
+ const int targetWidth = targetArea.width();
+ const int targetHeight = targetArea.height();
+
+ const qreal x = sign(targetWidth) == sign(maxX) ?
+ ((coordX - minX) * qAbs(targetWidth) / qAbs(qreal(maxX - minX))) + targetX :
+ ((qAbs(maxX) - (coordX - minX)) * qAbs(targetWidth) / qAbs(qreal(maxX - minX))) + targetX;
+
+ const qreal y = sign(targetHeight) == sign(maxY) ?
+ ((coordY - minY) * qAbs(targetHeight) / qAbs(qreal(maxY - minY))) + targetY :
+ ((qAbs(maxY) - (coordY - minY)) * qAbs(targetHeight) / qAbs(qreal(maxY - minY))) + targetY;
+
+ return QPointF(x, y);
+}
+
+QWindowsWinTab32DLL QWindowsTabletSupport::m_winTab32DLL;
+
+/*!
+ \class QWindowsWinTab32DLL QWindowsTabletSupport
+ \brief Functions from wintabl32.dll shipped with WACOM tablets used by QWindowsTabletSupport.
+
+ \internal
+ \ingroup qt-lighthouse-win
+*/
+
+bool QWindowsWinTab32DLL::init()
+{
+ if (wTInfo)
+ return true;
+ QSystemLibrary library(QStringLiteral("wintab32"));
+ if (!library.load())
+ return false;
+ wTOpen = (PtrWTOpen)library.resolve("WTOpenW");
+ wTClose = (PtrWTClose)library.resolve("WTClose");
+ wTInfo = (PtrWTInfo)library.resolve("WTInfoW");
+ wTEnable = (PtrWTEnable)library.resolve("WTEnable");
+ wTOverlap = (PtrWTEnable)library.resolve("WTOverlap");
+ wTPacketsGet = (PtrWTPacketsGet)library.resolve("WTPacketsGet");
+ wTGet = (PtrWTGet)library.resolve("WTGetW");
+ wTQueueSizeGet = (PtrWTQueueSizeGet)library.resolve("WTQueueSizeGet");
+ wTQueueSizeSet = (PtrWTQueueSizeSet)library.resolve("WTQueueSizeSet");
+ return wTOpen && wTClose && wTInfo && wTEnable && wTOverlap && wTPacketsGet && wTQueueSizeGet && wTQueueSizeSet;
+}
+
+/*!
+ \class QWindowsTabletSupport
+ \brief Tablet support for Windows.
+
+ Support for WACOM tablets.
+
+ \sa http://www.wacomeng.com/windows/docs/Wintab_v140.htm
+
+ \internal
+ \since 5.2
+ \ingroup qt-lighthouse-win
+*/
+
+QWindowsTabletSupport::QWindowsTabletSupport(HWND window, HCTX context)
+ : m_window(window)
+ , m_context(context)
+ , m_tiltSupport(false)
+ , m_currentDevice(-1)
+{
+ AXIS orientation[3];
+ // Some tablets don't support tilt, check if it is possible,
+ if (QWindowsTabletSupport::m_winTab32DLL.wTInfo(WTI_DEVICES, DVC_ORIENTATION, &orientation))
+ m_tiltSupport = orientation[0].axResolution && orientation[1].axResolution;
+}
+
+QWindowsTabletSupport::~QWindowsTabletSupport()
+{
+ QWindowsTabletSupport::m_winTab32DLL.wTClose(m_context);
+ DestroyWindow(m_window);
+}
+
+QWindowsTabletSupport *QWindowsTabletSupport::create()
+{
+ if (!m_winTab32DLL.init())
+ return 0;
+ const HWND window = QWindowsContext::instance()->createDummyWindow(QStringLiteral("TabletDummyWindow"),
+ L"TabletDummyWindow",
+ qWindowsTabletSupportWndProc);
+ if (!window) {
+ if (QWindowsContext::verboseTablet)
+ qWarning() << __FUNCTION__ << "Unable to create window for tablet.";
+ return 0;
+ }
+ LOGCONTEXT lcMine;
+ // build our context from the default context
+ QWindowsTabletSupport::m_winTab32DLL.wTInfo(WTI_DEFSYSCTX, 0, &lcMine);
+ // Go for the raw coordinates, the tablet event will return good stuff
+ lcMine.lcOptions |= CXO_MESSAGES | CXO_CSRMESSAGES;
+ lcMine.lcPktData = lcMine.lcMoveMask = PACKETDATA;
+ lcMine.lcPktMode = PacketMode;
+ lcMine.lcOutOrgX = 0;
+ lcMine.lcOutExtX = lcMine.lcInExtX;
+ lcMine.lcOutOrgY = 0;
+ lcMine.lcOutExtY = -lcMine.lcInExtY;
+ const HCTX context = QWindowsTabletSupport::m_winTab32DLL.wTOpen(window, &lcMine, true);
+ if (!context) {
+ if (QWindowsContext::verboseTablet)
+ qWarning() << __FUNCTION__ << "Unable to open tablet.";
+ DestroyWindow(window);
+ return 0;
+
+ }
+ // Set the size of the Packet Queue to the correct size
+ const int currentQueueSize = QWindowsTabletSupport::m_winTab32DLL.wTQueueSizeGet(context);
+ if (currentQueueSize != TabletPacketQSize) {
+ if (!QWindowsTabletSupport::m_winTab32DLL.wTQueueSizeSet(context, TabletPacketQSize)) {
+ if (!QWindowsTabletSupport::m_winTab32DLL.wTQueueSizeSet(context, currentQueueSize)) {
+ qWarning() << "Unable to set queue size on tablet. The tablet will not work.";
+ QWindowsTabletSupport::m_winTab32DLL.wTClose(context);
+ DestroyWindow(window);
+ return 0;
+ } // cannot restore old size
+ } // cannot set
+ } // mismatch
+ if (QWindowsContext::verboseTablet)
+ qDebug("Opened tablet context %p on window %p, changed packet queue size %d -> %d",
+ context, window, currentQueueSize, TabletPacketQSize);
+ return new QWindowsTabletSupport(window, context);
+}
+
+unsigned QWindowsTabletSupport::options() const
+{
+ UINT result = 0;
+ m_winTab32DLL.wTInfo(WTI_INTERFACE, IFC_CTXOPTIONS, &result);
+ return result;
+}
+
+QString QWindowsTabletSupport::description() const
+{
+ const unsigned size = m_winTab32DLL.wTInfo(WTI_INTERFACE, IFC_WINTABID, 0);
+ if (!size)
+ return QString();
+ QScopedPointer<TCHAR> winTabId(new TCHAR[size + 1]);
+ m_winTab32DLL.wTInfo(WTI_INTERFACE, IFC_WINTABID, winTabId.data());
+ WORD implementationVersion = 0;
+ m_winTab32DLL.wTInfo(WTI_INTERFACE, IFC_IMPLVERSION, &implementationVersion);
+ WORD specificationVersion = 0;
+ m_winTab32DLL.wTInfo(WTI_INTERFACE, IFC_SPECVERSION, &specificationVersion);
+ const unsigned opts = options();
+ QString result = QString::fromLatin1("%1 specification: v%2.%3 implementation: v%4.%5 options: 0x%6")
+ .arg(QString::fromWCharArray(winTabId.data()))
+ .arg(specificationVersion >> 8).arg(specificationVersion & 0xFF)
+ .arg(implementationVersion >> 8).arg(implementationVersion & 0xFF)
+ .arg(opts, 0, 16);
+ if (opts & CXO_MESSAGES)
+ result += QStringLiteral(" CXO_MESSAGES");
+ if (opts & CXO_CSRMESSAGES)
+ result += QStringLiteral(" CXO_CSRMESSAGES");
+ if (m_tiltSupport)
+ result += QStringLiteral(" tilt");
+ return result;
+}
+
+void QWindowsTabletSupport::notifyActivate()
+{
+ // Cooperate with other tablet applications, but when we get focus, I want to use the tablet.
+ const bool result = QWindowsTabletSupport::m_winTab32DLL.wTEnable(m_context, true)
+ && QWindowsTabletSupport::m_winTab32DLL.wTOverlap(m_context, true);
+ if (QWindowsContext::verboseTablet)
+ qDebug() << __FUNCTION__ << result;
+}
+
+static inline int indexOfDevice(const QVector<QWindowsTabletDeviceData> &devices, qint64 uniqueId)
+{
+ for (int i = 0; i < devices.size(); ++i)
+ if (devices.at(i).uniqueId == uniqueId)
+ return i;
+ return -1;
+}
+
+static inline QTabletEvent::TabletDevice deviceType(const UINT cursorType)
+{
+ if (((cursorType & 0x0006) == 0x0002) && ((cursorType & CursorTypeBitMask) != 0x0902))
+ return QTabletEvent::Stylus;
+ switch (cursorType & CursorTypeBitMask) {
+ case 0x0802:
+ return QTabletEvent::Stylus;
+ case 0x0902:
+ return QTabletEvent::Airbrush;
+ case 0x0004:
+ return QTabletEvent::FourDMouse;
+ case 0x0006:
+ return QTabletEvent::Puck;
+ case 0x0804:
+ return QTabletEvent::RotationStylus;
+ default:
+ break;
+ }
+ return QTabletEvent::NoDevice;
+}
+
+static inline QTabletEvent::PointerType pointerType(unsigned currentCursor)
+{
+ switch (currentCursor % 3) { // %3 for dual track
+ case 0:
+ return QTabletEvent::Cursor;
+ case 1:
+ return QTabletEvent::Pen;
+ case 2:
+ return QTabletEvent::Eraser;
+ default:
+ break;
+ }
+ return QTabletEvent::UnknownPointer;
+}
+
+QDebug operator<<(QDebug d, const QWindowsTabletDeviceData &t)
+{
+ d << "TabletDevice id:" << t.uniqueId << " pressure: " << t.minPressure
+ << ".." << t.maxPressure << " tan pressure: " << t.minTanPressure << ".."
+ << t.maxTanPressure << " area:" << t.minX << t.minY <<t.minZ
+ << ".." << t.maxX << t.maxY << t.maxZ << " device " << t.currentDevice
+ << " pointer " << t.currentPointerType;
+ return d;
+}
+
+QWindowsTabletDeviceData QWindowsTabletSupport::tabletInit(const quint64 uniqueId, const UINT cursorType) const
+{
+ QWindowsTabletDeviceData result;
+ result.uniqueId = uniqueId;
+ /* browse WinTab's many info items to discover pressure handling. */
+ AXIS axis;
+ LOGCONTEXT lc;
+ /* get the current context for its device variable. */
+ QWindowsTabletSupport::m_winTab32DLL.wTGet(m_context, &lc);
+ /* get the size of the pressure axis. */
+ QWindowsTabletSupport::m_winTab32DLL.wTInfo(WTI_DEVICES + lc.lcDevice, DVC_NPRESSURE, &axis);
+ result.minPressure = int(axis.axMin);
+ result.maxPressure = int(axis.axMax);
+
+ QWindowsTabletSupport::m_winTab32DLL.wTInfo(WTI_DEVICES + lc.lcDevice, DVC_TPRESSURE, &axis);
+ result.minTanPressure = int(axis.axMin);
+ result.maxTanPressure = int(axis.axMax);
+
+ LOGCONTEXT defaultLc;
+ /* get default region */
+ QWindowsTabletSupport::m_winTab32DLL.wTInfo(WTI_DEFCONTEXT, 0, &defaultLc);
+ result.maxX = int(defaultLc.lcInExtX) - int(defaultLc.lcInOrgX);
+ result.maxY = int(defaultLc.lcInExtY) - int(defaultLc.lcInOrgY);
+ result.maxZ = int(defaultLc.lcInExtZ) - int(defaultLc.lcInOrgZ);
+ result.currentDevice = deviceType(cursorType);
+ return result;
+}
+
+bool QWindowsTabletSupport::translateTabletProximityEvent(WPARAM /* wParam */, LPARAM lParam)
+{
+ const bool enteredProximity = LOWORD(lParam) != 0;
+ PACKET proximityBuffer[1]; // we are only interested in the first packet in this case
+ const int totalPacks = QWindowsTabletSupport::m_winTab32DLL.wTPacketsGet(m_context, 1, proximityBuffer);
+ if (!totalPacks)
+ return false;
+ const UINT currentCursor = proximityBuffer[0].pkCursor;
+ UINT physicalCursorId;
+ QWindowsTabletSupport::m_winTab32DLL.wTInfo(WTI_CURSORS + currentCursor, CSR_PHYSID, &physicalCursorId);
+ UINT cursorType;
+ QWindowsTabletSupport::m_winTab32DLL.wTInfo(WTI_CURSORS + currentCursor, CSR_TYPE, &cursorType);
+ const qint64 uniqueId = (qint64(cursorType & DeviceIdMask) << 32L) | qint64(physicalCursorId);
+ // initializing and updating the cursor should be done in response to
+ // WT_CSRCHANGE. We do it in WT_PROXIMITY because some wintab never send
+ // the event WT_CSRCHANGE even if asked with CXO_CSRMESSAGES
+ m_currentDevice = indexOfDevice(m_devices, uniqueId);
+ if (m_currentDevice < 0) {
+ m_currentDevice = m_devices.size();
+ m_devices.push_back(tabletInit(uniqueId, cursorType));
+ }
+ m_devices[m_currentDevice].currentPointerType = pointerType(currentCursor);
+ if (QWindowsContext::verboseTablet)
+ qDebug() << __FUNCTION__ << (enteredProximity ? "enter" : "leave")
+ << " proximity for device #"
+ << m_currentDevice << m_devices.at(m_currentDevice);
+ if (enteredProximity) {
+ QWindowSystemInterface::handleTabletEnterProximityEvent(m_devices.at(m_currentDevice).currentDevice,
+ m_devices.at(m_currentDevice).currentPointerType,
+ m_devices.at(m_currentDevice).uniqueId);
+ } else {
+ QWindowSystemInterface::handleTabletLeaveProximityEvent(m_devices.at(m_currentDevice).currentDevice,
+ m_devices.at(m_currentDevice).currentPointerType,
+ m_devices.at(m_currentDevice).uniqueId);
+ }
+ return true;
+}
+
+bool QWindowsTabletSupport::translateTabletPacketEvent()
+{
+ static PACKET localPacketBuf[TabletPacketQSize]; // our own tablet packet queue.
+ const int packetCount = QWindowsTabletSupport::m_winTab32DLL.wTPacketsGet(m_context, TabletPacketQSize, &localPacketBuf);
+ if (!packetCount || m_currentDevice < 0)
+ return false;
+
+ const int currentDevice = m_devices.at(m_currentDevice).currentDevice;
+ const int currentPointer = m_devices.at(m_currentDevice).currentPointerType;
+
+ // When entering proximity, the tablet driver snaps the mouse pointer to the
+ // tablet position scaled to the virtual desktop and keeps it in sync.
+ const QRect virtualDesktopArea = QGuiApplication::primaryScreen()->virtualGeometry();
+
+ if (QWindowsContext::verboseTablet)
+ qDebug() << __FUNCTION__ << "processing " << packetCount
+ << "target:" << QGuiApplicationPrivate::tabletPressTarget;
+
+ const Qt::KeyboardModifiers keyboardModifiers = QWindowsKeyMapper::queryKeyboardModifiers();
+
+ for (int i = 0; i < packetCount ; ++i) {
+ const PACKET &packet = localPacketBuf[i];
+
+ const int z = currentDevice == QTabletEvent::FourDMouse ? int(packet.pkZ) : 0;
+ const QPointF globalPosF = m_devices.at(m_currentDevice).scaleCoordinates(packet.pkX, packet.pkY, virtualDesktopArea);
+
+ QWindow *target = QGuiApplicationPrivate::tabletPressTarget; // Pass to window that grabbed it.
+ const QPoint globalPos = globalPosF.toPoint();
+ if (!target)
+ if (QPlatformWindow *pw = QWindowsContext::instance()->findPlatformWindowAt(GetDesktopWindow(), globalPos, CWP_SKIPINVISIBLE | CWP_SKIPTRANSPARENT))
+ target = pw->window();
+ if (!target)
+ continue;
+
+ const QPoint localPos = target->mapFromGlobal(globalPos);
+
+ const qreal pressureNew = packet.pkButtons && (currentPointer == QTabletEvent::Pen || currentPointer == QTabletEvent::Eraser) ?
+ m_devices.at(m_currentDevice).scalePressure(packet.pkNormalPressure) :
+ qreal(0);
+ const qreal tangentialPressure = currentDevice == QTabletEvent::Airbrush ?
+ m_devices.at(m_currentDevice).scaleTangentialPressure(packet.pkTangentPressure) :
+ qreal(0);
+
+ int tiltX = 0;
+ int tiltY = 0;
+ qreal rotation = 0;
+ if (m_tiltSupport) {
+ // Convert from azimuth and altitude to x tilt and y tilt. What
+ // follows is the optimized version. Here are the equations used:
+ // X = sin(azimuth) * cos(altitude)
+ // Y = cos(azimuth) * cos(altitude)
+ // Z = sin(altitude)
+ // X Tilt = arctan(X / Z)
+ // Y Tilt = arctan(Y / Z)
+ const double radAzim = (packet.pkOrientation.orAzimuth / 10) * (M_PI / 180);
+ const double tanAlt = tan((abs(packet.pkOrientation.orAltitude / 10)) * (M_PI / 180));
+
+ const double degX = atan(sin(radAzim) / tanAlt);
+ const double degY = atan(cos(radAzim) / tanAlt);
+ tiltX = int(degX * (180 / M_PI));
+ tiltY = int(-degY * (180 / M_PI));
+ rotation = packet.pkOrientation.orTwist;
+ }
+
+ if (QWindowsContext::verboseTablet > 1) {
+ qDebug()
+ << "Packet #" << i << '/' << packetCount << "button:" << packet.pkButtons
+ << globalPosF << z << "to:" << target << localPos << "(packet" << packet.pkX
+ << packet.pkY << ") dev:" << currentDevice << "pointer:"
+ << currentPointer << "P:" << pressureNew << "tilt:" << tiltX << ','
+ << tiltY << "tanP:" << tangentialPressure << "rotation:" << rotation;
+ }
+
+ QWindowSystemInterface::handleTabletEvent(target, packet.pkButtons, localPos, globalPosF,
+ currentDevice, currentPointer,
+ pressureNew, tiltX, tiltY,
+ tangentialPressure, rotation, z,
+ m_devices.at(m_currentDevice).uniqueId,
+ keyboardModifiers);
+ }
+ return true;
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_TABLETEVENT
diff --git a/src/plugins/platforms/windows/qwindowstabletsupport.h b/src/plugins/platforms/windows/qwindowstabletsupport.h
new file mode 100644
index 0000000000..12f96b618d
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowstabletsupport.h
@@ -0,0 +1,142 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSTABLETSUPPORT_H
+#define QWINDOWSTABLETSUPPORT_H
+
+#include "qtwindowsglobal.h"
+
+#if !defined(QT_NO_TABLETEVENT) && !defined(Q_OS_WINCE)
+
+#include <QtCore/QVector>
+#include <QtCore/QPointF>
+
+#include <wintab.h>
+
+QT_BEGIN_NAMESPACE
+
+class QDebug;
+class QWindow;
+class QRect;
+
+struct QWindowsWinTab32DLL
+{
+ QWindowsWinTab32DLL() : wTOpen(0), wTClose(0), wTInfo(0), wTEnable(0), wTOverlap(0), wTPacketsGet(0), wTGet(0),
+ wTQueueSizeGet(0), wTQueueSizeSet(0) {}
+
+ bool init();
+
+ typedef HCTX (API *PtrWTOpen)(HWND, LPLOGCONTEXT, BOOL);
+ typedef BOOL (API *PtrWTClose)(HCTX);
+ typedef UINT (API *PtrWTInfo)(UINT, UINT, LPVOID);
+ typedef BOOL (API *PtrWTEnable)(HCTX, BOOL);
+ typedef BOOL (API *PtrWTOverlap)(HCTX, BOOL);
+ typedef int (API *PtrWTPacketsGet)(HCTX, int, LPVOID);
+ typedef BOOL (API *PtrWTGet)(HCTX, LPLOGCONTEXT);
+ typedef int (API *PtrWTQueueSizeGet)(HCTX);
+ typedef BOOL (API *PtrWTQueueSizeSet)(HCTX, int);
+
+ PtrWTOpen wTOpen;
+ PtrWTClose wTClose;
+ PtrWTInfo wTInfo;
+ PtrWTEnable wTEnable;
+ PtrWTOverlap wTOverlap;
+ PtrWTPacketsGet wTPacketsGet;
+ PtrWTGet wTGet;
+ PtrWTQueueSizeGet wTQueueSizeGet;
+ PtrWTQueueSizeSet wTQueueSizeSet;
+};
+
+struct QWindowsTabletDeviceData
+{
+ QWindowsTabletDeviceData() : minPressure(0), maxPressure(0), minTanPressure(0),
+ maxTanPressure(0), minX(0), maxX(0), minY(0), maxY(0), minZ(0), maxZ(0),
+ uniqueId(0), currentDevice(0), currentPointerType(0) {}
+
+ QPointF scaleCoordinates(int coordX, int coordY,const QRect &targetArea) const;
+ qreal scalePressure(qreal p) const { return p / qreal(maxPressure - minPressure); }
+ qreal scaleTangentialPressure(qreal p) const { return p / qreal(maxTanPressure - minTanPressure); }
+
+ int minPressure;
+ int maxPressure;
+ int minTanPressure;
+ int maxTanPressure;
+ int minX, maxX, minY, maxY, minZ, maxZ;
+ qint64 uniqueId;
+ int currentDevice;
+ int currentPointerType;
+};
+
+QDebug operator<<(QDebug d, const QWindowsTabletDeviceData &t);
+
+class QWindowsTabletSupport
+{
+ Q_DISABLE_COPY(QWindowsTabletSupport)
+
+ explicit QWindowsTabletSupport(HWND window, HCTX context);
+
+public:
+ ~QWindowsTabletSupport();
+
+ static QWindowsTabletSupport *create();
+
+ void notifyActivate();
+ QString description() const;
+
+ bool translateTabletProximityEvent(WPARAM wParam, LPARAM lParam);
+ bool translateTabletPacketEvent();
+
+private:
+ unsigned options() const;
+ QWindowsTabletDeviceData tabletInit(const quint64 uniqueId, const UINT cursorType) const;
+
+ static QWindowsWinTab32DLL m_winTab32DLL;
+ const HWND m_window;
+ const HCTX m_context;
+ bool m_tiltSupport;
+ QVector<QWindowsTabletDeviceData> m_devices;
+ int m_currentDevice;
+};
+
+QT_END_NAMESPACE
+
+#endif // !QT_NO_TABLETEVENT && !Q_OS_WINCE
+#endif // QWINDOWSTABLETSUPPORT_H
diff --git a/src/plugins/platforms/windows/qwindowstheme.cpp b/src/plugins/platforms/windows/qwindowstheme.cpp
index 9f6e6b18e7..49fdfc15b8 100644
--- a/src/plugins/platforms/windows/qwindowstheme.cpp
+++ b/src/plugins/platforms/windows/qwindowstheme.cpp
@@ -54,6 +54,11 @@
#ifdef Q_OS_WINCE
# include "qplatformfunctions_wince.h"
# include "winuser.h"
+#else
+# include <commctrl.h>
+# include <objbase.h>
+# include <commoncontrols.h>
+# include <shellapi.h>
#endif
#include <QtCore/QVariant>
@@ -69,6 +74,12 @@
#include <qpa/qwindowsysteminterface.h>
#include <private/qsystemlibrary_p.h>
+#include <algorithm>
+
+#if defined(__IImageList_INTERFACE_DEFINED__) && defined(__IID_DEFINED__)
+# define USE_IIMAGELIST
+#endif
+
QT_BEGIN_NAMESPACE
static inline QTextStream& operator<<(QTextStream &str, const QColor &c)
@@ -290,8 +301,8 @@ QWindowsTheme *QWindowsTheme::m_instance = 0;
QWindowsTheme::QWindowsTheme()
{
m_instance = this;
- qFill(m_fonts, m_fonts + NFonts, static_cast<QFont *>(0));
- qFill(m_palettes, m_palettes + NPalettes, static_cast<QPalette *>(0));
+ std::fill(m_fonts, m_fonts + NFonts, static_cast<QFont *>(0));
+ std::fill(m_palettes, m_palettes + NPalettes, static_cast<QPalette *>(0));
refresh();
}
@@ -361,8 +372,15 @@ QVariant QWindowsTheme::themeHint(ThemeHint hint) const
case IconPixmapSizes: {
QList<int> sizes;
sizes << 16 << 32;
+#ifdef USE_IIMAGELIST
+ sizes << 48; // sHIL_EXTRALARGE
+ if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA)
+ sizes << 256; // SHIL_JUMBO
+#endif // USE_IIMAGELIST
return QVariant::fromValue(sizes);
}
+ case DialogSnapToDefaultButton:
+ return QVariant(booleanSystemParametersInfo(SPI_GETSNAPTODEFBUTTON, false));
default:
break;
}
@@ -372,7 +390,7 @@ QVariant QWindowsTheme::themeHint(ThemeHint hint) const
void QWindowsTheme::clearPalettes()
{
qDeleteAll(m_palettes, m_palettes + NPalettes);
- qFill(m_palettes, m_palettes + NPalettes, static_cast<QPalette *>(0));
+ std::fill(m_palettes, m_palettes + NPalettes, static_cast<QPalette *>(0));
}
void QWindowsTheme::refreshPalettes()
@@ -393,7 +411,7 @@ void QWindowsTheme::refreshPalettes()
void QWindowsTheme::clearFonts()
{
qDeleteAll(m_fonts, m_fonts + NFonts);
- qFill(m_fonts, m_fonts + NFonts, static_cast<QFont *>(0));
+ std::fill(m_fonts, m_fonts + NFonts, static_cast<QFont *>(0));
}
void QWindowsTheme::refreshFonts()
@@ -410,6 +428,8 @@ void QWindowsTheme::refreshFonts()
const QFont messageBoxFont = QWindowsFontDatabase::LOGFONT_to_QFont(ncm.lfMessageFont);
const QFont statusFont = QWindowsFontDatabase::LOGFONT_to_QFont(ncm.lfStatusFont);
const QFont titleFont = QWindowsFontDatabase::LOGFONT_to_QFont(ncm.lfCaptionFont);
+ QFont fixedFont(QStringLiteral("Courier New"), messageBoxFont.pointSize());
+ fixedFont.setStyleHint(QFont::TypeWriter);
LOGFONT lfIconTitleFont;
SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(lfIconTitleFont), &lfIconTitleFont, 0);
@@ -424,6 +444,7 @@ void QWindowsTheme::refreshFonts()
m_fonts[MdiSubWindowTitleFont] = new QFont(titleFont);
m_fonts[DockWidgetTitleFont] = new QFont(titleFont);
m_fonts[ItemViewFont] = new QFont(iconTitleFont);
+ m_fonts[FixedFont] = new QFont(fixedFont);
if (QWindowsContext::verboseTheming)
qDebug() << __FUNCTION__ << '\n'
@@ -573,11 +594,24 @@ QPixmap QWindowsTheme::standardPixmap(StandardPixmap sp, const QSizeF &size) con
return QPlatformTheme::standardPixmap(sp, size);
}
-static QString dirIconPixmapCacheKey(int iIcon, int iconSize)
+enum { // Shell image list ids
+ sHIL_EXTRALARGE = 0x2, // 48x48 or user-defined
+ sHIL_JUMBO = 0x4 // 256x256 (Vista or later)
+};
+
+static QString dirIconPixmapCacheKey(int iIcon, int iconSize, int imageListSize)
{
QString key = QLatin1String("qt_dir_") + QString::number(iIcon);
if (iconSize == SHGFI_LARGEICON)
key += QLatin1Char('l');
+ switch (imageListSize) {
+ case sHIL_EXTRALARGE:
+ key += QLatin1Char('e');
+ break;
+ case sHIL_JUMBO:
+ key += QLatin1Char('j');
+ break;
+ }
return key;
}
@@ -601,7 +635,40 @@ public:
void operator delete (void *) {}
};
-QPixmap QWindowsTheme::fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &size) const
+// Shell image list helper functions.
+
+static QPixmap pixmapFromShellImageList(int iImageList, const SHFILEINFO &info)
+{
+ QPixmap result;
+#ifdef USE_IIMAGELIST
+ // For MinGW:
+ static const IID iID_IImageList = {0x46eb5926, 0x582e, 0x4017, {0x9f, 0xdf, 0xe8, 0x99, 0x8d, 0xaa, 0x9, 0x50}};
+
+ if (!QWindowsContext::shell32dll.sHGetImageList)
+ return result;
+ if (iImageList == sHIL_JUMBO && QSysInfo::WindowsVersion < QSysInfo::WV_VISTA)
+ return result;
+
+ IImageList *imageList = 0;
+ HRESULT hr = QWindowsContext::shell32dll.sHGetImageList(iImageList, iID_IImageList, (void **)&imageList);
+ if (hr != S_OK)
+ return result;
+ HICON hIcon;
+ hr = imageList->GetIcon(info.iIcon, ILD_TRANSPARENT, &hIcon);
+ if (hr == S_OK) {
+ result = qt_pixmapFromWinHICON(hIcon);
+ DestroyIcon(hIcon);
+ }
+ imageList->Release();
+#else
+ Q_UNUSED(iImageList)
+ Q_UNUSED(info)
+#endif // USE_IIMAGELIST
+ return result;
+}
+
+QPixmap QWindowsTheme::fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &size,
+ QPlatformTheme::IconOptions iconOptions) const
{
/* We don't use the variable, but by storing it statically, we
* ensure CoInitialize is only called once. */
@@ -610,17 +677,26 @@ QPixmap QWindowsTheme::fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &s
static QCache<QString, FakePointer<int> > dirIconEntryCache(1000);
static QMutex mx;
+ static int defaultFolderIIcon = 0;
+ const bool useDefaultFolderIcon = iconOptions & QPlatformTheme::DontUseCustomDirectoryIcons;
QPixmap pixmap;
const QString filePath = QDir::toNativeSeparators(fileInfo.filePath());
- int iconSize = size.width() > 16 ? SHGFI_LARGEICON : SHGFI_SMALLICON;
-
+ const int width = size.width();
+ const int iconSize = width > 16 ? SHGFI_LARGEICON : SHGFI_SMALLICON;
+ const int requestedImageListSize =
+#ifdef USE_IIMAGELIST
+ width > 48 ? sHIL_JUMBO : (width > 32 ? sHIL_EXTRALARGE : 0);
+#else
+ 0;
+#endif // !USE_IIMAGELIST
bool cacheableDirIcon = fileInfo.isDir() && !fileInfo.isRoot();
if (cacheableDirIcon) {
QMutexLocker locker(&mx);
- int iIcon = **dirIconEntryCache.object(filePath);
+ int iIcon = (useDefaultFolderIcon && defaultFolderIIcon) ? defaultFolderIIcon
+ : **dirIconEntryCache.object(filePath);
if (iIcon) {
- QPixmapCache::find(dirIconPixmapCacheKey(iIcon, iconSize), pixmap);
+ QPixmapCache::find(dirIconPixmapCacheKey(iIcon, iconSize, requestedImageListSize), pixmap);
if (pixmap.isNull()) // Let's keep both caches in sync
dirIconEntryCache.remove(filePath);
else
@@ -635,15 +711,26 @@ QPixmap QWindowsTheme::fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &s
#else
iconSize|SHGFI_SYSICONINDEX;
#endif // Q_OS_WINCE
- unsigned long val = SHGetFileInfo((const wchar_t *)filePath.utf16(), 0,
- &info, sizeof(SHFILEINFO), flags);
+ unsigned long val = 0;
+ if (cacheableDirIcon && useDefaultFolderIcon) {
+ flags |= SHGFI_USEFILEATTRIBUTES;
+ val = SHGetFileInfo(L"dummy",
+ FILE_ATTRIBUTE_DIRECTORY,
+ &info, sizeof(SHFILEINFO), flags);
+ } else {
+ val = SHGetFileInfo(reinterpret_cast<const wchar_t *>(filePath.utf16()), 0,
+ &info, sizeof(SHFILEINFO), flags);
+ }
// Even if GetFileInfo returns a valid result, hIcon can be empty in some cases
if (val && info.hIcon) {
QString key;
if (cacheableDirIcon) {
+ if (useDefaultFolderIcon && !defaultFolderIIcon)
+ defaultFolderIIcon = info.iIcon;
+
//using the unique icon index provided by windows save us from duplicate keys
- key = dirIconPixmapCacheKey(info.iIcon, iconSize);
+ key = dirIconPixmapCacheKey(info.iIcon, iconSize, requestedImageListSize);
QPixmapCache::find(key, pixmap);
if (!pixmap.isNull()) {
QMutexLocker locker(&mx);
@@ -652,7 +739,13 @@ QPixmap QWindowsTheme::fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &s
}
if (pixmap.isNull()) {
- pixmap = qt_pixmapFromWinHICON(info.hIcon);
+ if (requestedImageListSize) {
+ pixmap = pixmapFromShellImageList(requestedImageListSize, info);
+ if (pixmap.isNull() && requestedImageListSize == sHIL_JUMBO)
+ pixmap = pixmapFromShellImageList(sHIL_EXTRALARGE, info);
+ }
+ if (pixmap.isNull())
+ pixmap = qt_pixmapFromWinHICON(info.hIcon);
if (!pixmap.isNull()) {
if (cacheableDirIcon) {
QMutexLocker locker(&mx);
diff --git a/src/plugins/platforms/windows/qwindowstheme.h b/src/plugins/platforms/windows/qwindowstheme.h
index bbd7f4623f..9346621d59 100644
--- a/src/plugins/platforms/windows/qwindowstheme.h
+++ b/src/plugins/platforms/windows/qwindowstheme.h
@@ -68,7 +68,8 @@ public:
{ return m_fonts[type]; }
virtual QPixmap standardPixmap(StandardPixmap sp, const QSizeF &size) const;
- virtual QPixmap fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &size) const;
+ virtual QPixmap fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &size,
+ QPlatformTheme::IconOptions iconOptions = 0) const;
void windowsThemeChanged(QWindow *window);
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp
index ace18ddf5b..f3faccbc14 100644
--- a/src/plugins/platforms/windows/qwindowswindow.cpp
+++ b/src/plugins/platforms/windows/qwindowswindow.cpp
@@ -56,6 +56,7 @@
#include <QtGui/QScreen>
#include <QtGui/QWindow>
#include <QtGui/QRegion>
+#include <private/qsystemlibrary_p.h>
#include <private/qwindow_p.h>
#include <private/qguiapplication_p.h>
#include <qpa/qwindowsysteminterface.h>
@@ -203,6 +204,69 @@ static inline QSize clientSize(HWND hwnd)
return qSizeOfRect(rect);
}
+static bool applyBlurBehindWindow(HWND hwnd)
+{
+#ifdef Q_OS_WINCE
+ Q_UNUSED(hwnd);
+ return false;
+#else
+ enum { dwmBbEnable = 0x1, dwmBbBlurRegion = 0x2 };
+
+ struct DwmBlurBehind {
+ DWORD dwFlags;
+ BOOL fEnable;
+ HRGN hRgnBlur;
+ BOOL fTransitionOnMaximized;
+ };
+
+ typedef HRESULT (WINAPI *PtrDwmEnableBlurBehindWindow)(HWND, const DwmBlurBehind*);
+ typedef HRESULT (WINAPI *PtrDwmIsCompositionEnabled)(BOOL *);
+
+ // DWM API is available only from Windows Vista
+ if (QSysInfo::windowsVersion() < QSysInfo::WV_VISTA)
+ return false;
+
+ static bool functionPointersResolved = false;
+ static PtrDwmEnableBlurBehindWindow dwmBlurBehind = 0;
+ static PtrDwmIsCompositionEnabled dwmIsCompositionEnabled = 0;
+
+ if (Q_UNLIKELY(!functionPointersResolved)) {
+ QSystemLibrary library(QStringLiteral("dwmapi"));
+ if (library.load()) {
+ dwmBlurBehind = (PtrDwmEnableBlurBehindWindow)(library.resolve("DwmEnableBlurBehindWindow"));
+ dwmIsCompositionEnabled = (PtrDwmIsCompositionEnabled)(library.resolve("DwmIsCompositionEnabled"));
+ }
+
+ functionPointersResolved = true;
+ }
+
+ if (Q_UNLIKELY(!dwmBlurBehind || !dwmIsCompositionEnabled))
+ return false;
+
+ BOOL compositionEnabled;
+ if (dwmIsCompositionEnabled(&compositionEnabled) != S_OK)
+ return false;
+
+ DwmBlurBehind blurBehind = {0, 0, 0, 0};
+
+ if (compositionEnabled) {
+ blurBehind.dwFlags = dwmBbEnable | dwmBbBlurRegion;
+ blurBehind.fEnable = TRUE;
+ blurBehind.hRgnBlur = CreateRectRgn(0, 0, -1, -1);
+ } else {
+ blurBehind.dwFlags = dwmBbEnable;
+ blurBehind.fEnable = FALSE;
+ }
+
+ const bool result = dwmBlurBehind(hwnd, &blurBehind) == S_OK;
+
+ if (blurBehind.hRgnBlur)
+ DeleteObject(blurBehind.hRgnBlur);
+
+ return result;
+#endif // Q_OS_WINCE
+}
+
// from qwidget_win.cpp, pass flags separately in case they have been "autofixed".
static bool shouldShowMaximizeButton(const QWindow *w, Qt::WindowFlags flags)
{
@@ -543,6 +607,10 @@ QWindowsWindow::WindowData
result.frame = context->margins;
result.embedded = embedded;
result.customMargins = context->customMargins;
+
+ if (isGL && hasAlpha)
+ applyBlurBehindWindow(result.hwnd);
+
return result;
}
@@ -1167,6 +1235,13 @@ void QWindowsWindow::handleHidden()
fireExpose(QRegion());
}
+void QWindowsWindow::handleCompositionSettingsChanged()
+{
+ const QWindow *w = window();
+ if (w->surfaceType() == QWindow::OpenGLSurface && w->format().hasAlpha())
+ applyBlurBehindWindow(handle());
+}
+
void QWindowsWindow::setGeometry(const QRect &rectIn)
{
QRect rect = rectIn;
diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h
index afcfa8b821..f055864482 100644
--- a/src/plugins/platforms/windows/qwindowswindow.h
+++ b/src/plugins/platforms/windows/qwindowswindow.h
@@ -221,6 +221,7 @@ public:
void handleMoved();
void handleResized(int wParam);
void handleHidden();
+ void handleCompositionSettingsChanged();
static inline HWND handleOf(const QWindow *w);
static inline QWindowsWindow *baseWindowOf(const QWindow *w);
diff --git a/src/plugins/platforms/windows/windows.pro b/src/plugins/platforms/windows/windows.pro
index 3aa9caaa0f..d4e6e558ed 100644
--- a/src/plugins/platforms/windows/windows.pro
+++ b/src/plugins/platforms/windows/windows.pro
@@ -102,6 +102,12 @@ contains(QT_CONFIG, opengles2) {
}
}
+!wince*:!contains( DEFINES, QT_NO_TABLETEVENT ) {
+ INCLUDEPATH += ../../../3rdparty/wintab
+ HEADERS += qwindowstabletsupport.h
+ SOURCES += qwindowstabletsupport.cpp
+}
+
contains(QT_CONFIG, freetype) {
DEFINES *= QT_NO_FONTCONFIG
QT_FREETYPE_DIR = $$QT_SOURCE_TREE/src/3rdparty/freetype