Windows: Adapt to new Lighthouse API

- Implement debug/deprecated options of QSurfaceFormat
- Implement stylehints
- Fixed input context to position the input window correctly.

Change-Id: Icba22f183c6895e30bd34d60cf6d2307ed3188cd
Reviewed-on: http://codereview.qt-project.org/6446
Sanity-Review: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@nokia.com>
This commit is contained in:
Friedemann Kleint 2011-10-11 16:33:42 +02:00 committed by Qt by Nokia
parent e941b37fcc
commit 32ec981745
6 changed files with 100 additions and 52 deletions

View File

@ -511,9 +511,10 @@ static QSurfaceFormat
iAttributes[i++] = WGL_STEREO_ARB; // 9
iAttributes[i++] = WGL_ACCELERATION_ARB; // 10
iAttributes[i++] = WGL_NUMBER_OVERLAYS_ARB; // 11
iAttributes[i++] = WGL_CONTEXT_FLAGS_ARB; // 12
if (hasSampleBuffers) {
iAttributes[i++] = WGL_SAMPLE_BUFFERS_ARB; // 12
iAttributes[i++] = WGL_SAMPLES_ARB; // 13
iAttributes[i++] = WGL_SAMPLE_BUFFERS_ARB; // 13
iAttributes[i++] = WGL_SAMPLES_ARB; // 14
}
if (!staticContext.wglGetPixelFormatAttribIVARB(hdc, pixelFormat, 0, i,
iAttributes, iValues))
@ -526,9 +527,14 @@ static QSurfaceFormat
result.setBlueBufferSize(iValues[5]);
result.setAlphaBufferSize(iValues[6]);
result.setStencilBufferSize(iValues[8]);
result.setStereo(iValues[9]);
if (iValues[9])
result.setOption(QSurfaceFormat::StereoBuffers);
if (iValues[12] & WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB)
result.setOption(QSurfaceFormat::DeprecatedFunctions);
if (iValues[12] & WGL_CONTEXT_DEBUG_BIT_ARB)
result.setOption(QSurfaceFormat::DebugContext);
if (hasSampleBuffers)
result.setSamples(iValues[13]);
result.setSamples(iValues[14]);
if (additionalIn) {
if (iValues[7])
additionalIn->formatFlags |= QWindowsGLAccumBuffer;
@ -543,7 +549,7 @@ static QSurfaceFormat
static HGLRC createContext(const QOpenGLStaticContext &staticContext,
HDC hdc,
const QSurfaceFormat &format,
const QWindowsOpenGLAdditionalFormat &additional,
const QWindowsOpenGLAdditionalFormat &,
int majorVersion = 0,
int minorVersion = 0,
HGLRC shared = 0)
@ -562,9 +568,14 @@ static HGLRC createContext(const QOpenGLStaticContext &staticContext,
attributes[attribIndex++] = WGL_CONTEXT_MINOR_VERSION_ARB;
attributes[attribIndex++] = minorVersion;
}
if (majorVersion >= 3 && additional.formatFlags & QWindowsGLDeprecatedFunctions) {
if (majorVersion >= 3) {
attributes[attribIndex++] = WGL_CONTEXT_FLAGS_ARB;
attributes[attribIndex++] = WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
attributes[attribIndex] = 0;
if (format.testOption(QSurfaceFormat::DeprecatedFunctions))
attributes[attribIndex] |= WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
if (format.testOption(QSurfaceFormat::DebugContext))
attributes[attribIndex++] |= WGL_CONTEXT_DEBUG_BIT_ARB;
attribIndex++;
}
if ((staticContext.majorVersion == 3 && staticContext.minorVersion >= 2)
|| staticContext.majorVersion > 3) {
@ -806,7 +817,7 @@ QWindowsGLContext::QWindowsGLContext(const QOpenGLStaticContextPtr &staticContex
describeFormats(hdc);
// Preferably use direct rendering and ARB extensions (unless pixmap)
const QWindowsOpenGLAdditionalFormat
requestedAdditional(QWindowsGLDirectRendering|QWindowsGLDeprecatedFunctions);
requestedAdditional(QWindowsGLDirectRendering);
const bool tryExtensions = m_staticContext->hasExtensions()
&& !testFlag(requestedAdditional.formatFlags, QWindowsGLRenderToPixmap);
QWindowsOpenGLAdditionalFormat obtainedAdditional;

View File

@ -58,8 +58,7 @@ enum QWindowsGLFormatFlags
QWindowsGLDirectRendering = 0x1,
QWindowsGLOverlay = 0x2,
QWindowsGLRenderToPixmap = 0x4,
QWindowsGLAccumBuffer = 0x8,
QWindowsGLDeprecatedFunctions = 0x10
QWindowsGLAccumBuffer = 0x8
};
// Additional format information for Windows.

View File

@ -48,6 +48,7 @@
#include <QtCore/QDebug>
#include <QtCore/QObject>
#include <QtCore/QRect>
#include <QtCore/QRectF>
#include <QtCore/QTextBoundaryFinder>
#include <QtGui/QInputMethodEvent>
@ -155,6 +156,8 @@ template <class T>
\ingroup qt-lighthouse-win
*/
QWindowsInputContext::CompositionContext::CompositionContext() :
hwnd(0), haveCaret(false), position(0), isComposing(false)
{
@ -164,6 +167,8 @@ QWindowsInputContext::QWindowsInputContext() :
m_WM_MSIME_MOUSE(RegisterWindowMessage(L"MSIMEMouseOperation")),
m_endCompositionRecursionGuard(false)
{
connect(qApp->inputPanel(), SIGNAL(cursorRectangleChanged()),
this, SLOT(cursorRectChanged()));
}
QWindowsInputContext::~QWindowsInputContext()
@ -202,66 +207,65 @@ void QWindowsInputContext::reset()
void QWindowsInputContext::update(Qt::InputMethodQueries queries)
{
QPlatformInputContext::update(queries);
}
void QWindowsInputContext::cursorRectChanged()
{
if (!m_compositionContext.hwnd)
return;
QObject *fo = qApp->inputPanel()->inputItem();
if (!fo)
const QInputPanel *inputPanel = qApp->inputPanel();
QRect cursorRectangle = inputPanel->cursorRectangle().toRect();
if (!cursorRectangle.isValid())
return;
if (QWindowsContext::verboseInputMethods)
qDebug() << __FUNCTION__<< cursorRectangle;
const HIMC himc = ImmGetContext(m_compositionContext.hwnd);
if (!himc)
return;
// Move candidate list window to the microfocus position.
QRect globalMicroFocusRect;
if (!inputMethodQuery(fo, Qt::ImCursorRectangle, &globalMicroFocusRect) || !globalMicroFocusRect.isValid())
return;
if (QWindowsContext::verboseInputMethods)
qDebug() << __FUNCTION__ << himc << globalMicroFocusRect;
COMPOSITIONFORM cf;
// ### need X-like inputStyle config settings
cf.dwStyle = CFS_FORCE_POSITION;
cf.ptCurrentPos.x = cursorRectangle.x();
cf.ptCurrentPos.y = cursorRectangle.y();
if (globalMicroFocusRect.isValid()) {
const QRect microFocusRect(QWindowsGeometryHint::mapFromGlobal(m_compositionContext.hwnd,
globalMicroFocusRect.topLeft()),
globalMicroFocusRect.size());
COMPOSITIONFORM cf;
// ### need X-like inputStyle config settings
cf.dwStyle = CFS_FORCE_POSITION;
cf.ptCurrentPos.x = microFocusRect.x();
cf.ptCurrentPos.y = microFocusRect.y();
CANDIDATEFORM candf;
candf.dwIndex = 0;
candf.dwStyle = CFS_EXCLUDE;
candf.ptCurrentPos.x = cursorRectangle.x();
candf.ptCurrentPos.y = cursorRectangle.y() + cursorRectangle.height();
candf.rcArea.left = cursorRectangle.x();
candf.rcArea.top = cursorRectangle.y();
candf.rcArea.right = cursorRectangle.x() + cursorRectangle.width();
candf.rcArea.bottom = cursorRectangle.y() + cursorRectangle.height();
CANDIDATEFORM candf;
candf.dwIndex = 0;
candf.dwStyle = CFS_EXCLUDE;
candf.ptCurrentPos.x = microFocusRect.x();
candf.ptCurrentPos.y = microFocusRect.y() + microFocusRect.height();
candf.rcArea.left = microFocusRect.x();
candf.rcArea.top = microFocusRect.y();
candf.rcArea.right = microFocusRect.x() + microFocusRect.width();
candf.rcArea.bottom = microFocusRect.y() + microFocusRect.height();
if (m_compositionContext.haveCaret)
SetCaretPos(cursorRectangle.x(), cursorRectangle.y());
if (m_compositionContext.haveCaret)
SetCaretPos(microFocusRect.x(), microFocusRect.y());
ImmSetCompositionWindow(himc, &cf);
ImmSetCandidateWindow(himc, &candf);
}
ImmSetCompositionWindow(himc, &cf);
ImmSetCandidateWindow(himc, &candf);
ImmReleaseContext(m_compositionContext.hwnd, himc);
}
void QWindowsInputContext::mouseHandler(int pos, QMouseEvent *event)
void QWindowsInputContext::invokeAction(QInputPanel::Action action, int cursorPosition)
{
if (event->type() != QEvent::MouseButtonPress || !m_compositionContext.hwnd)
if (action != QInputPanel::Click || !m_compositionContext.hwnd) {
QPlatformInputContext::invokeAction(action, cursorPosition);
return;
if (QWindowsContext::verboseInputMethods)
qDebug() << __FUNCTION__ << pos << event;
}
if (pos < 0 || pos > m_compositionContext.composition.size())
if (QWindowsContext::verboseInputMethods)
qDebug() << __FUNCTION__ << cursorPosition << action;
if (cursorPosition < 0 || cursorPosition > m_compositionContext.composition.size())
reset();
// Magic code that notifies Japanese IME about the cursor
// position.
const DWORD button = QWindowsMouseHandler::mouseButtonsToKeyState(event->buttons());
const HIMC himc = ImmGetContext(m_compositionContext.hwnd);
const HWND imeWindow = ImmGetDefaultIMEWnd(m_compositionContext.hwnd);
SendMessage(imeWindow, m_WM_MSIME_MOUSE, MAKELONG(MAKEWORD(button, pos == 0 ? 2 : 1), pos), (LPARAM)himc);
SendMessage(imeWindow, m_WM_MSIME_MOUSE, MAKELONG(MAKEWORD(MK_LBUTTON, cursorPosition == 0 ? 2 : 1), cursorPosition), (LPARAM)himc);
ImmReleaseContext(m_compositionContext.hwnd, himc);
}

View File

@ -52,6 +52,8 @@ class QInputMethodEvent;
class QWindowsInputContext : public QPlatformInputContext
{
Q_OBJECT
struct CompositionContext
{
CompositionContext();
@ -68,8 +70,7 @@ public:
virtual void reset();
virtual void update(Qt::InputMethodQueries);
virtual void mouseHandler(int x, QMouseEvent *event);
virtual void invokeAction(QInputPanel::Action, int cursorPosition);
static QWindowsInputContext *instance();
@ -81,6 +82,9 @@ public:
bool handleIME_Request(WPARAM wparam, LPARAM lparam, LRESULT *result);
private slots:
void cursorRectChanged();
private:
void initContext(HWND hwnd);
void doneContext();

View File

@ -83,6 +83,7 @@ QT_BEGIN_NAMESPACE
class QWindowsNativeInterface : public QPlatformNativeInterface
{
public:
virtual void *nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context);
virtual void *nativeResourceForWindow(const QByteArray &resource, QWindow *window);
virtual void *nativeResourceForBackingStore(const QByteArray &resource, QBackingStore *bs);
};
@ -121,6 +122,20 @@ void *QWindowsNativeInterface::nativeResourceForBackingStore(const QByteArray &r
return 0;
}
void *QWindowsNativeInterface::nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context)
{
if (!context || !context->handle()) {
qWarning("%s: '%s' requested for null context or context without handle.", __FUNCTION__, resource.constData());
return 0;
}
QWindowsGLContext *windowsContext = static_cast<QWindowsGLContext *>(context->handle());
if (resource == "renderingContext")
return windowsContext->renderingContext();
qWarning("%s: Invalid key '%s' requested.", __FUNCTION__, resource.constData());
return 0;
}
/*!
\class QWindowsIntegration
\brief QPlatformIntegration implementation for Windows.
@ -257,7 +272,23 @@ QPlatformFontDatabase *QWindowsIntegration::fontDatabase() const
#endif
}
return d->m_fontDatabase;
}
QVariant QWindowsIntegration::styleHint(QPlatformIntegration::StyleHint hint) const
{
switch (hint) {
case QPlatformIntegration::CursorFlashTime:
if (const unsigned timeMS = GetCaretBlinkTime())
return QVariant(int(timeMS));
break;
case QPlatformIntegration::StartDragTime:
case QPlatformIntegration::StartDragDistance:
case QPlatformIntegration::MouseDoubleClickInterval:
case QPlatformIntegration::KeyboardInputInterval:
break; // Not implemented
}
return QPlatformIntegration::styleHint(hint);
}
QPlatformNativeInterface *QWindowsIntegration::nativeInterface() const
@ -272,8 +303,6 @@ QPlatformClipboard * QWindowsIntegration::clipboard() const
QPlatformDrag *QWindowsIntegration::drag() const
{
if (QWindowsContext::verboseIntegration)
qDebug("%s", __FUNCTION__ );
return &d->m_drag;
}

View File

@ -69,6 +69,7 @@ public:
virtual QPlatformAccessibility *accessibility() const;
virtual QPlatformNativeInterface *nativeInterface() const;
virtual QPlatformFontDatabase *fontDatabase() const;
virtual QVariant styleHint(StyleHint hint) const;
static QWindowsIntegration *instance();