diff options
author | Richard Dale <richard.dale@codethink.co.uk> | 2013-07-04 09:57:10 +0100 |
---|---|---|
committer | Richard Dale <richard.dale@codethink.co.uk> | 2013-07-04 09:57:10 +0100 |
commit | 722e2df3638e98dca4915602b9cad59cf5fea2d5 (patch) | |
tree | 8f011519e7cea09c004fe2ce13c6941557773527 | |
parent | ecbcecf148897512e682452f0c152bb6b0c8ebaa (diff) | |
parent | 0368bb7e2682d0b187d31bb91618632965351e4d (diff) | |
download | qtwebkit-722e2df3638e98dca4915602b9cad59cf5fea2d5.tar.gz |
Merge v5.1.0 release
32 files changed, 675 insertions, 906 deletions
diff --git a/Source/WebCore/WebCore.pri b/Source/WebCore/WebCore.pri index b7cd93adf..cb9452356 100644 --- a/Source/WebCore/WebCore.pri +++ b/Source/WebCore/WebCore.pri @@ -177,41 +177,7 @@ use?(GSTREAMER) { } enable?(VIDEO) { - use?(QTKIT) { - INCLUDEPATH += $$SOURCE_DIR/platform/graphics/mac - - LIBS += -framework AppKit -framework AudioUnit \ - -framework AudioToolbox -framework CoreAudio \ - -framework QuartzCore -framework QTKit \ - -framework Security -framework IOKit - - DARWIN_VERSION = $$split(QMAKE_HOST.version, ".") - DARWIN_MAJOR_VERSION = $$first(DARWIN_VERSION) - - haveQt(5,1) { - equals(QMAKE_MAC_SDK_VERSION, 10.7): \ - SYSTEM_LIBRARY_PATH = $${ROOT_WEBKIT_DIR}/WebKitLibraries/libWebKitSystemInterfaceLion.a - else:equals(QMAKE_MAC_SDK_VERSION, 10.8): \ - SYSTEM_LIBRARY_PATH = $${ROOT_WEBKIT_DIR}/WebKitLibraries/libWebKitSystemInterfaceMountainLion.a - } else { - # We first check if a specific SDK is set to be used for the build. - contains(QMAKE_MAC_SDK, ".*MacOSX10.7.sdk.*") { - SYSTEM_LIBRARY_PATH = $${ROOT_WEBKIT_DIR}/WebKitLibraries/libWebKitSystemInterfaceLion.a - } else:contains(QMAKE_MAC_SDK, ".*MacOSX10.8.sdk.*") { - SYSTEM_LIBRARY_PATH = $${ROOT_WEBKIT_DIR}/WebKitLibraries/libWebKitSystemInterfaceMountainLion.a - } - - # If the previous check did not yield a result, we resort to the Darwin version. - isEmpty(SYSTEM_LIBRARY_PATH) { - equals(DARWIN_MAJOR_VERSION, "11") { - SYSTEM_LIBRARY_PATH = $${ROOT_WEBKIT_DIR}/WebKitLibraries/libWebKitSystemInterfaceLion.a - } else:equals(DARWIN_MAJOR_VERSION, "12") { - SYSTEM_LIBRARY_PATH = $${ROOT_WEBKIT_DIR}/WebKitLibraries/libWebKitSystemInterfaceMountainLion.a - } - } - } - LIBS += $$SYSTEM_LIBRARY_PATH - } else:use?(GSTREAMER) { + use?(GSTREAMER) { INCLUDEPATH += $$SOURCE_DIR/platform/graphics/gstreamer } else:use?(QT_MULTIMEDIA) { QT *= multimedia diff --git a/Source/WebCore/bridge/qt/qt_pixmapruntime.cpp b/Source/WebCore/bridge/qt/qt_pixmapruntime.cpp index f50465979..1ddf4fdf3 100644 --- a/Source/WebCore/bridge/qt/qt_pixmapruntime.cpp +++ b/Source/WebCore/bridge/qt/qt_pixmapruntime.cpp @@ -249,14 +249,16 @@ JSClassRef QtPixmapRuntime::getClassRef() { static const JSStaticValue staticValues[] = { { "width", getPixmapWidth, 0, 0 }, - { "height", getPixmapHeight, 0, 0 } + { "height", getPixmapHeight, 0, 0 }, + { 0, 0, 0, 0} }; static const JSStaticFunction staticFunctions[] = { { "assignToHTMLImageElement", assignToHTMLImageElement, 0 }, { "toDataUrl", pixmapToDataUrl, 0 }, { "toImageData", pixmapToImageData, 0 }, - { "toString", pixmapToString, 0 } + { "toString", pixmapToString, 0 }, + { 0, 0, 0 } }; static const JSClassDefinition classDefinition = { diff --git a/Source/WebCore/loader/appcache/ApplicationCacheHost.cpp b/Source/WebCore/loader/appcache/ApplicationCacheHost.cpp index fe9f010a0..c4e743065 100644 --- a/Source/WebCore/loader/appcache/ApplicationCacheHost.cpp +++ b/Source/WebCore/loader/appcache/ApplicationCacheHost.cpp @@ -473,7 +473,7 @@ void ApplicationCacheHost::abort() bool ApplicationCacheHost::isApplicationCacheEnabled() { - return m_documentLoader->frame()->settings() + return m_documentLoader->frame() && m_documentLoader->frame()->settings() && m_documentLoader->frame()->settings()->offlineWebApplicationCacheEnabled(); } diff --git a/Source/WebCore/platform/FileSystem.h b/Source/WebCore/platform/FileSystem.h index 943cc7b60..642d07edf 100644 --- a/Source/WebCore/platform/FileSystem.h +++ b/Source/WebCore/platform/FileSystem.h @@ -53,7 +53,7 @@ #include <wx/file.h> #endif -#if USE(CF) || (PLATFORM(QT) && defined(Q_WS_MAC)) +#if USE(CF) || (PLATFORM(QT) && defined(Q_OS_MACX)) typedef struct __CFBundle* CFBundleRef; typedef const struct __CFData* CFDataRef; #endif @@ -85,7 +85,7 @@ typedef GModule* PlatformModule; #elif PLATFORM(EFL) typedef Eina_Module* PlatformModule; #elif PLATFORM(QT) -#if defined(Q_WS_MAC) +#if defined(Q_OS_MACX) typedef CFBundleRef PlatformModule; #elif !defined(QT_NO_LIBRARY) typedef QLibrary* PlatformModule; diff --git a/Source/WebCore/platform/graphics/Color.cpp b/Source/WebCore/platform/graphics/Color.cpp index 04dc73ea6..51c710007 100644 --- a/Source/WebCore/platform/graphics/Color.cpp +++ b/Source/WebCore/platform/graphics/Color.cpp @@ -434,9 +434,9 @@ RGBA32 premultipliedARGBFromColor(const Color& color) unsigned alpha = color.alpha(); if (alpha < 255) { pixelColor = Color::createUnchecked( - (color.red() * alpha + 254) / 255, - (color.green() * alpha + 254) / 255, - (color.blue() * alpha + 254) / 255, + fastDivideBy255(color.red() * alpha + 254), + fastDivideBy255(color.green() * alpha + 254), + fastDivideBy255(color.blue() * alpha + 254), alpha).rgb(); } else pixelColor = color.rgb(); diff --git a/Source/WebCore/platform/graphics/Color.h b/Source/WebCore/platform/graphics/Color.h index 87ca23375..9e4ce8c11 100644 --- a/Source/WebCore/platform/graphics/Color.h +++ b/Source/WebCore/platform/graphics/Color.h @@ -211,6 +211,14 @@ inline Color blend(const Color& from, const Color& to, double progress, bool ble blend(from.alpha(), to.alpha(), progress)); } +inline uint16_t fastDivideBy255(uint16_t value) +{ + // This is an approximate algorithm for division by 255, but it gives accurate results for 16bit values. + uint16_t approximation = value >> 8; + uint16_t remainder = value - (approximation * 255) + 1; + return approximation + (remainder >> 8); +} + #if USE(CG) CGColorRef cachedCGColor(const Color&, ColorSpace); #endif diff --git a/Source/WebCore/platform/graphics/Font.cpp b/Source/WebCore/platform/graphics/Font.cpp index f55725e67..42dd14a6b 100644 --- a/Source/WebCore/platform/graphics/Font.cpp +++ b/Source/WebCore/platform/graphics/Font.cpp @@ -166,12 +166,7 @@ void Font::drawText(GraphicsContext* context, const TextRun& run, const FloatPoi to = (to == -1 ? run.length() : to); - CodePath codePathToUse = codePath(run); - // FIXME: Use the fast code path once it handles partial runs with kerning and ligatures. See http://webkit.org/b/100050 - if (codePathToUse != Complex && typesettingFeatures() && (from || to != run.length())) - codePathToUse = Complex; - - if (codePathToUse != Complex) + if (codePath(run) != Complex) return drawSimpleText(context, run, point, from, to); return drawComplexText(context, run, point, from, to); @@ -185,12 +180,7 @@ void Font::drawEmphasisMarks(GraphicsContext* context, const TextRun& run, const if (to < 0) to = run.length(); - CodePath codePathToUse = codePath(run); - // FIXME: Use the fast code path once it handles partial runs with kerning and ligatures. See http://webkit.org/b/100050 - if (codePathToUse != Complex && typesettingFeatures() && (from || to != run.length())) - codePathToUse = Complex; - - if (codePathToUse != Complex) + if (codePath(run) != Complex) drawEmphasisMarksForSimpleText(context, run, mark, point, from, to); else drawEmphasisMarksForComplexText(context, run, mark, point, from, to); @@ -260,12 +250,7 @@ FloatRect Font::selectionRectForText(const TextRun& run, const FloatPoint& point { to = (to == -1 ? run.length() : to); - CodePath codePathToUse = codePath(run); - // FIXME: Use the fast code path once it handles partial runs with kerning and ligatures. See http://webkit.org/b/100050 - if (codePathToUse != Complex && typesettingFeatures() && (from || to != run.length())) - codePathToUse = Complex; - - if (codePathToUse != Complex) + if (codePath(run) != Complex) return selectionRectForSimpleText(run, point, h, from, to); return selectionRectForComplexText(run, point, h, from, to); @@ -273,8 +258,7 @@ FloatRect Font::selectionRectForText(const TextRun& run, const FloatPoint& point int Font::offsetForPosition(const TextRun& run, float x, bool includePartialGlyphs) const { - // FIXME: Use the fast code path once it handles partial runs with kerning and ligatures. See http://webkit.org/b/100050 - if (codePath(run) != Complex && !typesettingFeatures()) + if (codePath(run) != Complex) return offsetForPositionForSimpleText(run, x, includePartialGlyphs); return offsetForPositionForComplexText(run, x, includePartialGlyphs); diff --git a/Source/WebCore/platform/graphics/FontFastPath.cpp b/Source/WebCore/platform/graphics/FontFastPath.cpp index 7ed7a9703..22ce7f57e 100644 --- a/Source/WebCore/platform/graphics/FontFastPath.cpp +++ b/Source/WebCore/platform/graphics/FontFastPath.cpp @@ -325,32 +325,34 @@ int Font::emphasisMarkHeight(const AtomicString& mark) const float Font::getGlyphsAndAdvancesForSimpleText(const TextRun& run, int from, int to, GlyphBuffer& glyphBuffer, ForTextEmphasisOrNot forTextEmphasis) const { - float initialAdvance; - WidthIterator it(this, run, 0, false, forTextEmphasis); - // FIXME: Using separate glyph buffers for the prefix and the suffix is incorrect when kerning or - // ligatures are enabled. GlyphBuffer localGlyphBuffer; - it.advance(from, &localGlyphBuffer); - float beforeWidth = it.m_runWidthSoFar; - it.advance(to, &glyphBuffer); + it.advance(run.length(), &localGlyphBuffer); - if (glyphBuffer.isEmpty()) + if (localGlyphBuffer.isEmpty()) return 0; - float afterWidth = it.m_runWidthSoFar; + float totalWidth = it.m_runWidthSoFar; + float beforeWidth = 0; + int glyphPos = 0; + for (; glyphPos < localGlyphBuffer.size() && it.m_characterIndex[glyphPos] < from; ++glyphPos) + beforeWidth += localGlyphBuffer.advanceAt(glyphPos); + int glyphFrom = glyphPos; - if (run.rtl()) { - float finalRoundingWidth = it.m_finalRoundingWidth; - it.advance(run.length(), &localGlyphBuffer); - initialAdvance = finalRoundingWidth + it.m_runWidthSoFar - afterWidth; - } else - initialAdvance = beforeWidth; + float afterWidth = totalWidth; + glyphPos = localGlyphBuffer.size() - 1; + for (; glyphPos >= glyphFrom && it.m_characterIndex[glyphPos] >= to; --glyphPos) + afterWidth -= localGlyphBuffer.advanceAt(glyphPos); + int glyphTo = glyphPos + 1; + + glyphBuffer.add(&localGlyphBuffer, glyphFrom, glyphTo - glyphFrom); - if (run.rtl()) + if (run.rtl()) { glyphBuffer.reverse(0, glyphBuffer.size()); + return totalWidth - afterWidth; + } - return initialAdvance; + return beforeWidth; } void Font::drawSimpleText(GraphicsContext* context, const TextRun& run, const FloatPoint& point, int from, int to) const @@ -487,15 +489,22 @@ FloatRect Font::selectionRectForSimpleText(const TextRun& run, const FloatPoint& { GlyphBuffer glyphBuffer; WidthIterator it(this, run); - it.advance(from, &glyphBuffer); - float beforeWidth = it.m_runWidthSoFar; - it.advance(to, &glyphBuffer); - float afterWidth = it.m_runWidthSoFar; + it.advance(run.length(), &glyphBuffer); + + float totalWidth = it.m_runWidthSoFar; + float beforeWidth = 0; + int glyphPos = 0; + for (; glyphPos < glyphBuffer.size() && it.m_characterIndex[glyphPos] < from; ++glyphPos) + beforeWidth += glyphBuffer.advanceAt(glyphPos); + int glyphFrom = glyphPos; + + float afterWidth = totalWidth; + glyphPos = glyphBuffer.size() - 1; + for (; glyphPos >= glyphFrom && it.m_characterIndex[glyphPos] >= to; --glyphPos) + afterWidth -= glyphBuffer.advanceAt(glyphPos); // Using roundf() rather than ceilf() for the right edge as a compromise to ensure correct caret positioning. if (run.rtl()) { - it.advance(run.length(), &glyphBuffer); - float totalWidth = it.m_runWidthSoFar; return FloatRect(floorf(point.x() + totalWidth - afterWidth), point.y(), roundf(point.x() + totalWidth - beforeWidth) - floorf(point.x() + totalWidth - afterWidth), h); } @@ -504,45 +513,50 @@ FloatRect Font::selectionRectForSimpleText(const TextRun& run, const FloatPoint& int Font::offsetForPositionForSimpleText(const TextRun& run, float x, bool includePartialGlyphs) const { - float delta = x; - + GlyphBuffer glyphBuffer; WidthIterator it(this, run); - GlyphBuffer localGlyphBuffer; - unsigned offset; + it.advance(run.length(), &glyphBuffer); + + int characterOffset = 0; if (run.rtl()) { - delta -= floatWidthForSimpleText(run); - while (1) { - offset = it.m_currentCharacter; - float w; - if (!it.advanceOneCharacter(w, localGlyphBuffer)) + float currentX = it.m_runWidthSoFar; + for (int glyphPosition = 0; glyphPosition <= glyphBuffer.size(); ++glyphPosition) { + if (glyphPosition == glyphBuffer.size()) { + characterOffset = run.length(); break; - delta += w; + } + characterOffset = it.m_characterIndex[glyphPosition]; + float glyphWidth = glyphBuffer.advanceAt(glyphPosition); if (includePartialGlyphs) { - if (delta - w / 2 >= 0) + if (currentX - glyphWidth / 2.0f <= x) break; } else { - if (delta >= 0) + if (currentX - glyphWidth <= x) break; } + currentX -= glyphWidth; } } else { - while (1) { - offset = it.m_currentCharacter; - float w; - if (!it.advanceOneCharacter(w, localGlyphBuffer)) + float currentX = 0; + for (int glyphPosition = 0; glyphPosition <= glyphBuffer.size(); ++glyphPosition) { + if (glyphPosition == glyphBuffer.size()) { + characterOffset = run.length(); break; - delta -= w; + } + characterOffset = it.m_characterIndex[glyphPosition]; + float glyphWidth = glyphBuffer.advanceAt(glyphPosition); if (includePartialGlyphs) { - if (delta + w / 2 <= 0) + if (currentX + glyphWidth / 2.0f >= x) break; } else { - if (delta <= 0) + if (currentX + glyphWidth >= x) break; } + currentX += glyphWidth; } } - return offset; + return characterOffset; } -} +} // namespace WebCore diff --git a/Source/WebCore/platform/graphics/GlyphBuffer.h b/Source/WebCore/platform/graphics/GlyphBuffer.h index 3aec08e65..9d757bc20 100644 --- a/Source/WebCore/platform/graphics/GlyphBuffer.h +++ b/Source/WebCore/platform/graphics/GlyphBuffer.h @@ -153,6 +153,16 @@ public: #endif } + void add(const GlyphBuffer* glyphBuffer, int from, int len) + { + m_glyphs.append(glyphBuffer->glyphs(from), len); + m_advances.append(glyphBuffer->advances(from), len); + m_fontData.append(glyphBuffer->m_fontData.data() + from, len); +#if PLATFORM(WIN) + m_offsets.append(glyphBuffer->m_offsets.data() + from, len); +#endif + } + void add(Glyph glyph, const SimpleFontData* font, float width, const FloatSize* offset = 0) { m_fontData.append(font); diff --git a/Source/WebCore/platform/graphics/SimpleFontData.h b/Source/WebCore/platform/graphics/SimpleFontData.h index 8621ca596..a99482404 100644 --- a/Source/WebCore/platform/graphics/SimpleFontData.h +++ b/Source/WebCore/platform/graphics/SimpleFontData.h @@ -200,6 +200,8 @@ public: bool applyTransforms(GlyphBufferGlyph* glyphs, GlyphBufferAdvance* advances, size_t glyphCount, TypesettingFeatures typesettingFeatures) const { + if (isSVGFont()) + return false; #if PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED > 1080 wkCTFontTransformOptions options = (typesettingFeatures & Kerning ? wkCTFontTransformApplyPositioning : 0) | (typesettingFeatures & Ligatures ? wkCTFontTransformApplyShaping : 0); return wkCTFontTransformGlyphs(m_platformData.ctFont(), glyphs, reinterpret_cast<CGSize*>(advances), glyphCount, options); diff --git a/Source/WebCore/platform/graphics/WidthIterator.cpp b/Source/WebCore/platform/graphics/WidthIterator.cpp index 96600c732..1fb1d9b40 100644 --- a/Source/WebCore/platform/graphics/WidthIterator.cpp +++ b/Source/WebCore/platform/graphics/WidthIterator.cpp @@ -162,7 +162,8 @@ inline unsigned WidthIterator::advanceInternal(TextIterator& textIterator, Glyph CharactersTreatedAsSpace charactersTreatedAsSpace; while (textIterator.consume(character, clusterLength)) { unsigned advanceLength = clusterLength; - const GlyphData& glyphData = glyphDataForCharacter(character, rtl, textIterator.currentCharacter(), advanceLength); + int currentCharacterIndex = textIterator.currentCharacter(); + const GlyphData& glyphData = glyphDataForCharacter(character, rtl, currentCharacterIndex, advanceLength); Glyph glyph = glyphData.glyph; const SimpleFontData* fontData = glyphData.fontData; @@ -223,9 +224,10 @@ inline unsigned WidthIterator::advanceInternal(TextIterator& textIterator, Glyph float expansionAtThisOpportunity = !m_run.applyWordRounding() ? m_expansionPerOpportunity : roundf(previousExpansion) - roundf(m_expansion); m_runWidthSoFar += expansionAtThisOpportunity; if (glyphBuffer) { - if (glyphBuffer->isEmpty()) + if (glyphBuffer->isEmpty()) { glyphBuffer->add(fontData->spaceGlyph(), fontData, expansionAtThisOpportunity); - else + m_characterIndex.append(currentCharacterIndex); + } else glyphBuffer->expandLastAdvance(expansionAtThisOpportunity); } previousExpansion = m_expansion; @@ -291,8 +293,10 @@ inline unsigned WidthIterator::advanceInternal(TextIterator& textIterator, Glyph widthSinceLastRounding += width; } - if (glyphBuffer) + if (glyphBuffer) { glyphBuffer->add(glyph, fontData, (rtl ? oldWidth + lastRoundingWidth : width)); + m_characterIndex.append(currentCharacterIndex); + } lastRoundingWidth = width - oldWidth; @@ -332,15 +336,4 @@ unsigned WidthIterator::advance(int offset, GlyphBuffer* glyphBuffer) return advanceInternal(textIterator, glyphBuffer); } -bool WidthIterator::advanceOneCharacter(float& width, GlyphBuffer& glyphBuffer) -{ - int oldSize = glyphBuffer.size(); - advance(m_currentCharacter + 1, &glyphBuffer); - float w = 0; - for (int i = oldSize; i < glyphBuffer.size(); ++i) - w += glyphBuffer.advanceAt(i); - width = w; - return glyphBuffer.size() > oldSize; -} - } diff --git a/Source/WebCore/platform/graphics/WidthIterator.h b/Source/WebCore/platform/graphics/WidthIterator.h index 8e4e06997..6dc1c206c 100644 --- a/Source/WebCore/platform/graphics/WidthIterator.h +++ b/Source/WebCore/platform/graphics/WidthIterator.h @@ -43,7 +43,6 @@ public: WidthIterator(const Font*, const TextRun&, HashSet<const SimpleFontData*>* fallbackFonts = 0, bool accountForGlyphBounds = false, bool forTextEmphasis = false); unsigned advance(int to, GlyphBuffer*); - bool advanceOneCharacter(float& width, GlyphBuffer&); float maxGlyphBoundingBoxY() const { ASSERT(m_accountForGlyphBounds); return m_maxGlyphBoundingBoxY; } float minGlyphBoundingBoxY() const { ASSERT(m_accountForGlyphBounds); return m_minGlyphBoundingBoxY; } @@ -83,6 +82,7 @@ public: float m_expansionPerOpportunity; bool m_isAfterExpansion; float m_finalRoundingWidth; + Vector<int> m_characterIndex; #if ENABLE(SVG_FONTS) String m_lastGlyphName; diff --git a/Source/WebCore/platform/graphics/filters/FEBlend.cpp b/Source/WebCore/platform/graphics/filters/FEBlend.cpp index d5897c392..bf527ff53 100644 --- a/Source/WebCore/platform/graphics/filters/FEBlend.cpp +++ b/Source/WebCore/platform/graphics/filters/FEBlend.cpp @@ -63,14 +63,6 @@ bool FEBlend::setBlendMode(BlendModeType mode) return true; } -static inline unsigned char fastDivideBy255(uint16_t value) -{ - // This is an approximate algorithm for division by 255, but it gives accurate results for 16bit values. - uint16_t quotient = value >> 8; - uint16_t remainder = value - (quotient * 255) + 1; - return quotient + (remainder >> 8); -} - inline unsigned char feBlendNormal(unsigned char colorA, unsigned char colorB, unsigned char alphaA, unsigned char) { return fastDivideBy255((255 - alphaA) * colorB + colorA * 255); diff --git a/Source/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp b/Source/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp index 7984c9ae8..776acce2b 100644 --- a/Source/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp +++ b/Source/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp @@ -40,6 +40,7 @@ #include "config.h" #include "PNGImageDecoder.h" +#include "Color.h" #include "PlatformInstrumentation.h" #include "png.h" #include <wtf/OwnArrayPtr.h> @@ -402,6 +403,29 @@ void PNGImageDecoder::headerAvailable() } } +static inline void setPixelRGB(ImageFrame::PixelData* dest, png_bytep pixel) +{ + *dest = 0xFF000000U | pixel[0] << 16 | pixel[1] << 8 | pixel[2]; +} + +static inline void setPixelRGBA(ImageFrame::PixelData* dest, png_bytep pixel, unsigned char& nonTrivialAlphaMask) +{ + unsigned char a = pixel[3]; + *dest = a << 24 | pixel[0] << 16 | pixel[1] << 8 | pixel[2]; + nonTrivialAlphaMask |= (255 - a); +} + +static inline void setPixelPremultipliedRGBA(ImageFrame::PixelData* dest, png_bytep pixel, unsigned char& nonTrivialAlphaMask) +{ + unsigned char a = pixel[3]; + unsigned char r = fastDivideBy255(pixel[0] * a); + unsigned char g = fastDivideBy255(pixel[1] * a); + unsigned char b = fastDivideBy255(pixel[2] * a); + + *dest = a << 24 | r << 16 | g << 8 | b; + nonTrivialAlphaMask |= (255 - a); +} + void PNGImageDecoder::rowAvailable(unsigned char* rowBuffer, unsigned rowIndex, int) { if (m_frameBufferCache.isEmpty()) @@ -501,27 +525,37 @@ void PNGImageDecoder::rowAvailable(unsigned char* rowBuffer, unsigned rowIndex, // Write the decoded row pixels to the frame buffer. ImageFrame::PixelData* address = buffer.getAddr(0, y); int width = scaledSize().width(); - bool nonTrivialAlpha = false; + unsigned char nonTrivialAlphaMask = 0; #if ENABLE(IMAGE_DECODER_DOWN_SAMPLING) - for (int x = 0; x < width; ++x) { - png_bytep pixel = row + (m_scaled ? m_scaledColumns[x] : x) * colorChannels; - unsigned alpha = hasAlpha ? pixel[3] : 255; - buffer.setRGBA(address++, pixel[0], pixel[1], pixel[2], alpha); - nonTrivialAlpha |= alpha < 255; - } -#else - ASSERT(!m_scaled); - png_bytep pixel = row; - for (int x = 0; x < width; ++x, pixel += colorChannels) { - unsigned alpha = hasAlpha ? pixel[3] : 255; - buffer.setRGBA(address++, pixel[0], pixel[1], pixel[2], alpha); - nonTrivialAlpha |= alpha < 255; - } + if (m_scaled) { + for (int x = 0; x < width; ++x) { + png_bytep pixel = row + m_scaledColumns[x] * colorChannels; + unsigned alpha = hasAlpha ? pixel[3] : 255; + buffer.setRGBA(address++, pixel[0], pixel[1], pixel[2], alpha); + nonTrivialAlphaMask |= (255 - alpha); + } + } else #endif + { + png_bytep pixel = row; + if (hasAlpha) { + if (buffer.premultiplyAlpha()) { + for (int x = 0; x < width; ++x, pixel += 4) + setPixelPremultipliedRGBA(address++, pixel, nonTrivialAlphaMask); + } else { + for (int x = 0; x < width; ++x, pixel += 4) + setPixelRGBA(address++, pixel, nonTrivialAlphaMask); + } + } else { + for (int x = 0; x < width; ++x, pixel += 3) + setPixelRGB(address++, pixel); + } + } + - if (nonTrivialAlpha && !buffer.hasAlpha()) - buffer.setHasAlpha(nonTrivialAlpha); + if (nonTrivialAlphaMask && !buffer.hasAlpha()) + buffer.setHasAlpha(true); } void PNGImageDecoder::pngComplete() diff --git a/Source/WebCore/platform/network/qt/QNetworkReplyHandler.cpp b/Source/WebCore/platform/network/qt/QNetworkReplyHandler.cpp index 904e85983..d4bc9bcb8 100644 --- a/Source/WebCore/platform/network/qt/QNetworkReplyHandler.cpp +++ b/Source/WebCore/platform/network/qt/QNetworkReplyHandler.cpp @@ -272,6 +272,7 @@ QNetworkReplyWrapper::QNetworkReplyWrapper(QNetworkReplyHandlerCallQueue* queue, connect(m_reply, SIGNAL(finished()), this, SLOT(setFinished())); connect(m_reply, SIGNAL(finished()), this, SLOT(receiveMetaData())); connect(m_reply, SIGNAL(readyRead()), this, SLOT(receiveMetaData())); + connect(m_reply, SIGNAL(destroyed()), this, SLOT(replyDestroyed())); } QNetworkReplyWrapper::~QNetworkReplyWrapper() @@ -286,12 +287,11 @@ QNetworkReply* QNetworkReplyWrapper::release() if (!m_reply) return 0; - resetConnections(); + m_reply->disconnect(this); QNetworkReply* reply = m_reply; m_reply = 0; m_sniffer = nullptr; - reply->setParent(0); return reply; } @@ -301,10 +301,10 @@ void QNetworkReplyWrapper::synchronousLoad() receiveMetaData(); } -void QNetworkReplyWrapper::resetConnections() +void QNetworkReplyWrapper::stopForwarding() { if (m_reply) { - // Disconnect all connections except the one to setFinished() slot. + // Disconnect all connections that might affect the ResourceHandleClient. m_reply->disconnect(this, SLOT(receiveMetaData())); m_reply->disconnect(this, SLOT(didReceiveFinished())); m_reply->disconnect(this, SLOT(didReceiveReadyRead())); @@ -315,8 +315,7 @@ void QNetworkReplyWrapper::resetConnections() void QNetworkReplyWrapper::receiveMetaData() { // This slot is only used to receive the first signal from the QNetworkReply object. - resetConnections(); - + stopForwarding(); WTF::String contentType = m_reply->header(QNetworkRequest::ContentTypeHeader).toString(); m_encoding = extractCharsetFromMediaType(contentType); @@ -369,6 +368,12 @@ void QNetworkReplyWrapper::setFinished() m_reply->setProperty("_q_isFinished", true); } +void QNetworkReplyWrapper::replyDestroyed() +{ + m_reply = 0; + m_sniffer = nullptr; +} + void QNetworkReplyWrapper::emitMetaDataChanged() { QueueLocker lock(m_queue); @@ -399,7 +404,7 @@ void QNetworkReplyWrapper::didReceiveReadyRead() void QNetworkReplyWrapper::didReceiveFinished() { // Disconnecting will make sure that nothing will happen after emitting the finished signal. - resetConnections(); + stopForwarding(); m_queue->push(&QNetworkReplyHandler::finish); } diff --git a/Source/WebCore/platform/network/qt/QNetworkReplyHandler.h b/Source/WebCore/platform/network/qt/QNetworkReplyHandler.h index a68904147..6bc35cc12 100644 --- a/Source/WebCore/platform/network/qt/QNetworkReplyHandler.h +++ b/Source/WebCore/platform/network/qt/QNetworkReplyHandler.h @@ -94,9 +94,10 @@ private Q_SLOTS: void didReceiveReadyRead(); void receiveSniffedMIMEType(); void setFinished(); + void replyDestroyed(); private: - void resetConnections(); + void stopForwarding(); void emitMetaDataChanged(); QNetworkReply* m_reply; diff --git a/Source/WebCore/platform/qt/FileSystemQt.cpp b/Source/WebCore/platform/qt/FileSystemQt.cpp index 16f4d7420..9744790d3 100644 --- a/Source/WebCore/platform/qt/FileSystemQt.cpp +++ b/Source/WebCore/platform/qt/FileSystemQt.cpp @@ -234,7 +234,7 @@ int writeToFile(PlatformFileHandle handle, const char* data, int length) bool unloadModule(PlatformModule module) { -#if defined(Q_WS_MAC) +#if defined(Q_OS_MACX) CFRelease(module); return true; diff --git a/Source/WebCore/platform/qt/QWebPageClient.h b/Source/WebCore/platform/qt/QWebPageClient.h index 1526e9d20..da9ef05de 100644 --- a/Source/WebCore/platform/qt/QWebPageClient.h +++ b/Source/WebCore/platform/qt/QWebPageClient.h @@ -86,6 +86,7 @@ public: virtual int screenNumber() const = 0; virtual QObject* ownerWidget() const = 0; virtual QRect geometryRelativeToOwnerWidget() const = 0; + virtual QPoint mapToOwnerWindow(const QPoint&) const = 0; virtual QObject* pluginParent() const = 0; diff --git a/Source/WebCore/plugins/PluginView.cpp b/Source/WebCore/plugins/PluginView.cpp index 8a31103af..cdf8a78bb 100644 --- a/Source/WebCore/plugins/PluginView.cpp +++ b/Source/WebCore/plugins/PluginView.cpp @@ -646,11 +646,7 @@ NPError PluginView::setValue(NPPVariable variable, void* value) NPDrawingModel newDrawingModel = NPDrawingModel(uintptr_t(value)); switch (newDrawingModel) { case NPDrawingModelCoreGraphics: - m_drawingModel = newDrawingModel; return NPERR_NO_ERROR; -#ifndef NP_NO_QUICKDRAW - case NPDrawingModelQuickDraw: -#endif case NPDrawingModelCoreAnimation: default: LOG(Plugins, "Plugin asked for unsupported drawing model: %s", @@ -666,13 +662,8 @@ NPError PluginView::setValue(NPPVariable variable, void* value) NPEventModel newEventModel = NPEventModel(uintptr_t(value)); switch (newEventModel) { -#ifndef NP_NO_CARBON - case NPEventModelCarbon: -#endif case NPEventModelCocoa: - m_eventModel = newEventModel; return NPERR_NO_ERROR; - default: LOG(Plugins, "Plugin asked for unsupported event model: %s", prettyNameForEventModel(newEventModel)); @@ -856,14 +847,11 @@ PluginView::PluginView(Frame* parentFrame, const IntSize& size, PluginPackage* p , m_wmPrintHDC(0) , m_haveUpdatedPluginWidget(false) #endif -#if (PLATFORM(QT) && OS(WINDOWS)) || defined(XP_MACOSX) || PLATFORM(EFL) +#if (PLATFORM(QT) && OS(WINDOWS)) || PLATFORM(EFL) , m_window(0) #endif #if defined(XP_MACOSX) - , m_drawingModel(NPDrawingModel(-1)) - , m_eventModel(NPEventModel(-1)) , m_contextRef(0) - , m_fakeWindow(0) #endif #if defined(XP_UNIX) && ENABLE(NETSCAPE_PLUGIN_API) , m_hasPendingGeometryChange(true) diff --git a/Source/WebCore/plugins/PluginView.h b/Source/WebCore/plugins/PluginView.h index 84e62d8ae..361c286db 100644 --- a/Source/WebCore/plugins/PluginView.h +++ b/Source/WebCore/plugins/PluginView.h @@ -52,9 +52,6 @@ typedef struct HWND__* HWND; typedef HWND PlatformPluginWidget; #else typedef PlatformWidget PlatformPluginWidget; -#if defined(XP_MACOSX) && PLATFORM(QT) -#include <QPixmap> -#endif #endif #if PLATFORM(QT) #if USE(TEXTURE_MAPPER) @@ -323,16 +320,13 @@ namespace WebCore { void lifeSupportTimerFired(Timer<PluginView>*); Timer<PluginView> m_lifeSupportTimer; -#ifndef NP_NO_CARBON #if ENABLE(NETSCAPE_PLUGIN_API) bool dispatchNPEvent(NPEvent&); -#endif // ENABLE(NETSCAPE_PLUGIN_API) #endif #if defined(XP_MACOSX) && ENABLE(NETSCAPE_PLUGIN_API) int16_t dispatchNPCocoaEvent(NPCocoaEvent&); bool m_updatedCocoaTextInputRequested; bool m_keyDownSent; - bool m_usePixmap; uint16_t m_disregardKeyUpCounter; #endif @@ -392,7 +386,7 @@ namespace WebCore { bool m_haveUpdatedPluginWidget; #endif -#if ((PLATFORM(GTK) || PLATFORM(QT) || PLATFORM(WX)) && OS(WINDOWS)) || defined(XP_MACOSX) || PLATFORM(EFL) +#if ((PLATFORM(GTK) || PLATFORM(QT) || PLATFORM(WX)) && OS(WINDOWS)) || PLATFORM(EFL) // On Mac OSX and Qt/Windows the plugin does not have its own native widget, // but is using the containing window as its reference for positioning/painting. PlatformPluginWidget m_window; @@ -411,20 +405,9 @@ private: void setNPWindowIfNeeded(); #elif defined(XP_MACOSX) NP_CGContext m_npCgContext; - OwnPtr<Timer<PluginView> > m_nullEventTimer; - NPDrawingModel m_drawingModel; - NPEventModel m_eventModel; CGContextRef m_contextRef; - WindowRef m_fakeWindow; -#if PLATFORM(QT) - QPixmap m_pixmap; -#endif - Point m_lastMousePos; void setNPWindowIfNeeded(); - void nullEventTimerFired(Timer<PluginView>*); - Point globalMousePosForPlugin() const; - Point mousePosForPlugin(MouseEvent* event = 0) const; #endif #if defined(XP_UNIX) && ENABLE(NETSCAPE_PLUGIN_API) diff --git a/Source/WebCore/plugins/mac/PluginPackageMac.cpp b/Source/WebCore/plugins/mac/PluginPackageMac.cpp index fead89bc3..23a5e231b 100644 --- a/Source/WebCore/plugins/mac/PluginPackageMac.cpp +++ b/Source/WebCore/plugins/mac/PluginPackageMac.cpp @@ -138,7 +138,7 @@ bool PluginPackage::fetchInfo() if (mimeTypesFileName && CFGetTypeID(mimeTypesFileName.get()) == CFStringGetTypeID()) { WTF::RetainPtr<CFStringRef> fileName = (CFStringRef)mimeTypesFileName.get(); - WTF::RetainPtr<CFStringRef> homeDir = adoptCF(homeDirectoryPath().createCFString()); + WTF::RetainPtr<CFStringRef> homeDir = homeDirectoryPath().createCFString(); WTF::RetainPtr<CFStringRef> path(AdoptCF, CFStringCreateWithFormat(0, 0, CFSTR("%@/Library/Preferences/%@"), homeDir.get(), fileName.get())); WTF::RetainPtr<CFDictionaryRef> plist = readPListFile(path.get(), /*createFile*/ false, m_module); @@ -255,7 +255,7 @@ bool PluginPackage::load() return true; } - WTF::RetainPtr<CFStringRef> path(AdoptCF, m_path.createCFString()); + WTF::RetainPtr<CFStringRef> path = m_path.createCFString(); WTF::RetainPtr<CFURLRef> url(AdoptCF, CFURLCreateWithFileSystemPath(kCFAllocatorDefault, path.get(), kCFURLPOSIXPathStyle, false)); m_module = CFBundleCreate(NULL, url.get()); diff --git a/Source/WebCore/plugins/mac/PluginViewMac.mm b/Source/WebCore/plugins/mac/PluginViewMac.mm index 849a57fdf..c163b5f3b 100644 --- a/Source/WebCore/plugins/mac/PluginViewMac.mm +++ b/Source/WebCore/plugins/mac/PluginViewMac.mm @@ -61,6 +61,9 @@ #include "WheelEvent.h" #include "npruntime_impl.h" #include "runtime_root.h" +#include <AppKit/NSEvent.h> +#include <AppKit/NSMenu.h> +#include <AppKit/NSWindow.h> #include <runtime/JSLock.h> #include <runtime/JSValue.h> #include <wtf/RetainPtr.h> @@ -73,16 +76,7 @@ using JSC::JSObject; using JSC::JSValue; #if PLATFORM(QT) -#include <QWidget> -#include <QKeyEvent> #include <QPainter> -#include <QDateTime> -#include <QPixmap> -#include "QWebPageClient.h" -QT_BEGIN_NAMESPACE -extern Q_GUI_EXPORT OSWindowRef qt_mac_window_for(const QWidget* w); -extern Q_GUI_EXPORT CGContextRef qt_mac_cg_context(const QPaintDevice *pdev); //qpaintdevice_mac.cpp -QT_END_NAMESPACE #endif #if PLATFORM(WX) @@ -90,64 +84,12 @@ QT_END_NAMESPACE #include <wx/wx.h> #endif -using std::min; - using namespace WTF; namespace WebCore { using namespace HTMLNames; -#ifndef NP_NO_CARBON -static int modifiersForEvent(UIEventWithKeyState *event); -#endif - -static inline WindowRef nativeWindowFor(PlatformWidget widget) -{ -#if PLATFORM(QT) - if (widget) -#if QT_MAC_USE_COCOA - return static_cast<WindowRef>([qt_mac_window_for(static_cast<QWidget*>(widget)) windowRef]); -#else - return static_cast<WindowRef>(qt_mac_window_for(widget)); -#endif -#elif PLATFORM(WX) - if (widget) - return (WindowRef)widget->MacGetTopLevelWindowRef(); -#endif - return 0; -} - -static inline CGContextRef cgHandleFor(PlatformWidget widget) -{ -#if PLATFORM(QT) - if (widget) - return (CGContextRef)static_cast<QWidget*>(widget)->macCGHandle(); -#endif -#if PLATFORM(WX) - if (widget) - return (CGContextRef)widget->MacGetCGContextRef(); -#endif - return 0; -} - -static inline IntPoint topLevelOffsetFor(PlatformWidget widget) -{ -#if PLATFORM(QT) - if (widget) { - QWidget* topLevel = static_cast<QWidget*>(widget)->window(); - return static_cast<QWidget*>(widget)->mapTo(topLevel, QPoint(0, 0)) + topLevel->geometry().topLeft() - topLevel->pos(); - } -#endif -#if PLATFORM(WX) - if (widget) { - PlatformWidget toplevel = wxGetTopLevelParent(widget); - return toplevel->ScreenToClient(widget->GetScreenPosition()); - } -#endif - return IntPoint(); -} - // --------- Cocoa specific utility functions ---------- static void initializeNPCocoaEvent(NPCocoaEvent* event) @@ -167,6 +109,19 @@ static int32_t getModifiers(UIEventWithKeyState *event) return modifiers; } +static CGContextRef createBitmapContext(const IntSize& size) +{ + CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB(); + uint flags = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host; + CGContextRef context = CGBitmapContextCreate(0, size.width(), size.height(), + 8, 4 * size.width(), colorspace, flags); + + CGContextTranslateCTM(context, 0, size.height()); + CGContextScaleCTM(context, 1, -1); + CGColorSpaceRelease(colorspace); + return context; +} + // --------------- Lifetime management ----------------- bool PluginView::platformStart() @@ -174,120 +129,28 @@ bool PluginView::platformStart() ASSERT(m_isStarted); ASSERT(m_status == PluginStatusLoadedSuccessfully); - if (m_drawingModel == NPDrawingModel(-1)) { - // We default to QuickDraw, even though we don't support it, - // since that's what Safari does, and some plugins expect this - // behavior and never set the drawing model explicitly. -#ifndef NP_NO_QUICKDRAW - m_drawingModel = NPDrawingModelQuickDraw; -#else - // QuickDraw not available, so we have to default to CoreGraphics - m_drawingModel = NPDrawingModelCoreGraphics; -#endif - } - - if (m_eventModel == NPEventModel(-1)) { - // If the plug-in did not specify an event model - // we default to Carbon, when it is available. -#ifndef NP_NO_CARBON - m_eventModel = NPEventModelCarbon; -#else - m_eventModel = NPEventModelCocoa; -#endif - } - // Gracefully handle unsupported drawing or event models. We can do this // now since the drawing and event model can only be set during NPP_New. -#ifndef NP_NO_CARBON NPBool eventModelSupported; - if (getValueStatic(NPNVariable(NPNVsupportsCarbonBool + m_eventModel), &eventModelSupported) != NPERR_NO_ERROR + if (getValueStatic(NPNVariable(NPNVsupportsCocoaBool), &eventModelSupported) != NPERR_NO_ERROR || !eventModelSupported) { -#else - NPBool eventModelSupported; - if (getValueStatic(NPNVariable(NPNVsupportsCocoaBool/* + m_eventModel*/), &eventModelSupported) != NPERR_NO_ERROR - || !eventModelSupported) { -#endif m_status = PluginStatusCanNotLoadPlugin; LOG(Plugins, "Plug-in '%s' uses unsupported event model %s", - m_plugin->name().utf8().data(), prettyNameForEventModel(m_eventModel)); - return false; - } - -#ifndef NP_NO_QUICKDRAW - NPBool drawingModelSupported; - if (getValueStatic(NPNVariable(NPNVsupportsQuickDrawBool + m_drawingModel), &drawingModelSupported) != NPERR_NO_ERROR - || !drawingModelSupported) { - m_status = PluginStatusCanNotLoadPlugin; - LOG(Plugins, "Plug-in '%s' uses unsupported drawing model %s", - m_plugin->name().utf8().data(), prettyNameForDrawingModel(m_drawingModel)); + m_plugin->name().utf8().data(), prettyNameForEventModel(NPEventModelCocoa)); return false; } -#endif - -#ifdef NP_NO_QUICKDRAW - NPBool drawingModelSupported; - if (getValueStatic(NPNVariable(NPNVsupportsCoreGraphicsBool/* + m_drawingModel*/), &drawingModelSupported) != NPERR_NO_ERROR - || !drawingModelSupported) { - m_status = PluginStatusCanNotLoadPlugin; - LOG(Plugins, "Plug-in '%s' uses unsupported drawing model %s", - m_plugin->name().utf8().data(), prettyNameForDrawingModel(m_drawingModel)); - return false; - } -#endif - - -#if PLATFORM(QT) - // Set the platformPluginWidget only in the case of QWebView so that the context menu appears in the right place. - // In all other cases, we use off-screen rendering - if (QWebPageClient* client = m_parentFrame->view()->hostWindow()->platformPageClient()) { - if (QWidget* widget = qobject_cast<QWidget*>(client->pluginParent())) - setPlatformPluginWidget(widget); - } -#endif -#if PLATFORM(WX) - if (wxWindow* widget = m_parentFrame->view()->hostWindow()->platformPageClient()) - setPlatformPluginWidget(widget); -#endif - - // Create a fake window relative to which all events will be sent when using offscreen rendering -#ifndef NP_NO_CARBON - if (!platformPluginWidget()) { - // Make the default size really big. It is unclear why this is required but with a smaller size, mouse move - // events don't get processed. Resizing the fake window to flash's size doesn't help. - ::Rect windowBounds = { 0, 0, 1000, 1000 }; - CreateNewWindow(kDocumentWindowClass, kWindowStandardDocumentAttributes, &windowBounds, &m_fakeWindow); - // Flash requires the window to be hilited to process mouse move events. - HiliteWindow(m_fakeWindow, true); - } -#endif updatePluginWidget(); if (!m_plugin->quirks().contains(PluginQuirkDeferFirstSetWindowCall)) setNPWindowIfNeeded(); -#ifndef NP_NO_CARBON - // TODO: Implement null timer throttling depending on plugin activation - m_nullEventTimer = adoptPtr(new Timer<PluginView>(this, &PluginView::nullEventTimerFired)); - m_nullEventTimer->startRepeating(0.02); - - m_lastMousePos.h = m_lastMousePos.v = 0; -#endif // NP_NO_CARBON - return true; } void PluginView::platformDestroy() { - if (platformPluginWidget()) - setPlatformPluginWidget(0); - else { - CGContextRelease(m_contextRef); -#ifndef NP_NO_CARBON - if (m_fakeWindow) - DisposeWindow(m_fakeWindow); -#endif - } + CGContextRelease(m_contextRef); } // Used before the plugin view has been initialized properly, and as a @@ -305,13 +168,6 @@ bool PluginView::platformGetValueStatic(NPNVariable variable, void* value, NPErr *result = NPERR_NO_ERROR; return true; -#ifndef NP_NO_CARBON - case NPNVsupportsCarbonBool: - *static_cast<NPBool*>(value) = true; - *result = NPERR_NO_ERROR; - return true; - -#endif case NPNVsupportsCocoaBool: *static_cast<NPBool*>(value) = true; *result = NPERR_NO_ERROR; @@ -328,10 +184,6 @@ bool PluginView::platformGetValueStatic(NPNVariable variable, void* value, NPErr *result = NPERR_NO_ERROR; return true; -#ifndef NP_NO_QUICKDRAW - // QuickDraw is deprecated in 10.5 and not supported on 64-bit - case NPNVsupportsQuickDrawBool: -#endif case NPNVsupportsOpenGLBool: case NPNVsupportsCoreAnimationBool: *static_cast<NPBool*>(value) = false; @@ -396,44 +248,19 @@ void PluginView::hide() void PluginView::setFocus(bool focused) { LOG(Plugins, "PluginView::setFocus(%d)", focused); - if (!focused) { - Widget::setFocus(focused); - if (m_eventModel != NPEventModelCocoa) - return; - } - - if (platformPluginWidget()) -#if PLATFORM(QT) - static_cast<QWidget*>(platformPluginWidget())->setFocus(Qt::OtherFocusReason); -#else - platformPluginWidget()->SetFocus(); -#endif - else + if (!focused) Widget::setFocus(focused); + Widget::setFocus(focused); -#ifndef NP_NO_CARBON - // TODO: Also handle and pass on blur events (focus lost) - EventRecord record; - record.what = NPEventType_GetFocusEvent; - record.message = 0; - record.when = TickCount(); - record.where = globalMousePosForPlugin(); - record.modifiers = GetCurrentKeyModifiers(); + NPCocoaEvent cocoaEvent; + initializeNPCocoaEvent(&cocoaEvent); + cocoaEvent.type = NPCocoaEventFocusChanged; + NPBool focus = focused; + cocoaEvent.data.focus.hasFocus = focus; - if (!dispatchNPEvent(record)) - LOG(Events, "PluginView::setFocus(%d): Focus event not accepted", focused); -#endif - { - NPCocoaEvent cocoaEvent; - initializeNPCocoaEvent(&cocoaEvent); - cocoaEvent.type = NPCocoaEventFocusChanged; - NPBool focus = focused; - cocoaEvent.data.focus.hasFocus = focus; - - if(!dispatchNPCocoaEvent(cocoaEvent)) { - LOG(Events, "PluginView::setFocus(): Focus event %d not accepted", cocoaEvent.type); - } + if(!dispatchNPCocoaEvent(cocoaEvent)) { + LOG(Events, "PluginView::setFocus(): Focus event %d not accepted", cocoaEvent.type); } } @@ -452,46 +279,27 @@ void PluginView::setNPWindowRect(const IntRect&) void PluginView::setNPWindowIfNeeded() { - if (!m_isStarted || !parent() || !m_plugin->pluginFuncs()->setwindow) + if (!m_isStarted || !parent() || !m_plugin->pluginFuncs()->setwindow || !m_contextRef) return; - CGContextRef newContextRef = 0; - WindowRef newWindowRef = 0; - if (platformPluginWidget()) { - newContextRef = cgHandleFor(platformPluginWidget()); - newWindowRef = nativeWindowFor(platformPluginWidget()); - m_npWindow.type = NPWindowTypeWindow; - } else { - newContextRef = m_contextRef; - newWindowRef = m_fakeWindow; - m_npWindow.type = NPWindowTypeDrawable; - } - - if (!newContextRef || !newWindowRef) { - if (!m_usePixmap) - return; - } - + // The context is set through the draw event. + ASSERT(!m_npCgContext.context && !m_npCgContext.window); m_npWindow.window = (void*)&m_npCgContext; -#ifndef NP_NO_CARBON - m_npCgContext.window = newWindowRef; -#endif - m_npCgContext.context = newContextRef; + m_npWindow.type = NPWindowTypeDrawable; m_npWindow.x = m_windowRect.x(); m_npWindow.y = m_windowRect.y(); m_npWindow.width = m_windowRect.width(); m_npWindow.height = m_windowRect.height(); - // TODO: (also clip against scrollbars, etc.) m_npWindow.clipRect.left = max(0, m_windowRect.x()); m_npWindow.clipRect.top = max(0, m_windowRect.y()); m_npWindow.clipRect.right = m_windowRect.x() + m_windowRect.width(); m_npWindow.clipRect.bottom = m_windowRect.y() + m_windowRect.height(); - LOG(Plugins, "PluginView::setNPWindowIfNeeded(): window=%p, context=%p," + LOG(Plugins, "PluginView::setNPWindowIfNeeded(): context=%p," " window.x:%d window.y:%d window.width:%d window.height:%d window.clipRect size:%dx%d", - newWindowRef, newContextRef, m_npWindow.x, m_npWindow.y, m_npWindow.width, m_npWindow.height, + m_contextRef, m_npWindow.x, m_npWindow.y, m_npWindow.width, m_npWindow.height, m_npWindow.clipRect.right - m_npWindow.clipRect.left, m_npWindow.clipRect.bottom - m_npWindow.clipRect.top); PluginView::setCurrentPluginView(this); @@ -511,27 +319,15 @@ void PluginView::updatePluginWidget() FrameView* frameView = static_cast<FrameView*>(parent()); IntRect oldWindowRect = m_windowRect; - IntRect oldClipRect = m_clipRect; - m_windowRect = frameView->contentsToWindow(frameRect()); - IntPoint offset = topLevelOffsetFor(platformPluginWidget()); - m_windowRect.move(offset.x(), offset.y()); - if (!platformPluginWidget()) { - if (m_windowRect.size() != oldWindowRect.size()) { - CGContextRelease(m_contextRef); -#if PLATFORM(QT) - m_pixmap = QPixmap(m_windowRect.size()); - m_pixmap.fill(Qt::transparent); - m_contextRef = m_pixmap.isNull() ? 0 : qt_mac_cg_context(&m_pixmap); -#endif - } + if (m_windowRect.size() != oldWindowRect.size()) { + CGContextRelease(m_contextRef); + m_contextRef = createBitmapContext(m_windowRect.size()); + CGContextClearRect(m_contextRef, CGRectMake(0, 0, m_windowRect.width(), m_windowRect.height())); } - m_clipRect = windowClipRect(); - m_clipRect.move(-m_windowRect.x(), -m_windowRect.y()); - - if (platformPluginWidget() && (m_windowRect != oldWindowRect || m_clipRect != oldClipRect)) + if (m_windowRect != oldWindowRect) setNPWindowIfNeeded(); } @@ -542,41 +338,10 @@ void PluginView::paint(GraphicsContext* context, const IntRect& rect) return; } - if (context->paintingDisabled()) + if (context->paintingDisabled() || !m_contextRef) return; -#if PLATFORM(QT) - QPainter* p = context->platformContext(); - CGContextRef cgContext = qt_mac_cg_context(p->device()); -#else - CGContextRef cgContext = m_npCgContext.context; -#endif - setNPWindowIfNeeded(); - if (!cgContext) { - cgContext = m_contextRef; - if (!cgContext) - return; - else { - m_usePixmap = true; - setNPWindowIfNeeded(); - } - } else - m_usePixmap = false; - - bool oldUsePixmap = m_usePixmap; - if (m_isTransparent && !m_usePixmap) { - if (m_pixmap.isNull()) - m_pixmap = QPixmap(frameRect().size()); - m_usePixmap = true; - setNPWindowIfNeeded(); - cgContext = qt_mac_cg_context(&m_pixmap); - } - - CGContextSaveGState(cgContext); - if (platformPluginWidget()) { - IntPoint offset = frameRect().location(); - CGContextTranslateCTM(cgContext, offset.x(), offset.y()); - } + CGContextSaveGState(m_contextRef); IntRect targetRect(frameRect()); targetRect.intersects(rect); @@ -586,56 +351,40 @@ void PluginView::paint(GraphicsContext* context, const IntRect& rect) r.origin.y = targetRect.y() - frameRect().y(); r.size.width = targetRect.width(); r.size.height = targetRect.height(); - CGContextClipToRect(cgContext, r); + CGContextClipToRect(m_contextRef, r); - if (!platformPluginWidget() || m_isTransparent) { // clean the pixmap in transparent mode -#if PLATFORM(QT) - QPainter painter(&m_pixmap); - painter.setCompositionMode(QPainter::CompositionMode_Clear); - painter.fillRect(QRectF(r.origin.x, r.origin.y, r.size.width, r.size.height), Qt::transparent); -#endif + if (m_isTransparent) { + // Clean the pixmap in transparent mode. + CGContextClearRect(m_contextRef, CGRectMake(r.origin.x, r.origin.y, r.size.width, r.size.height)); } -#ifndef NP_NO_CARBON - if (m_eventModel != NPEventModelCocoa) { - EventRecord event; - event.what = updateEvt; - event.message = (long unsigned int)m_npCgContext.window; - event.when = TickCount(); - event.where.h = 0; - event.where.v = 0; - event.modifiers = GetCurrentKeyModifiers(); - - if (!dispatchNPEvent(event)) - LOG(Events, "PluginView::paint(): Paint event not accepted"); - } else -#endif - { - NPCocoaEvent cocoaEvent; - initializeNPCocoaEvent(&cocoaEvent); - cocoaEvent.type = NPCocoaEventDrawRect; - cocoaEvent.data.draw.x = m_usePixmap ? 0 : r.origin.x; - cocoaEvent.data.draw.y = m_usePixmap ? 0 : r.origin.y; - cocoaEvent.data.draw.width = m_usePixmap ? m_pixmap.width() : r.size.width; - cocoaEvent.data.draw.height = m_usePixmap ? m_pixmap.height() : r.size.height; - cocoaEvent.data.draw.context = cgContext; - - if(!dispatchNPCocoaEvent(cocoaEvent)) - LOG(Events, "PluginView::paint(): Paint event type %d not accepted", cocoaEvent.type); - } + NPCocoaEvent cocoaEvent; + initializeNPCocoaEvent(&cocoaEvent); + cocoaEvent.type = NPCocoaEventDrawRect; + cocoaEvent.data.draw.x = 0; + cocoaEvent.data.draw.y = 0; + cocoaEvent.data.draw.width = CGBitmapContextGetWidth(m_contextRef); + cocoaEvent.data.draw.height = CGBitmapContextGetHeight(m_contextRef); + cocoaEvent.data.draw.context = m_contextRef; + + if(!dispatchNPCocoaEvent(cocoaEvent)) + LOG(Events, "PluginView::paint(): Paint event type %d not accepted", cocoaEvent.type); - if (!platformPluginWidget() || m_isTransparent) { #if PLATFORM(QT) - QPainter* painter = context->platformContext(); - painter->drawPixmap(targetRect.x(), targetRect.y(), m_pixmap, - targetRect.x() - frameRect().x(), targetRect.y() - frameRect().y(), targetRect.width(), targetRect.height()); + // Paint the intermediate bitmap into our graphics context. + ASSERT(CGBitmapContextGetBitmapInfo(m_contextRef) & (kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host)); + ASSERT(CGBitmapContextGetBitsPerPixel(m_contextRef) == 32); + const uint8_t* data = reinterpret_cast<const uint8_t*>(CGBitmapContextGetData(m_contextRef)); + size_t width = CGBitmapContextGetWidth(m_contextRef); + size_t height = CGBitmapContextGetHeight(m_contextRef); + const QImage imageFromBitmap(data, width, height, QImage::Format_ARGB32_Premultiplied); + + QPainter* painter = context->platformContext(); + painter->drawImage(targetRect.x(), targetRect.y(), imageFromBitmap, + targetRect.x() - frameRect().x(), targetRect.y() - frameRect().y(), targetRect.width(), targetRect.height()); #endif - } - CGContextRestoreGState(cgContext); - if (oldUsePixmap != m_usePixmap) { - m_usePixmap = oldUsePixmap; - m_pixmap = QPixmap(); - } + + CGContextRestoreGState(m_contextRef); } bool PluginView::popUpContextMenu(NPMenu *menu) @@ -654,12 +403,6 @@ bool PluginView::popUpContextMenu(NPMenu *menu) void PluginView::invalidateRect(const IntRect& rect) { - if (platformPluginWidget() && m_isTransparent) -#if PLATFORM(QT) - static_cast<QWidget*>(platformPluginWidget())->update(convertToContainingWindow(rect)); -#else - platformPluginWidget()->RefreshRect(convertToContainingWindow(rect)); -#endif invalidateWindowlessPluginRect(rect); } @@ -684,7 +427,7 @@ void PluginView::forceRedraw() // ----------------- Event handling -------------------- void PluginView::handleWheelEvent(WheelEvent *event) { - if (!m_isStarted || m_eventModel != NPEventModelCocoa) + if (!m_isStarted) return; NPCocoaEvent cocoaEvent; @@ -702,8 +445,8 @@ void PluginView::handleWheelEvent(WheelEvent *event) cocoaEvent.data.mouse.modifierFlags = getModifiers(event); if(!dispatchNPCocoaEvent(cocoaEvent)) { - LOG(Events, "PluginView::handleMouseEvent(): Wheel event type %d at %d,%d not accepted", cocoaEvent.type - cocoaEvent.data.mouse.x, cocoaEvent.data.mouse.y); + LOG(Events, "PluginView::handleMouseEvent(): Wheel event type %d at %d,%d not accepted", cocoaEvent.type, + cocoaEvent.data.mouse.pluginX, cocoaEvent.data.mouse.pluginY); } event->setDefaultHandled(); } @@ -713,125 +456,80 @@ void PluginView::handleMouseEvent(MouseEvent* event) if (!m_isStarted) return; -#ifndef NP_NO_CARBON - if (m_eventModel != NPEventModelCocoa) { - EventRecord record; - - if (event->type() == eventNames().mousemoveEvent) { - // Mouse movement is handled by null timer events - m_lastMousePos = mousePosForPlugin(event); - return; - } else if (event->type() == eventNames().mouseoverEvent) { - record.what = NPEventType_AdjustCursorEvent; - } else if (event->type() == eventNames().mouseoutEvent) { - record.what = NPEventType_AdjustCursorEvent; - } else if (event->type() == eventNames().mousedownEvent) { - record.what = mouseDown; + NPCocoaEventType eventType; + int32_t buttonNumber = 0; + int32_t clickCount = 0; + NSEvent *currentEvent = [NSApp currentEvent]; + + NSEventType type = [currentEvent type]; + + switch (type) { + case NSLeftMouseDown: + case NSRightMouseDown: + case NSOtherMouseDown: + buttonNumber = [currentEvent buttonNumber]; + clickCount = [currentEvent clickCount]; + eventType = NPCocoaEventMouseDown; // The plugin needs focus to receive keyboard events if (Page* page = m_parentFrame->page()) page->focusController()->setFocusedFrame(m_parentFrame); m_parentFrame->document()->setFocusedNode(m_element); - } else if (event->type() == eventNames().mouseupEvent) { - record.what = mouseUp; - } else { + break; + + case NSLeftMouseUp: + case NSRightMouseUp: + case NSOtherMouseUp: + buttonNumber = [currentEvent buttonNumber]; + clickCount = [currentEvent clickCount]; + eventType = NPCocoaEventMouseUp; + break; + + case NSMouseMoved: + eventType = NPCocoaEventMouseMoved; + break; + + case NSLeftMouseDragged: + case NSRightMouseDragged: + case NSOtherMouseDragged: + buttonNumber = [currentEvent buttonNumber]; + eventType = NPCocoaEventMouseDragged; + break; + + case NSMouseEntered: + eventType = NPCocoaEventMouseEntered; + break; + + case NSMouseExited: + eventType = NPCocoaEventMouseExited; + default: return; - } - record.where = mousePosForPlugin(event); - record.modifiers = modifiersForEvent(event); - - if (!event->buttonDown()) - record.modifiers |= btnState; - - if (event->button() == 2) - record.modifiers |= controlKey; - - if (!dispatchNPEvent(record)) { - if (record.what == NPEventType_AdjustCursorEvent) - return; // Signals that the plugin wants a normal cursor - - LOG(Events, "PluginView::handleMouseEvent(): Mouse event type %d at %d,%d not accepted", - record.what, record.where.h, record.where.v); - } else { - event->setDefaultHandled(); - } - } else -#endif - { - NPCocoaEventType eventType; - int32_t buttonNumber = 0; - int32_t clickCount = 0; - NSEvent *currentEvent = [NSApp currentEvent]; - - NSEventType type = [currentEvent type]; - - switch (type) { - case NSLeftMouseDown: - case NSRightMouseDown: - case NSOtherMouseDown: - buttonNumber = [currentEvent buttonNumber]; - clickCount = [currentEvent clickCount]; - eventType = NPCocoaEventMouseDown; - // The plugin needs focus to receive keyboard events - if (Page* page = m_parentFrame->page()) - page->focusController()->setFocusedFrame(m_parentFrame); - m_parentFrame->document()->setFocusedNode(m_element); - break; - - case NSLeftMouseUp: - case NSRightMouseUp: - case NSOtherMouseUp: - buttonNumber = [currentEvent buttonNumber]; - clickCount = [currentEvent clickCount]; - eventType = NPCocoaEventMouseUp; - break; - - case NSMouseMoved: - eventType = NPCocoaEventMouseMoved; - break; - - case NSLeftMouseDragged: - case NSRightMouseDragged: - case NSOtherMouseDragged: - buttonNumber = [currentEvent buttonNumber]; - eventType = NPCocoaEventMouseDragged; - break; - - case NSMouseEntered: - eventType = NPCocoaEventMouseEntered; - break; - - case NSMouseExited: - eventType = NPCocoaEventMouseExited; - default: - return; - } - - NPCocoaEvent cocoaEvent; - initializeNPCocoaEvent(&cocoaEvent); - - cocoaEvent.type = eventType; - if (!(NPCocoaEventMouseEntered == eventType || NPCocoaEventMouseExited == eventType)) { - cocoaEvent.data.mouse.buttonNumber = buttonNumber; - cocoaEvent.data.mouse.clickCount = clickCount; - } - - cocoaEvent.data.mouse.pluginX = event->layerX() - m_npWindow.x + m_windowRect.x() - m_element->offsetLeft(); - cocoaEvent.data.mouse.pluginY = event->layerY() - m_npWindow.y + m_windowRect.y() - m_element->offsetTop(); - cocoaEvent.data.mouse.deltaX = [currentEvent deltaX]; - cocoaEvent.data.mouse.deltaY = [currentEvent deltaY]; - cocoaEvent.data.mouse.deltaZ = [currentEvent deltaZ]; - cocoaEvent.data.mouse.modifierFlags = getModifiers(event); - - int16_t response = dispatchNPCocoaEvent(cocoaEvent); - if(response = kNPEventNotHandled) { - LOG(Events, "PluginView::handleMouseEvent(): Mouse event type %d at %d,%d not accepted", cocoaEvent.type - cocoaEvent.data.mouse.x, cocoaEvent.data.mouse.y); - } - - // Safari policy is to return true for all mouse events, because some plugins - // return false even if they have handled the event. - event->setDefaultHandled(); } + + NPCocoaEvent cocoaEvent; + initializeNPCocoaEvent(&cocoaEvent); + + cocoaEvent.type = eventType; + if (!(NPCocoaEventMouseEntered == eventType || NPCocoaEventMouseExited == eventType)) { + cocoaEvent.data.mouse.buttonNumber = buttonNumber; + cocoaEvent.data.mouse.clickCount = clickCount; + } + + cocoaEvent.data.mouse.pluginX = event->layerX() - m_npWindow.x + m_windowRect.x() - m_element->offsetLeft(); + cocoaEvent.data.mouse.pluginY = event->layerY() - m_npWindow.y + m_windowRect.y() - m_element->offsetTop(); + cocoaEvent.data.mouse.deltaX = [currentEvent deltaX]; + cocoaEvent.data.mouse.deltaY = [currentEvent deltaY]; + cocoaEvent.data.mouse.deltaZ = [currentEvent deltaZ]; + cocoaEvent.data.mouse.modifierFlags = getModifiers(event); + + int16_t response = dispatchNPCocoaEvent(cocoaEvent); + if(response == kNPEventNotHandled) { + LOG(Events, "PluginView::handleMouseEvent(): Mouse event type %d at %d,%d not accepted", cocoaEvent.type, + cocoaEvent.data.mouse.pluginX, cocoaEvent.data.mouse.pluginY); + } + + // Safari policy is to return true for all mouse events, because some plugins + // return false even if they have handled the event. + event->setDefaultHandled(); } void PluginView::handleKeyboardEvent(KeyboardEvent* event) @@ -839,238 +537,74 @@ void PluginView::handleKeyboardEvent(KeyboardEvent* event) if (!m_isStarted) return; LOG(Plugins, "PluginView::handleKeyboardEvent() ----------------- "); - + LOG(Plugins, "PV::hKE(): KE.keyCode: 0x%02X, KE.charCode: %d", event->keyCode(), event->charCode()); - -#ifndef NP_NO_CARBON - if (m_eventModel != NPEventModelCocoa) { - EventRecord record; - if (event->type() == eventNames().keydownEvent) { - // This event is the result of a PlatformKeyboardEvent::KeyDown which - // was disambiguated into a PlatformKeyboardEvent::RawKeyDown. Since - // we don't have access to the text here, we return, and wait for the - // corresponding event based on PlatformKeyboardEvent::Char. - return; - } else if (event->type() == eventNames().keypressEvent) { - // Which would be this one. This event was disambiguated from the same - // PlatformKeyboardEvent::KeyDown, but to a PlatformKeyboardEvent::Char, - // which retains the text from the original event. So, we can safely pass - // on the event as a key-down event to the plugin. - record.what = keyDown; - } else if (event->type() == eventNames().keyupEvent) { - // PlatformKeyboardEvent::KeyUp events always have the text, so nothing - // fancy here. - record.what = keyUp; - } else { - return; - } - - const PlatformKeyboardEvent* platformEvent = event->keyEvent(); - int keyCode = platformEvent->nativeVirtualKeyCode(); - - const String text = platformEvent->text(); - if (text.length() < 1) { - event->setDefaultHandled(); - return; - } - - WTF::RetainPtr<CFStringRef> cfText(WTF::AdoptCF, text.createCFString()); - - LOG(Plugins, "PV::hKE(): PKE.text: %s, PKE.unmodifiedText: %s, PKE.keyIdentifier: %s", - text.ascii().data(), platformEvent->unmodifiedText().ascii().data(), - platformEvent->keyIdentifier().ascii().data()); - - char charCodes[2] = { 0, 0 }; - if (!CFStringGetCString(cfText.get(), charCodes, 2, CFStringGetSystemEncoding())) { - LOG_ERROR("Could not resolve character code using system encoding."); - event->setDefaultHandled(); - return; - } - - record.where = globalMousePosForPlugin(); - record.modifiers = modifiersForEvent(event); - record.message = ((keyCode & 0xFF) << 8) | (charCodes[0] & 0xFF); - record.when = TickCount(); - - LOG(Plugins, "PV::hKE(): record.modifiers: %d", record.modifiers); - -#if PLATFORM(QT) - LOG(Plugins, "PV::hKE(): PKE.qtEvent()->nativeVirtualKey: 0x%02X, charCode: %d", - keyCode, int(uchar(charCodes[0]))); -#endif - - if (!dispatchNPEvent(record)) - LOG(Events, "PluginView::handleKeyboardEvent(): Keyboard event type %d not accepted", record.what); - else - event->setDefaultHandled(); - } else -#endif - { - NSEvent *currentEvent = [NSApp currentEvent]; - NPCocoaEventType eventType; - NSEventType type = [currentEvent type]; - - switch (type) { - case NSKeyDown: - eventType = NPCocoaEventKeyDown; - m_keyDownSent = true; - break; - case NSKeyUp: - if (m_disregardKeyUpCounter > 0) { - m_disregardKeyUpCounter--; - event->setDefaultHandled(); - return; - } - eventType = NPCocoaEventKeyUp; - break; - case NSFlagsChanged: - eventType = NPCocoaEventFlagsChanged; - break; - default: - return; - } - - NPCocoaEvent cocoaEvent; - initializeNPCocoaEvent(&cocoaEvent); - cocoaEvent.type = eventType; - if (eventType != NPCocoaEventFlagsChanged) { - NSString *characters = [currentEvent characters]; - NSString *charactersIgnoringModifiers = [currentEvent charactersIgnoringModifiers]; - cocoaEvent.data.key.characters = reinterpret_cast<NPNSString*>(characters); - cocoaEvent.data.key.charactersIgnoringModifiers = reinterpret_cast<NPNSString*>(charactersIgnoringModifiers); - cocoaEvent.data.key.isARepeat = [currentEvent isARepeat]; - cocoaEvent.data.key.keyCode = [currentEvent keyCode]; - cocoaEvent.data.key.modifierFlags = getModifiers(event); - } - - int16_t response = dispatchNPCocoaEvent(cocoaEvent); - if(response == kNPEventNotHandled) { - LOG(Events, "PluginView::handleKeyboardEvent(): Keyboard event type %d not accepted", cocoaEvent.type); - } else if (response == kNPEventStartIME) { - // increment counter and resend as a text input - m_disregardKeyUpCounter++; - NPCocoaEvent textEvent; - initializeNPCocoaEvent(&textEvent); - textEvent.type = NPCocoaEventTextInput; - textEvent.data.text.text = reinterpret_cast<NPNSString*>([currentEvent characters]); - response = dispatchNPCocoaEvent(textEvent); - if(response == kNPEventNotHandled) - LOG(Events, "PluginView::handleKeyboardEvent(): Keyboard event type %d not accepted", cocoaEvent.type); - } - - // All keyboard events need to be handled to prevent them falling - // through to the page, unless they are Meta key events, in which - // case they are, unless they are Cmd+a. From WebKit2, possibly - // not the most elegant piece of key handling code..... - if (event->metaKey()) { - if (cocoaEvent.data.key.keyCode == 0) + + NSEvent *currentEvent = [NSApp currentEvent]; + NPCocoaEventType eventType; + NSEventType type = [currentEvent type]; + + switch (type) { + case NSKeyDown: + eventType = NPCocoaEventKeyDown; + m_keyDownSent = true; + break; + case NSKeyUp: + if (m_disregardKeyUpCounter > 0) { + m_disregardKeyUpCounter--; event->setDefaultHandled(); - } else { - // else ignore, it's a Meta Key event for the browser. - event->setDefaultHandled(); - } + return; + } + eventType = NPCocoaEventKeyUp; + break; + case NSFlagsChanged: + eventType = NPCocoaEventFlagsChanged; + break; + default: + return; } -} - -#ifndef NP_NO_CARBON -void PluginView::nullEventTimerFired(Timer<PluginView>*) -{ - EventRecord record; - - record.what = nullEvent; - record.message = 0; - record.when = TickCount(); - record.where = m_lastMousePos; - record.modifiers = GetCurrentKeyModifiers(); - if (!Button()) - record.modifiers |= btnState; - - if (!dispatchNPEvent(record)) - LOG(Events, "PluginView::nullEventTimerFired(): Null event not accepted"); -} -#endif - -#ifndef NP_NO_CARBON -static int modifiersForEvent(UIEventWithKeyState* event) -{ - int modifiers = 0; - - if (event->ctrlKey()) - modifiers |= controlKey; - - if (event->altKey()) - modifiers |= optionKey; - - if (event->metaKey()) - modifiers |= cmdKey; - - if (event->shiftKey()) - modifiers |= shiftKey; - - return modifiers; -} -#endif - -#ifndef NP_NO_CARBON -Point PluginView::globalMousePosForPlugin() const -{ - Point pos; - GetGlobalMouse(&pos); - -#if PLATFORM(WX) - // make sure the titlebar/toolbar size is included - WindowRef windowRef = nativeWindowFor(platformPluginWidget()); - ::Rect content, structure; - - GetWindowBounds(windowRef, kWindowStructureRgn, &structure); - GetWindowBounds(windowRef, kWindowContentRgn, &content); - int top = content.top - structure.top; - pos.v -= top; -#endif - - return pos; -} -#endif - -#ifndef NP_NO_CARBON -Point PluginView::mousePosForPlugin(MouseEvent* event) const -{ - ASSERT(event); - if (platformPluginWidget()) - return globalMousePosForPlugin(); - - if (event->button() == 2) { - // always pass the global position for right-click since Flash uses it to position the context menu - return globalMousePosForPlugin(); + NPCocoaEvent cocoaEvent; + initializeNPCocoaEvent(&cocoaEvent); + cocoaEvent.type = eventType; + if (eventType != NPCocoaEventFlagsChanged) { + NSString *characters = [currentEvent characters]; + NSString *charactersIgnoringModifiers = [currentEvent charactersIgnoringModifiers]; + cocoaEvent.data.key.characters = reinterpret_cast<NPNSString*>(characters); + cocoaEvent.data.key.charactersIgnoringModifiers = reinterpret_cast<NPNSString*>(charactersIgnoringModifiers); + cocoaEvent.data.key.isARepeat = [currentEvent isARepeat]; + cocoaEvent.data.key.keyCode = [currentEvent keyCode]; + cocoaEvent.data.key.modifierFlags = getModifiers(event); } - Point pos; - IntPoint postZoomPos = roundedIntPoint(m_element->renderer()->absoluteToLocal(event->absoluteLocation())); - pos.h = postZoomPos.x() + m_windowRect.x(); - // The number 22 is the height of the title bar. As to why it figures in the calculation below - // is left as an exercise to the reader :-) - pos.v = postZoomPos.y() + m_windowRect.y() - 22; - return pos; -} -#endif - -#ifndef NP_NO_CARBON -bool PluginView::dispatchNPEvent(NPEvent& event) -{ - PluginView::setCurrentPluginView(this); - JSC::JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonJSGlobalData()); - setCallingPlugin(true); - - bool accepted = m_plugin->pluginFuncs()->event(m_instance, &event); + int16_t response = dispatchNPCocoaEvent(cocoaEvent); + if(response == kNPEventNotHandled) { + LOG(Events, "PluginView::handleKeyboardEvent(): Keyboard event type %d not accepted", cocoaEvent.type); + } else if (response == kNPEventStartIME) { + // increment counter and resend as a text input + m_disregardKeyUpCounter++; + NPCocoaEvent textEvent; + initializeNPCocoaEvent(&textEvent); + textEvent.type = NPCocoaEventTextInput; + textEvent.data.text.text = reinterpret_cast<NPNSString*>([currentEvent characters]); + response = dispatchNPCocoaEvent(textEvent); + if(response == kNPEventNotHandled) + LOG(Events, "PluginView::handleKeyboardEvent(): Keyboard event type %d not accepted", cocoaEvent.type); + } - setCallingPlugin(false); - PluginView::setCurrentPluginView(0); - return accepted; + // All keyboard events need to be handled to prevent them falling + // through to the page, unless they are Meta key events, in which + // case they are, unless they are Cmd+a. From WebKit2, possibly + // not the most elegant piece of key handling code..... + if (event->metaKey()) { + if (cocoaEvent.data.key.keyCode == 0) + event->setDefaultHandled(); + } else { + // else ignore, it's a Meta Key event for the browser. + event->setDefaultHandled(); + } } -#endif - int16_t PluginView::dispatchNPCocoaEvent(NPCocoaEvent& cocoaEvent) { diff --git a/Source/WebCore/plugins/win/PluginViewWin.cpp b/Source/WebCore/plugins/win/PluginViewWin.cpp index bd14cd948..7160d8a99 100644 --- a/Source/WebCore/plugins/win/PluginViewWin.cpp +++ b/Source/WebCore/plugins/win/PluginViewWin.cpp @@ -357,6 +357,29 @@ static bool isWindowsMessageUserGesture(UINT message) } } +static inline IntPoint contentsToNativeWindow(FrameView* view, const IntPoint& point) +{ +#if PLATFORM(QT) + // Our web view's QWidget isn't necessarily a native window itself. Map the position + // all the way up to the QWidget associated with the HWND returned as NPNVnetscapeWindow. + PlatformPageClient client = view->hostWindow()->platformPageClient(); + return client->mapToOwnerWindow(view->contentsToWindow(point)); +#else + return view->contentsToWindow(point); +#endif +} + +static inline IntRect contentsToNativeWindow(FrameView* view, const IntRect& rect) +{ +#if PLATFORM(QT) + // This only handles translation of the rect. + ASSERT(view->contentsToWindow(rect).size() == rect.size()); + return IntRect(contentsToNativeWindow(view, rect.location()), rect.size()); +#else + return view->contentsToWindow(rect); +#endif +} + LRESULT PluginView::wndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { @@ -553,7 +576,7 @@ void PluginView::paintIntoTransformedContext(HDC hdc) WINDOWPOS windowpos = { 0, 0, 0, 0, 0, 0, 0 }; - IntRect r = static_cast<FrameView*>(parent())->contentsToWindow(frameRect()); + IntRect r = contentsToNativeWindow(static_cast<FrameView*>(parent()), frameRect()); windowpos.x = r.x(); windowpos.y = r.y(); @@ -702,7 +725,7 @@ void PluginView::handleMouseEvent(MouseEvent* event) NPEvent npEvent; - IntPoint p = static_cast<FrameView*>(parent())->contentsToWindow(IntPoint(event->pageX(), event->pageY())); + IntPoint p = contentsToNativeWindow(static_cast<FrameView*>(parent()), IntPoint(event->pageX(), event->pageY())); npEvent.lParam = MAKELPARAM(p.x(), p.y()); npEvent.wParam = 0; diff --git a/Source/WebKit/qt/WebCoreSupport/ChromeClientQt.cpp b/Source/WebKit/qt/WebCoreSupport/ChromeClientQt.cpp index 58dad5b76..ae3fef43e 100644 --- a/Source/WebKit/qt/WebCoreSupport/ChromeClientQt.cpp +++ b/Source/WebKit/qt/WebCoreSupport/ChromeClientQt.cpp @@ -405,7 +405,7 @@ IntRect ChromeClientQt::windowResizerRect() const // always draw scrollbars on the right hand side, so we assume this to be the // location when computing the resize rect to reserve for WebKit. QPoint resizeCornerTopLeft = QPoint(topLevelGeometry.width(), topLevelGeometry.height()) - - QPoint(scollbarThickness, scollbarThickness)) + - QPoint(scollbarThickness, scollbarThickness) - m_webPage->viewRectRelativeToWindow().topLeft(); QRect resizeCornerRect = QRect(resizeCornerTopLeft, QSize(scollbarThickness, scollbarThickness)); diff --git a/Source/WebKit/qt/WidgetSupport/PageClientQt.cpp b/Source/WebKit/qt/WidgetSupport/PageClientQt.cpp index 095f9e582..8f486d594 100644 --- a/Source/WebKit/qt/WidgetSupport/PageClientQt.cpp +++ b/Source/WebKit/qt/WidgetSupport/PageClientQt.cpp @@ -120,6 +120,16 @@ QRect PageClientQWidget::geometryRelativeToOwnerWidget() const return view->geometry(); } +QPoint PageClientQWidget::mapToOwnerWindow(const QPoint& point) const +{ + QWidget* widget = qobject_cast<QWidget*>(ownerWidget()); + // Can be false both if ownerWidget() is native or if it doesn't have any native parent. + if (const QWidget *nativeParent = widget->nativeParentWidget()) + return widget->mapTo(nativeParent, point); + + return point; +} + QObject* PageClientQWidget::pluginParent() const { return view; @@ -170,7 +180,7 @@ void PageClientQGraphicsWidget::repaintViewport() bool PageClientQGraphicsWidget::makeOpenGLContextCurrentIfAvailable() { #if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER_GL) && defined(QT_OPENGL_LIB) - QGraphicsView* graphicsView = view->scene()->views()[0]; + QGraphicsView* graphicsView = firstGraphicsView(); if (graphicsView && graphicsView->viewport()) { QGLWidget* glWidget = qobject_cast<QGLWidget*>(graphicsView->viewport()); if (glWidget) { @@ -218,14 +228,9 @@ QPalette PageClientQGraphicsWidget::palette() const int PageClientQGraphicsWidget::screenNumber() const { #if defined(Q_WS_X11) - if (QGraphicsScene* scene = view->scene()) { - const QList<QGraphicsView*> views = scene->views(); - - if (!views.isEmpty()) - return views.at(0)->x11Info().screen(); - } + if (QGraphicsView* graphicsView = firstGraphicsView()) + return graphicsView->x11Info().screen(); #endif - return 0; } @@ -240,28 +245,26 @@ QObject* PageClientQGraphicsWidget::ownerWidget() const QRect PageClientQGraphicsWidget::geometryRelativeToOwnerWidget() const { - if (!view->scene()) - return QRect(); - - QList<QGraphicsView*> views = view->scene()->views(); - if (views.isEmpty()) - return QRect(); + if (QGraphicsView* graphicsView = firstGraphicsView()) + return graphicsView->mapFromScene(view->boundingRect()).boundingRect(); + return QRect(); +} - QGraphicsView* graphicsView = views.at(0); - return graphicsView->mapFromScene(view->boundingRect()).boundingRect(); +QPoint PageClientQGraphicsWidget::mapToOwnerWindow(const QPoint& point) const +{ + if (const QGraphicsView* graphicsView = firstGraphicsView()) + if (const QWidget *nativeParent = graphicsView->nativeParentWidget()) + return graphicsView->mapTo(nativeParent, graphicsView->mapFromScene(view->mapToScene(point))); + return point; } #if USE(TILED_BACKING_STORE) QRectF PageClientQGraphicsWidget::graphicsItemVisibleRect() const { - if (!view->scene()) + QGraphicsView* graphicsView = firstGraphicsView(); + if (!graphicsView) return QRectF(); - QList<QGraphicsView*> views = view->scene()->views(); - if (views.isEmpty()) - return QRectF(); - - QGraphicsView* graphicsView = views.at(0); int xOffset = graphicsView->horizontalScrollBar()->value(); int yOffset = graphicsView->verticalScrollBar()->value(); return view->mapRectFromScene(QRectF(QPointF(xOffset, yOffset), graphicsView->viewport()->size())); @@ -291,6 +294,13 @@ QRectF PageClientQGraphicsWidget::windowRect() const // The sceneRect is a good approximation of the size of the application, independent of the view. return view->scene()->sceneRect(); } + +QGraphicsView* PageClientQGraphicsWidget::firstGraphicsView() const +{ + if (view->scene() && !view->scene()->views().isEmpty()) + return view->scene()->views().first(); + return 0; +} #endif // QT_NO_GRAPHICSVIEW } // namespace WebCore diff --git a/Source/WebKit/qt/WidgetSupport/PageClientQt.h b/Source/WebKit/qt/WidgetSupport/PageClientQt.h index 63a80ad03..e9da360bc 100644 --- a/Source/WebKit/qt/WidgetSupport/PageClientQt.h +++ b/Source/WebKit/qt/WidgetSupport/PageClientQt.h @@ -72,6 +72,7 @@ public: virtual int screenNumber() const; virtual QObject* ownerWidget() const; virtual QRect geometryRelativeToOwnerWidget() const; + virtual QPoint mapToOwnerWindow(const QPoint&) const; virtual QObject* pluginParent() const; @@ -158,6 +159,7 @@ public: virtual int screenNumber() const; virtual QObject* ownerWidget() const; virtual QRect geometryRelativeToOwnerWidget() const; + virtual QPoint mapToOwnerWindow(const QPoint&) const; virtual QObject* pluginParent() const; @@ -175,6 +177,8 @@ public: virtual QRectF windowRect() const; + QGraphicsView* firstGraphicsView() const; + QGraphicsWebView* view; QWebPage* page; bool viewResizesToContents; diff --git a/Source/WebKit/qt/declarative/plugins.qmltypes b/Source/WebKit/qt/declarative/plugins.qmltypes new file mode 100644 index 000000000..9532916b9 --- /dev/null +++ b/Source/WebKit/qt/declarative/plugins.qmltypes @@ -0,0 +1,199 @@ +import QtQuick.tooling 1.1 + +// This file describes the plugin-supplied types contained in the library. +// It is used for QML tooling purposes only. +// +// This file was auto-generated with the command 'qmlplugindump -noinstantiate -nonrelocatable QtWebKit 3.0'. + +Module { + Component { + name: "QIODevice" + prototype: "QObject" + Signal { name: "readyRead" } + Signal { + name: "bytesWritten" + Parameter { name: "bytes"; type: "qlonglong" } + } + Signal { name: "aboutToClose" } + Signal { name: "readChannelFinished" } + } + Component { + name: "QNetworkReply" + prototype: "QIODevice" + exports: ["QtWebKit/NetworkReply 3.0"] + exportMetaObjectRevisions: [0] + Enum { + name: "NetworkError" + values: { + "NoError": 0, + "ConnectionRefusedError": 1, + "RemoteHostClosedError": 2, + "HostNotFoundError": 3, + "TimeoutError": 4, + "OperationCanceledError": 5, + "SslHandshakeFailedError": 6, + "TemporaryNetworkFailureError": 7, + "NetworkSessionFailedError": 8, + "BackgroundRequestNotAllowedError": 9, + "UnknownNetworkError": 99, + "ProxyConnectionRefusedError": 101, + "ProxyConnectionClosedError": 102, + "ProxyNotFoundError": 103, + "ProxyTimeoutError": 104, + "ProxyAuthenticationRequiredError": 105, + "UnknownProxyError": 199, + "ContentAccessDenied": 201, + "ContentOperationNotPermittedError": 202, + "ContentNotFoundError": 203, + "AuthenticationRequiredError": 204, + "ContentReSendError": 205, + "UnknownContentError": 299, + "ProtocolUnknownError": 301, + "ProtocolInvalidOperationError": 302, + "ProtocolFailure": 399 + } + } + Signal { name: "metaDataChanged" } + Signal { name: "finished" } + Signal { + name: "error" + Parameter { type: "QNetworkReply::NetworkError" } + } + Signal { name: "encrypted" } + Signal { + name: "sslErrors" + Parameter { name: "errors"; type: "QList<QSslError>" } + } + Signal { + name: "uploadProgress" + Parameter { name: "bytesSent"; type: "qlonglong" } + Parameter { name: "bytesTotal"; type: "qlonglong" } + } + Signal { + name: "downloadProgress" + Parameter { name: "bytesReceived"; type: "qlonglong" } + Parameter { name: "bytesTotal"; type: "qlonglong" } + } + Method { name: "abort" } + Method { name: "ignoreSslErrors" } + } + Component { + name: "QQuickWebPage" + defaultProperty: "data" + prototype: "QQuickItem" + exports: ["QtWebKit/WebPage 3.0"] + exportMetaObjectRevisions: [0] + } + Component { + name: "QQuickWebView" + defaultProperty: "flickableData" + prototype: "QQuickFlickable" + exports: ["QtWebKit/WebView 3.0"] + exportMetaObjectRevisions: [0] + attachedType: "QQuickWebViewAttached" + Enum { + name: "NavigationRequestAction" + values: { + "AcceptRequest": 0, + "IgnoreRequest": 255 + } + } + Enum { + name: "LoadStatus" + values: { + "LoadStartedStatus": 0, + "LoadStoppedStatus": 1, + "LoadSucceededStatus": 2, + "LoadFailedStatus": 3 + } + } + Enum { + name: "ErrorDomain" + values: { + "NoErrorDomain": 0, + "InternalErrorDomain": 1, + "NetworkErrorDomain": 2, + "HttpErrorDomain": 3, + "DownloadErrorDomain": 4 + } + } + Enum { + name: "NavigationType" + values: { + "LinkClickedNavigation": 0, + "FormSubmittedNavigation": 1, + "BackForwardNavigation": 2, + "ReloadNavigation": 3, + "FormResubmittedNavigation": 4, + "OtherNavigation": 5 + } + } + Property { name: "title"; type: "string"; isReadonly: true } + Property { name: "url"; type: "QUrl" } + Property { name: "icon"; type: "QUrl"; isReadonly: true } + Property { name: "canGoBack"; type: "bool"; isReadonly: true } + Property { name: "canGoForward"; type: "bool"; isReadonly: true } + Property { name: "loading"; type: "bool"; isReadonly: true } + Property { name: "loadProgress"; type: "int"; isReadonly: true } + Signal { name: "navigationHistoryChanged" } + Signal { + name: "loadingChanged" + Parameter { name: "loadRequest"; type: "QWebLoadRequest"; isPointer: true } + } + Signal { + name: "linkHovered" + Parameter { name: "hoveredUrl"; type: "QUrl" } + Parameter { name: "hoveredTitle"; type: "string" } + } + Signal { + name: "navigationRequested" + Parameter { name: "request"; type: "QWebNavigationRequest"; isPointer: true } + } + Method { + name: "loadHtml" + Parameter { name: "html"; type: "string" } + Parameter { name: "baseUrl"; type: "QUrl" } + Parameter { name: "unreachableUrl"; type: "QUrl" } + } + Method { + name: "loadHtml" + Parameter { name: "html"; type: "string" } + Parameter { name: "baseUrl"; type: "QUrl" } + } + Method { + name: "loadHtml" + Parameter { name: "html"; type: "string" } + } + Method { name: "goBack" } + Method { name: "goForward" } + Method { name: "stop" } + Method { name: "reload" } + } + Component { + name: "QQuickWebViewAttached" + prototype: "QObject" + Property { name: "view"; type: "QQuickWebView"; isReadonly: true; isPointer: true } + } + Component { + name: "QWebLoadRequest" + prototype: "QObject" + exports: ["QtWebKit/WebLoadRequest 3.0"] + exportMetaObjectRevisions: [0] + Property { name: "url"; type: "QUrl"; isReadonly: true } + Property { name: "status"; type: "QQuickWebView::LoadStatus"; isReadonly: true } + Property { name: "errorString"; type: "string"; isReadonly: true } + Property { name: "errorDomain"; type: "QQuickWebView::ErrorDomain"; isReadonly: true } + Property { name: "errorCode"; type: "int"; isReadonly: true } + } + Component { + name: "QWebNavigationRequest" + prototype: "QObject" + exports: ["QtWebKit/NavigationRequest 3.0"] + exportMetaObjectRevisions: [0] + Property { name: "url"; type: "QUrl"; isReadonly: true } + Property { name: "mouseButton"; type: "int"; isReadonly: true } + Property { name: "keyboardModifiers"; type: "int"; isReadonly: true } + Property { name: "action"; type: "QQuickWebView::NavigationRequestAction" } + Property { name: "navigationType"; type: "QQuickWebView::NavigationType"; isReadonly: true } + } +} diff --git a/Source/WebKit/qt/declarative/qmldir b/Source/WebKit/qt/declarative/qmldir index b9c5d05dc..962e92f06 100644 --- a/Source/WebKit/qt/declarative/qmldir +++ b/Source/WebKit/qt/declarative/qmldir @@ -1,2 +1,3 @@ module QtWebKit plugin qmlwebkitplugin +typeinfo plugins.qmltypes diff --git a/Source/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp b/Source/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp index fbba56d6c..e5abf6b79 100644 --- a/Source/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp +++ b/Source/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp @@ -38,6 +38,7 @@ #include <qgraphicsview.h> #include <qgraphicswebview.h> #include <qnetworkcookiejar.h> +#include <qnetworkreply.h> #include <qnetworkrequest.h> #include <qpa/qplatforminputcontext.h> #include <qwebdatabase.h> @@ -173,6 +174,8 @@ private Q_SLOTS: #endif void originatingObjectInNetworkRequests(); + void networkReplyParentDidntChange(); + void destroyQNAMBeforeAbortDoesntCrash(); void testJSPrompt(); void showModalDialog(); void testStopScheduledPageRefresh(); @@ -2846,6 +2849,32 @@ void tst_QWebPage::originatingObjectInNetworkRequests() QVERIFY(qobject_cast<QWebFrame*>(networkManager->requests.at(i).originatingObject()) == childFrames.at(i)); } +void tst_QWebPage::networkReplyParentDidntChange() +{ + TestNetworkManager* networkManager = new TestNetworkManager(m_page); + m_page->setNetworkAccessManager(networkManager); + networkManager->requests.clear(); + + // Trigger a load and check that pending QNetworkReplies haven't been reparented before returning to the event loop. + m_view->load(QUrl("qrc:///resources/content.html")); + + QVERIFY(networkManager->requests.count() > 0); + QVERIFY(networkManager->findChildren<QNetworkReply*>().size() > 0); +} + +void tst_QWebPage::destroyQNAMBeforeAbortDoesntCrash() +{ + QNetworkAccessManager* networkManager = new QNetworkAccessManager; + m_page->setNetworkAccessManager(networkManager); + + m_view->load(QUrl("qrc:///resources/content.html")); + delete networkManager; + // This simulates what PingLoader does with its QNetworkReply when it times out. + // PingLoader isn't attached to a QWebPage and can be kept alive + // for 60000 seconds (~16.7 hours) to then cancel its ResourceHandle. + m_view->stop(); +} + /** * Test fixups for https://bugs.webkit.org/show_bug.cgi?id=30914 * diff --git a/Tools/DumpRenderTree/qt/TestNetscapePlugin/TestNetscapePlugin.pro b/Tools/DumpRenderTree/qt/TestNetscapePlugin/TestNetscapePlugin.pro index f962ee18b..ae45c0331 100644 --- a/Tools/DumpRenderTree/qt/TestNetscapePlugin/TestNetscapePlugin.pro +++ b/Tools/DumpRenderTree/qt/TestNetscapePlugin/TestNetscapePlugin.pro @@ -55,7 +55,7 @@ mac { LIBS += -framework Carbon -framework Cocoa -framework QuartzCore } -!win32:!embedded:!mac { +!win32:!mac { LIBS += -lX11 DEFINES += XP_UNIX } diff --git a/Tools/qmake/mkspecs/features/features.prf b/Tools/qmake/mkspecs/features/features.prf index cf6dc7fac..ddbccf984 100644 --- a/Tools/qmake/mkspecs/features/features.prf +++ b/Tools/qmake/mkspecs/features/features.prf @@ -71,7 +71,7 @@ defineTest(detectFeatures) { plugin_architecture_x11 \ plugin_process - } else: unix|win32-*:!embedded:!wince* { + } else: mac|win32 { WEBKIT_CONFIG += netscape_plugin_api # WebKit2 WEBKIT_CONFIG += plugin_architecture_unsupported @@ -100,28 +100,18 @@ defineTest(detectFeatures) { # Orientation support haveQtModule(sensors): WEBKIT_CONFIG += orientation_events device_orientation - # HTML5 Media Support - mac { - QMAKE_MAC_SDK_VERSION = $$system("xcodebuild -sdk $$QMAKE_MAC_SDK -version SDKVersion 2>/dev/null") - haveQt(5,1):!equals(QMAKE_MACOSX_DEPLOYMENT_TARGET, $$QMAKE_MAC_SDK_VERSION) { - CONFIGURE_WARNINGS += "Deployment target ($$QMAKE_MACOSX_DEPLOYMENT_TARGET) doesn't match SDK ($$QMAKE_MAC_SDK_VERSION), disabling media element support" - } else { - DARWIN_VERSION = $$split(QMAKE_HOST.version, ".") - DARWIN_MAJOR_VERSION = $$first(DARWIN_VERSION) - # QTKIT support requires 10.7 or newer - greaterThan(DARWIN_MAJOR_VERSION, 10) { - WEBKIT_CONFIG += video use_qtkit + # HTML5 Media Support for non-Mac builds + !mac { + !contains(QT_CONFIG, no-pkg-config) { + packagesExist("glib-2.0 gio-2.0 gstreamer-1.0 gstreamer-plugins-base-1.0") { + WEBKIT_CONFIG += video use_gstreamer + } else: packagesExist("glib-2.0 gio-2.0 \'gstreamer-0.10 >= 0.10.30\' \'gstreamer-plugins-base-0.10 >= 0.10.30\'") { + WEBKIT_CONFIG += video use_gstreamer use_gstreamer010 } } - } else: linux-* { - !contains(QT_CONFIG, no-pkg-config):packagesExist("glib-2.0 gio-2.0 gstreamer-1.0 gstreamer-plugins-base-1.0") { - WEBKIT_CONFIG += video use_gstreamer - } else:!contains(QT_CONFIG, no-pkg-config):packagesExist("glib-2.0 gio-2.0 \'gstreamer-0.10 >= 0.10.30\' \'gstreamer-plugins-base-0.10 >= 0.10.30\'") { - WEBKIT_CONFIG += video use_gstreamer use_gstreamer010 - } else { - CONFIGURE_WARNINGS += "Missing GLib/Gio/GStreamer, disabling media element support" - } - } else: haveQtModule(multimediawidgets) { + } + + !enable?(video):haveQtModule(multimediawidgets) { WEBKIT_CONFIG += video use_qt_multimedia } diff --git a/Tools/qmake/mkspecs/features/unix/default_pre.prf b/Tools/qmake/mkspecs/features/unix/default_pre.prf index aafc48ceb..60de13338 100644 --- a/Tools/qmake/mkspecs/features/unix/default_pre.prf +++ b/Tools/qmake/mkspecs/features/unix/default_pre.prf @@ -12,10 +12,6 @@ CONFIG += object_parallel_to_source SBOX_CHECK = $$(_SBOX_DIR) !isEmpty(SBOX_CHECK): CONFIG += scratchbox -# If Qt is configured with embedded or QPA we set a convenience config -# flag that can be used to test for either of these situations. -contains(QT_CONFIG, qpa)|contains(QT_CONFIG, embedded): CONFIG += embedded - # Reduce linking memory pressure on 32-bit debug builds on Linux linux-g++*:CONFIG(debug, debug|release):isEqual(QT_ARCH,i386): CONFIG += use_all_in_one_files |