diff options
author | Feng Qian <> | 2009-04-10 18:11:29 -0700 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-04-10 18:11:29 -0700 |
commit | 8f72e70a9fd78eec56623b3a62e68f16b7b27e28 (patch) | |
tree | 181bf9a400c30a1bf34ea6d72560e8d00111d549 /WebCore/platform/graphics/win | |
parent | 7ed56f225e0ade046e1c2178977f72b2d896f196 (diff) | |
download | external_webkit-8f72e70a9fd78eec56623b3a62e68f16b7b27e28.zip external_webkit-8f72e70a9fd78eec56623b3a62e68f16b7b27e28.tar.gz external_webkit-8f72e70a9fd78eec56623b3a62e68f16b7b27e28.tar.bz2 |
AI 145796: Land the WebKit merge @r42026.
Automated import of CL 145796
Diffstat (limited to 'WebCore/platform/graphics/win')
13 files changed, 179 insertions, 573 deletions
diff --git a/WebCore/platform/graphics/win/FontCGWin.cpp b/WebCore/platform/graphics/win/FontCGWin.cpp index 9ca95f3..feeb2ae 100644 --- a/WebCore/platform/graphics/win/FontCGWin.cpp +++ b/WebCore/platform/graphics/win/FontCGWin.cpp @@ -223,8 +223,6 @@ static void drawGDIGlyphs(GraphicsContext* graphicsContext, const SimpleFontData ExtTextOut(hdc, 0, 0, ETO_GLYPH_INDEX, 0, reinterpret_cast<const WCHAR*>(glyphBuffer.glyphs(from)), numGlyphs, gdiAdvances.data()); } } else { - RetainPtr<CGMutablePathRef> path(AdoptCF, CGPathCreateMutable()); - XFORM xform; GetWorldTransform(hdc, &xform); TransformationMatrix hdcTransform(xform.eM11, xform.eM21, xform.eM12, xform.eM22, xform.eDx, xform.eDy); @@ -233,16 +231,8 @@ static void drawGDIGlyphs(GraphicsContext* graphicsContext, const SimpleFontData initialGlyphTransform = CGAffineTransformConcat(initialGlyphTransform, CGAffineTransformMake(1, 0, tanf(syntheticObliqueAngle * piFloat / 180.0f), 1, 0, 0)); initialGlyphTransform.tx = 0; initialGlyphTransform.ty = 0; - CGAffineTransform glyphTranslation = CGAffineTransformIdentity; - - for (unsigned i = 0; i < numGlyphs; ++i) { - RetainPtr<CGPathRef> glyphPath(AdoptCF, createPathForGlyph(hdc, glyphBuffer.glyphAt(from + i))); - CGAffineTransform glyphTransform = CGAffineTransformConcat(initialGlyphTransform, glyphTranslation); - CGPathAddPath(path.get(), &glyphTransform, glyphPath.get()); - glyphTranslation = CGAffineTransformTranslate(glyphTranslation, gdiAdvances[i], 0); - } - CGContextRef cgContext = graphicsContext->platformContext(); + CGContextSaveGState(cgContext); BOOL fontSmoothingEnabled = false; @@ -252,26 +242,36 @@ static void drawGDIGlyphs(GraphicsContext* graphicsContext, const SimpleFontData CGContextScaleCTM(cgContext, 1.0, -1.0); CGContextTranslateCTM(cgContext, point.x() + glyphBuffer.offsetAt(from).width(), -(point.y() + glyphBuffer.offsetAt(from).height())); - if (drawingMode & cTextFill) { - CGContextAddPath(cgContext, path.get()); - CGContextFillPath(cgContext); - if (font->m_syntheticBoldOffset) { - CGContextTranslateCTM(cgContext, font->m_syntheticBoldOffset, 0); - CGContextAddPath(cgContext, path.get()); + for (unsigned i = 0; i < numGlyphs; ++i) { + RetainPtr<CGPathRef> glyphPath(AdoptCF, createPathForGlyph(hdc, glyphBuffer.glyphAt(from + i))); + CGContextSaveGState(cgContext); + CGContextConcatCTM(cgContext, initialGlyphTransform); + + if (drawingMode & cTextFill) { + CGContextAddPath(cgContext, glyphPath.get()); CGContextFillPath(cgContext); - CGContextTranslateCTM(cgContext, -font->m_syntheticBoldOffset, 0); + if (font->m_syntheticBoldOffset) { + CGContextTranslateCTM(cgContext, font->m_syntheticBoldOffset, 0); + CGContextAddPath(cgContext, glyphPath.get()); + CGContextFillPath(cgContext); + CGContextTranslateCTM(cgContext, -font->m_syntheticBoldOffset, 0); + } } - } - if (drawingMode & cTextStroke) { - CGContextAddPath(cgContext, path.get()); - CGContextStrokePath(cgContext); - if (font->m_syntheticBoldOffset) { - CGContextTranslateCTM(cgContext, font->m_syntheticBoldOffset, 0); - CGContextAddPath(cgContext, path.get()); + if (drawingMode & cTextStroke) { + CGContextAddPath(cgContext, glyphPath.get()); CGContextStrokePath(cgContext); - CGContextTranslateCTM(cgContext, -font->m_syntheticBoldOffset, 0); + if (font->m_syntheticBoldOffset) { + CGContextTranslateCTM(cgContext, font->m_syntheticBoldOffset, 0); + CGContextAddPath(cgContext, glyphPath.get()); + CGContextStrokePath(cgContext); + CGContextTranslateCTM(cgContext, -font->m_syntheticBoldOffset, 0); + } } + + CGContextRestoreGState(cgContext); + CGContextTranslateCTM(cgContext, gdiAdvances[i], 0); } + CGContextRestoreGState(cgContext); } @@ -298,8 +298,7 @@ void Font::drawGlyphs(GraphicsContext* graphicsContext, const SimpleFontData* fo bool shouldUseFontSmoothing = WebCoreShouldUseFontSmoothing(); if (font->platformData().useGDI()) { - static bool canUsePlatformNativeGlyphs = wkCanUsePlatformNativeGlyphs(); - if (!canUsePlatformNativeGlyphs || !shouldUseFontSmoothing || (graphicsContext->textDrawingMode() & cTextStroke)) { + if (!shouldUseFontSmoothing || (graphicsContext->textDrawingMode() & cTextStroke)) { drawGDIGlyphs(graphicsContext, font, glyphBuffer, from, numGlyphs, point); return; } diff --git a/WebCore/platform/graphics/win/FontCacheWin.cpp b/WebCore/platform/graphics/win/FontCacheWin.cpp index 9acc5a0..887bf79 100644 --- a/WebCore/platform/graphics/win/FontCacheWin.cpp +++ b/WebCore/platform/graphics/win/FontCacheWin.cpp @@ -422,7 +422,24 @@ static HFONT createGDIFont(const AtomicString& family, LONG desiredWeight, bool matchData.m_chosen.lfQuality = DEFAULT_QUALITY; matchData.m_chosen.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE; - return CreateFontIndirect(&matchData.m_chosen); + HFONT result = CreateFontIndirect(&matchData.m_chosen); + if (!result) + return 0; + + HDC dc = GetDC(0); + SaveDC(dc); + SelectObject(dc, result); + WCHAR actualName[LF_FACESIZE]; + GetTextFace(dc, LF_FACESIZE, actualName); + RestoreDC(dc, -1); + ReleaseDC(0, dc); + + if (wcsicmp(matchData.m_chosen.lfFaceName, actualName)) { + DeleteObject(result); + result = 0; + } + + return result; } struct TraitsInFamilyProcData { diff --git a/WebCore/platform/graphics/win/FontCustomPlatformData.cpp b/WebCore/platform/graphics/win/FontCustomPlatformData.cpp index ba8afe7..1ac3359 100644 --- a/WebCore/platform/graphics/win/FontCustomPlatformData.cpp +++ b/WebCore/platform/graphics/win/FontCustomPlatformData.cpp @@ -65,10 +65,7 @@ FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, b ASSERT(m_fontReference); ASSERT(T2embedLibrary()); - static bool canUsePlatformNativeGlyphs = wkCanUsePlatformNativeGlyphs(); - LOGFONT _logFont; - - LOGFONT& logFont = canUsePlatformNativeGlyphs ? *static_cast<LOGFONT*>(malloc(sizeof(LOGFONT))) : _logFont; + LOGFONT& logFont = *static_cast<LOGFONT*>(malloc(sizeof(LOGFONT))); if (m_name.isNull()) TTGetNewFontName(&m_fontReference, logFont.lfFaceName, LF_FACESIZE, 0, 0); else @@ -90,8 +87,7 @@ FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, b logFont.lfWeight = bold ? 700 : 400; HFONT hfont = CreateFontIndirect(&logFont); - if (canUsePlatformNativeGlyphs) - wkSetFontPlatformInfo(m_cgFont, &logFont, free); + wkSetFontPlatformInfo(m_cgFont, &logFont, free); return FontPlatformData(hfont, m_cgFont, size, bold, italic, renderingMode == AlternateRenderingMode); } @@ -120,7 +116,7 @@ size_t getBytesWithOffset(void *info, void* buffer, size_t offset, size_t count) // Streams the concatenation of a header and font data. class EOTStream { public: - EOTStream(const Vector<UInt8, 512>& eotHeader, const SharedBuffer* fontData, size_t overlayDst, size_t overlaySrc, size_t overlayLength) + EOTStream(const Vector<uint8_t, 512>& eotHeader, const SharedBuffer* fontData, size_t overlayDst, size_t overlaySrc, size_t overlayLength) : m_eotHeader(eotHeader) , m_fontData(fontData) , m_overlayDst(overlayDst) @@ -134,7 +130,7 @@ public: size_t read(void* buffer, size_t count); private: - const Vector<UInt8, 512>& m_eotHeader; + const Vector<uint8_t, 512>& m_eotHeader; const SharedBuffer* m_fontData; size_t m_overlayDst; size_t m_overlaySrc; @@ -210,7 +206,7 @@ FontCustomPlatformData* createFontCustomPlatformData(SharedBuffer* buffer) // TTLoadEmbeddedFont works only with Embedded OpenType (.eot) data, so we need to create an EOT header // and prepend it to the font data. - Vector<UInt8, 512> eotHeader; + Vector<uint8_t, 512> eotHeader; size_t overlayDst; size_t overlaySrc; size_t overlayLength; diff --git a/WebCore/platform/graphics/win/FontPlatformDataCGWin.cpp b/WebCore/platform/graphics/win/FontPlatformDataCGWin.cpp index c7e59ab..59f7e5c 100644 --- a/WebCore/platform/graphics/win/FontPlatformDataCGWin.cpp +++ b/WebCore/platform/graphics/win/FontPlatformDataCGWin.cpp @@ -120,7 +120,7 @@ void FontPlatformData::platformDataInit(HFONT font, float size, HDC hdc, WCHAR* ASSERT(m_cgFont); } } - if (m_useGDI && wkCanUsePlatformNativeGlyphs()) { + if (m_useGDI) { LOGFONT* logfont = static_cast<LOGFONT*>(malloc(sizeof(LOGFONT))); GetObject(font, sizeof(*logfont), logfont); wkSetFontPlatformInfo(m_cgFont.get(), logfont, free); diff --git a/WebCore/platform/graphics/win/GraphicsContextCGWin.cpp b/WebCore/platform/graphics/win/GraphicsContextCGWin.cpp index dccbe6c..da5b503 100644 --- a/WebCore/platform/graphics/win/GraphicsContextCGWin.cpp +++ b/WebCore/platform/graphics/win/GraphicsContextCGWin.cpp @@ -76,8 +76,6 @@ GraphicsContext::GraphicsContext(HDC hdc, bool hasAlpha) } } -bool GraphicsContext::inTransparencyLayer() const { return m_data->m_transparencyCount; } - // FIXME: Is it possible to merge getWindowsContext and createWindowsBitmap into a single API // suitable for all clients? HDC GraphicsContext::getWindowsContext(const IntRect& dstRect, bool supportAlphaBlend, bool mayCreateBitmap) @@ -173,16 +171,6 @@ void GraphicsContext::releaseWindowsContext(HDC hdc, const IntRect& dstRect, boo m_data->restore(); } -void GraphicsContext::setShouldIncludeChildWindows(bool include) -{ - m_data->m_shouldIncludeChildWindows = include; -} - -bool GraphicsContext::shouldIncludeChildWindows() const -{ - return m_data->m_shouldIncludeChildWindows; -} - GraphicsContext::WindowsBitmap::WindowsBitmap(HDC hdc, IntSize size) : m_hdc(0) , m_size(size) @@ -265,7 +253,7 @@ void GraphicsContext::drawFocusRing(const Color& color) float radius = (focusRingWidth() - 1) / 2.0f; int offset = radius + focusRingOffset(); - CGColorRef colorRef = color.isValid() ? cgColor(color) : 0; + CGColorRef colorRef = color.isValid() ? createCGColor(color) : 0; CGMutablePathRef focusRingPath = CGPathCreateMutable(); const Vector<IntRect>& rects = focusRingRects(); diff --git a/WebCore/platform/graphics/win/GraphicsContextCairoWin.cpp b/WebCore/platform/graphics/win/GraphicsContextCairoWin.cpp index 892d24a..1980d18 100644 --- a/WebCore/platform/graphics/win/GraphicsContextCairoWin.cpp +++ b/WebCore/platform/graphics/win/GraphicsContextCairoWin.cpp @@ -87,8 +87,6 @@ HDC GraphicsContext::getWindowsContext(const IntRect& dstRect, bool supportAlpha return hdc; } -bool GraphicsContext::inTransparencyLayer() const { return m_data->m_transparencyCount; } - void GraphicsContext::releaseWindowsContext(HDC hdc, const IntRect& dstRect, bool supportAlphaBlend, bool mayCreateBitmap) { // FIXME: We aren't really doing anything with the 'mayCreateBitmap' flag. This needs diff --git a/WebCore/platform/graphics/win/GraphicsContextWin.cpp b/WebCore/platform/graphics/win/GraphicsContextWin.cpp index b3ebcb0..e4c5b04 100644 --- a/WebCore/platform/graphics/win/GraphicsContextWin.cpp +++ b/WebCore/platform/graphics/win/GraphicsContextWin.cpp @@ -43,6 +43,18 @@ namespace WebCore { class SVGResourceImage; +bool GraphicsContext::inTransparencyLayer() const { return m_data->m_transparencyCount; } + +void GraphicsContext::setShouldIncludeChildWindows(bool include) +{ + m_data->m_shouldIncludeChildWindows = include; +} + +bool GraphicsContext::shouldIncludeChildWindows() const +{ + return m_data->m_shouldIncludeChildWindows; +} + void GraphicsContextPlatformPrivate::save() { if (!m_hdc) diff --git a/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.cpp b/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.cpp index 1b09e1f..c293f49 100644 --- a/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.cpp +++ b/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.cpp @@ -32,7 +32,10 @@ #include "KURL.h" #include "QTMovieWin.h" #include "ScrollView.h" +#include "StringHash.h" +#include <wtf/HashSet.h> #include <wtf/MathExtras.h> +#include <wtf/StdLibExtras.h> #if DRAW_FRAME_RATE #include "Font.h" @@ -48,16 +51,25 @@ using namespace std; namespace WebCore { -static const double endPointTimerInterval = 0.020; - +MediaPlayerPrivateInterface* MediaPlayerPrivate::create(MediaPlayer* player) +{ + return new MediaPlayerPrivate(player); +} + +void MediaPlayerPrivate::registerMediaEngine(MediaEngineRegistrar registrar) +{ + if (isAvailable()) + registrar(create, getSupportedTypes, supportsType); +} + MediaPlayerPrivate::MediaPlayerPrivate(MediaPlayer* player) : m_player(player) , m_seekTo(-1) , m_endTime(numeric_limits<float>::infinity()) , m_seekTimer(this, &MediaPlayerPrivate::seekTimerFired) - , m_endPointTimer(this, &MediaPlayerPrivate::endPointTimerFired) , m_networkState(MediaPlayer::Empty) - , m_readyState(MediaPlayer::DataUnavailable) + , m_readyState(MediaPlayer::HaveNothing) + , m_enabledTrackCount(0) , m_startedPlaying(false) , m_isStreaming(false) #if DRAW_FRAME_RATE @@ -75,7 +87,8 @@ MediaPlayerPrivate::~MediaPlayerPrivate() void MediaPlayerPrivate::load(const String& url) { if (!QTMovieWin::initializeQuickTime()) { - m_networkState = MediaPlayer::LoadFailed; + // FIXME: is this the right error to return? + m_networkState = MediaPlayer::DecodeError; m_player->networkStateChanged(); return; } @@ -84,17 +97,16 @@ void MediaPlayerPrivate::load(const String& url) m_networkState = MediaPlayer::Loading; m_player->networkStateChanged(); } - if (m_readyState != MediaPlayer::DataUnavailable) { - m_readyState = MediaPlayer::DataUnavailable; + if (m_readyState != MediaPlayer::HaveNothing) { + m_readyState = MediaPlayer::HaveNothing; m_player->readyStateChanged(); } cancelSeek(); - m_endPointTimer.stop(); m_qtMovie.set(new QTMovieWin(this)); m_qtMovie->load(url.characters(), url.length()); - m_qtMovie->setVolume(m_player->m_volume); - m_qtMovie->setVisible(m_player->m_visible); + m_qtMovie->setVolume(m_player->volume()); + m_qtMovie->setVisible(m_player->visible()); } void MediaPlayerPrivate::play() @@ -107,7 +119,6 @@ void MediaPlayerPrivate::play() #endif m_qtMovie->play(); - startEndPointTimerIfNeeded(); } void MediaPlayerPrivate::pause() @@ -119,7 +130,6 @@ void MediaPlayerPrivate::pause() m_timeStoppedPlaying = GetTickCount(); #endif m_qtMovie->pause(); - m_endPointTimer.stop(); } float MediaPlayerPrivate::duration() const @@ -156,11 +166,12 @@ void MediaPlayerPrivate::seek(float time) void MediaPlayerPrivate::doSeek() { float oldRate = m_qtMovie->rate(); - m_qtMovie->setRate(0); + if (oldRate) + m_qtMovie->setRate(0); m_qtMovie->setCurrentTime(m_seekTo); float timeAfterSeek = currentTime(); // restore playback only if not at end, othewise QTMovie will loop - if (timeAfterSeek < duration() && timeAfterSeek < m_endTime) + if (oldRate && timeAfterSeek < duration() && timeAfterSeek < m_endTime) m_qtMovie->setRate(oldRate); cancelSeek(); } @@ -195,22 +206,6 @@ void MediaPlayerPrivate::seekTimerFired(Timer<MediaPlayerPrivate>*) void MediaPlayerPrivate::setEndTime(float time) { m_endTime = time; - startEndPointTimerIfNeeded(); -} - -void MediaPlayerPrivate::startEndPointTimerIfNeeded() -{ - if (m_endTime < duration() && m_startedPlaying && !m_endPointTimer.isActive()) - m_endPointTimer.startRepeating(endPointTimerInterval); -} - -void MediaPlayerPrivate::endPointTimerFired(Timer<MediaPlayerPrivate>*) -{ - float time = currentTime(); - if (time >= m_endTime) { - pause(); - didEnd(); - } } bool MediaPlayerPrivate::paused() const @@ -325,42 +320,44 @@ void MediaPlayerPrivate::updateStates() long loadState = m_qtMovie ? m_qtMovie->loadState() : QTMovieLoadStateError; - if (loadState >= QTMovieLoadStateLoaded && m_networkState < MediaPlayer::LoadedMetaData && !m_player->inMediaDocument()) { - unsigned enabledTrackCount; - m_qtMovie->disableUnsupportedTracks(enabledTrackCount); - // FIXME: We should differentiate between load errors and decode errors <rdar://problem/5605692> - if (!enabledTrackCount) + if (loadState >= QTMovieLoadStateLoaded && m_readyState < MediaPlayer::HaveMetadata && !m_player->inMediaDocument()) { + m_qtMovie->disableUnsupportedTracks(m_enabledTrackCount); + if (!m_enabledTrackCount) loadState = QTMovieLoadStateError; } // "Loaded" is reserved for fully buffered movies, never the case when streaming if (loadState >= QTMovieLoadStateComplete && !m_isStreaming) { - if (m_networkState < MediaPlayer::Loaded) - m_networkState = MediaPlayer::Loaded; - m_readyState = MediaPlayer::CanPlayThrough; + m_networkState = MediaPlayer::Loaded; + m_readyState = MediaPlayer::HaveEnoughData; } else if (loadState >= QTMovieLoadStatePlaythroughOK) { - if (m_networkState < MediaPlayer::LoadedFirstFrame && !seeking()) - m_networkState = MediaPlayer::LoadedFirstFrame; - m_readyState = MediaPlayer::CanPlayThrough; + m_readyState = MediaPlayer::HaveEnoughData; } else if (loadState >= QTMovieLoadStatePlayable) { - if (m_networkState < MediaPlayer::LoadedFirstFrame && !seeking()) - m_networkState = MediaPlayer::LoadedFirstFrame; - m_readyState = currentTime() < maxTimeLoaded() ? MediaPlayer::CanPlay : MediaPlayer::DataUnavailable; + // FIXME: This might not work correctly in streaming case, <rdar://problem/5693967> + m_readyState = currentTime() < maxTimeLoaded() ? MediaPlayer::HaveFutureData : MediaPlayer::HaveCurrentData; } else if (loadState >= QTMovieLoadStateLoaded) { - if (m_networkState < MediaPlayer::LoadedMetaData) - m_networkState = MediaPlayer::LoadedMetaData; - m_readyState = MediaPlayer::DataUnavailable; + m_readyState = MediaPlayer::HaveMetadata; } else if (loadState > QTMovieLoadStateError) { - if (m_networkState < MediaPlayer::Loading) - m_networkState = MediaPlayer::Loading; - m_readyState = MediaPlayer::DataUnavailable; + m_networkState = MediaPlayer::Loading; + m_readyState = MediaPlayer::HaveNothing; } else { - m_networkState = MediaPlayer::LoadFailed; - m_readyState = MediaPlayer::DataUnavailable; + float loaded = maxTimeLoaded(); + if (!loaded) + m_readyState = MediaPlayer::HaveNothing; + + if (!m_enabledTrackCount) + m_networkState = MediaPlayer::FormatError; + else { + // FIXME: We should differentiate between load/network errors and decode errors <rdar://problem/5605692> + if (loaded > 0) + m_networkState = MediaPlayer::DecodeError; + else + m_readyState = MediaPlayer::HaveNothing; + } } if (seeking()) - m_readyState = MediaPlayer::DataUnavailable; + m_readyState = MediaPlayer::HaveNothing; if (m_networkState != oldNetworkState) m_player->networkStateChanged(); @@ -371,7 +368,6 @@ void MediaPlayerPrivate::updateStates() void MediaPlayerPrivate::didEnd() { - m_endPointTimer.stop(); m_startedPlaying = false; #if DRAW_FRAME_RATE m_timeStoppedPlaying = GetTickCount(); @@ -380,10 +376,10 @@ void MediaPlayerPrivate::didEnd() m_player->timeChanged(); } -void MediaPlayerPrivate::setRect(const IntRect& r) +void MediaPlayerPrivate::setSize(const IntSize& size) { if (m_qtMovie) - m_qtMovie->setSize(r.width(), r.height()); + m_qtMovie->setSize(size.width(), size.height()); } void MediaPlayerPrivate::setVisible(bool b) @@ -403,7 +399,7 @@ void MediaPlayerPrivate::paint(GraphicsContext* p, const IntRect& r) #if DRAW_FRAME_RATE if (m_frameCountWhilePlaying > 10) { - Frame* frame = m_player->m_frameView ? m_player->m_frameView->frame() : NULL; + Frame* frame = m_player->frameView() ? m_player->frameView()->frame() : NULL; Document* document = frame ? frame->document() : NULL; RenderObject* renderer = document ? document->renderer() : NULL; RenderStyle* styleToUse = renderer ? renderer->style() : NULL; @@ -427,16 +423,30 @@ void MediaPlayerPrivate::paint(GraphicsContext* p, const IntRect& r) #endif } -void MediaPlayerPrivate::getSupportedTypes(HashSet<String>& types) +static HashSet<String> mimeTypeCache() { - unsigned count = QTMovieWin::countSupportedTypes(); - for (unsigned n = 0; n < count; n++) { - const UChar* character; - unsigned len; - QTMovieWin::getSupportedType(n, character, len); - if (len) - types.add(String(character, len)); + DEFINE_STATIC_LOCAL(HashSet<String>, typeCache, ()); + static bool typeListInitialized = false; + + if (!typeListInitialized) { + unsigned count = QTMovieWin::countSupportedTypes(); + for (unsigned n = 0; n < count; n++) { + const UChar* character; + unsigned len; + QTMovieWin::getSupportedType(n, character, len); + if (len) + typeCache.add(String(character, len)); + } + + typeListInitialized = true; } + + return typeCache; +} + +void MediaPlayerPrivate::getSupportedTypes(HashSet<String>& types) +{ + types = mimeTypeCache(); } bool MediaPlayerPrivate::isAvailable() @@ -444,6 +454,13 @@ bool MediaPlayerPrivate::isAvailable() return QTMovieWin::initializeQuickTime(); } +MediaPlayer::SupportsType MediaPlayerPrivate::supportsType(const String& type, const String& codecs) +{ + // only return "IsSupported" if there is no codecs parameter for now as there is no way to ask QT if it supports an + // extended MIME type + return mimeTypeCache().contains(type) ? (!codecs.isEmpty() ? MediaPlayer::MayBeSupported : MediaPlayer::IsSupported) : MediaPlayer::IsNotSupported; +} + void MediaPlayerPrivate::movieEnded(QTMovieWin* movie) { ASSERT(m_qtMovie.get() == movie); diff --git a/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.h b/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.h index c4c893c..63aa62b 100644 --- a/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.h +++ b/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007 Apple Inc. All rights reserved. + * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -28,7 +28,7 @@ #if ENABLE(VIDEO) -#include "MediaPlayer.h" +#include "MediaPlayerPrivate.h" #include "Timer.h" #include <QTMovieWin.h> #include <wtf/OwnPtr.h> @@ -44,9 +44,10 @@ class IntSize; class IntRect; class String; -class MediaPlayerPrivate : QTMovieWinClient, Noncopyable { +class MediaPlayerPrivate : public MediaPlayerPrivateInterface, public QTMovieWinClient { public: - MediaPlayerPrivate(MediaPlayer*); + static void registerMediaEngine(MediaEngineRegistrar); + ~MediaPlayerPrivate(); IntSize naturalSize() const; @@ -81,38 +82,42 @@ public: unsigned totalBytes() const; void setVisible(bool); - void setRect(const IntRect&); + void setSize(const IntSize&); void loadStateChanged(); void didEnd(); void paint(GraphicsContext*, const IntRect&); - static void getSupportedTypes(HashSet<String>& types); - static bool isAvailable(); private: + MediaPlayerPrivate(MediaPlayer*); + void updateStates(); void doSeek(); void cancelSeek(); void seekTimerFired(Timer<MediaPlayerPrivate>*); - void endPointTimerFired(Timer<MediaPlayerPrivate>*); float maxTimeLoaded() const; - void startEndPointTimerIfNeeded(); virtual void movieEnded(QTMovieWin*); virtual void movieLoadStateChanged(QTMovieWin*); virtual void movieTimeChanged(QTMovieWin*); virtual void movieNewImageAvailable(QTMovieWin*); - + + // engine support + static MediaPlayerPrivateInterface* create(MediaPlayer*); + static void getSupportedTypes(HashSet<String>& types); + static MediaPlayer::SupportsType supportsType(const String& type, const String& codecs); + static bool isAvailable(); + MediaPlayer* m_player; OwnPtr<QTMovieWin> m_qtMovie; float m_seekTo; float m_endTime; Timer<MediaPlayerPrivate> m_seekTimer; - Timer<MediaPlayerPrivate> m_endPointTimer; MediaPlayer::NetworkState m_networkState; MediaPlayer::ReadyState m_readyState; + unsigned m_enabledTrackCount; bool m_startedPlaying; bool m_isStreaming; #if DRAW_FRAME_RATE diff --git a/WebCore/platform/graphics/win/OpenTypeUtilities.cpp b/WebCore/platform/graphics/win/OpenTypeUtilities.cpp deleted file mode 100644 index 1951320..0000000 --- a/WebCore/platform/graphics/win/OpenTypeUtilities.cpp +++ /dev/null @@ -1,387 +0,0 @@ -/* - * Copyright (C) 2008 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "OpenTypeUtilities.h" - -#include "SharedBuffer.h" - -namespace WebCore { - -struct BigEndianUShort { - operator unsigned short() const { return (v & 0x00ff) << 8 | v >> 8; } - BigEndianUShort(unsigned short u) : v((u & 0x00ff) << 8 | u >> 8) { } - unsigned short v; -}; - -struct BigEndianULong { - operator unsigned() const { return (v & 0xff) << 24 | (v & 0xff00) << 8 | (v & 0xff0000) >> 8 | v >> 24; } - BigEndianULong(unsigned u) : v((u & 0xff) << 24 | (u & 0xff00) << 8 | (u & 0xff0000) >> 8 | u >> 24) { } - unsigned v; -}; - -#pragma pack(1) - -struct EOTPrefix { - unsigned eotSize; - unsigned fontDataSize; - unsigned version; - unsigned flags; - UInt8 fontPANOSE[10]; - UInt8 charset; - UInt8 italic; - unsigned weight; - unsigned short fsType; - unsigned short magicNumber; - unsigned unicodeRange[4]; - unsigned codePageRange[2]; - unsigned checkSumAdjustment; - unsigned reserved[4]; - unsigned short padding1; -}; - -struct TableDirectoryEntry { - BigEndianULong tag; - BigEndianULong checkSum; - BigEndianULong offset; - BigEndianULong length; -}; - -struct sfntHeader { - Fixed version; - BigEndianUShort numTables; - BigEndianUShort searchRange; - BigEndianUShort entrySelector; - BigEndianUShort rangeShift; - TableDirectoryEntry tables[1]; -}; - -struct OS2Table { - BigEndianUShort version; - BigEndianUShort avgCharWidth; - BigEndianUShort weightClass; - BigEndianUShort widthClass; - BigEndianUShort fsType; - BigEndianUShort subscriptXSize; - BigEndianUShort subscriptYSize; - BigEndianUShort subscriptXOffset; - BigEndianUShort subscriptYOffset; - BigEndianUShort superscriptXSize; - BigEndianUShort superscriptYSize; - BigEndianUShort superscriptXOffset; - BigEndianUShort superscriptYOffset; - BigEndianUShort strikeoutSize; - BigEndianUShort strikeoutPosition; - BigEndianUShort familyClass; - UInt8 panose[10]; - BigEndianULong unicodeRange[4]; - UInt8 vendID[4]; - BigEndianUShort fsSelection; - BigEndianUShort firstCharIndex; - BigEndianUShort lastCharIndex; - BigEndianUShort typoAscender; - BigEndianUShort typoDescender; - BigEndianUShort typoLineGap; - BigEndianUShort winAscent; - BigEndianUShort winDescent; - BigEndianULong codePageRange[2]; - BigEndianUShort xHeight; - BigEndianUShort capHeight; - BigEndianUShort defaultChar; - BigEndianUShort breakChar; - BigEndianUShort maxContext; -}; - -struct headTable { - Fixed version; - Fixed fontRevision; - BigEndianULong checkSumAdjustment; - BigEndianULong magicNumber; - BigEndianUShort flags; - BigEndianUShort unitsPerEm; - long long created; - long long modified; - BigEndianUShort xMin; - BigEndianUShort xMax; - BigEndianUShort yMin; - BigEndianUShort yMax; - BigEndianUShort macStyle; - BigEndianUShort lowestRectPPEM; - BigEndianUShort fontDirectionHint; - BigEndianUShort indexToLocFormat; - BigEndianUShort glyphDataFormat; -}; - -struct nameRecord { - BigEndianUShort platformID; - BigEndianUShort encodingID; - BigEndianUShort languageID; - BigEndianUShort nameID; - BigEndianUShort length; - BigEndianUShort offset; -}; - -struct nameTable { - BigEndianUShort format; - BigEndianUShort count; - BigEndianUShort stringOffset; - nameRecord nameRecords[1]; -}; - -#pragma pack() - -static void appendBigEndianStringToEOTHeader(Vector<UInt8, 512>& eotHeader, const BigEndianUShort* string, unsigned short length) -{ - size_t size = eotHeader.size(); - eotHeader.resize(size + length + 2 * sizeof(unsigned short)); - UChar* dst = reinterpret_cast<UChar*>(eotHeader.data() + size); - unsigned i = 0; - dst[i++] = length; - unsigned numCharacters = length / 2; - for (unsigned j = 0; j < numCharacters; j++) - dst[i++] = string[j]; - dst[i] = 0; -} - -bool getEOTHeader(SharedBuffer* fontData, Vector<UInt8, 512>& eotHeader, size_t& overlayDst, size_t& overlaySrc, size_t& overlayLength) -{ - overlayDst = 0; - overlaySrc = 0; - overlayLength = 0; - - size_t dataLength = fontData->size(); - const char* data = fontData->data(); - - eotHeader.resize(sizeof(EOTPrefix)); - EOTPrefix* prefix = reinterpret_cast<EOTPrefix*>(eotHeader.data()); - - prefix->fontDataSize = dataLength; - prefix->version = 0x00020001; - prefix->flags = 0; - - if (dataLength < offsetof(sfntHeader, tables)) - return false; - - const sfntHeader* sfnt = reinterpret_cast<const sfntHeader*>(data); - - if (dataLength < offsetof(sfntHeader, tables) + sfnt->numTables * sizeof(TableDirectoryEntry)) - return false; - - bool haveOS2 = false; - bool haveHead = false; - bool haveName = false; - - const BigEndianUShort* familyName = 0; - unsigned short familyNameLength = 0; - const BigEndianUShort* subfamilyName = 0; - unsigned short subfamilyNameLength = 0; - const BigEndianUShort* fullName = 0; - unsigned short fullNameLength = 0; - const BigEndianUShort* versionString = 0; - unsigned short versionStringLength = 0; - - for (unsigned i = 0; i < sfnt->numTables; i++) { - unsigned tableOffset = sfnt->tables[i].offset; - unsigned tableLength = sfnt->tables[i].length; - - if (dataLength < tableOffset || dataLength < tableLength || dataLength < tableOffset + tableLength) - return false; - - unsigned tableTag = sfnt->tables[i].tag; - switch (tableTag) { - case 'OS/2': - { - if (dataLength < tableOffset + sizeof(OS2Table)) - return false; - - haveOS2 = true; - const OS2Table* OS2 = reinterpret_cast<const OS2Table*>(data + tableOffset); - for (unsigned j = 0; j < 10; j++) - prefix->fontPANOSE[j] = OS2->panose[j]; - prefix->italic = OS2->fsSelection & 0x01; - prefix->weight = OS2->weightClass; - // FIXME: Should use OS2->fsType, but some TrueType fonts set it to an over-restrictive value. - // Since ATS does not enforce this on Mac OS X, we do not enforce it either. - prefix->fsType = 0; - for (unsigned j = 0; j < 4; j++) - prefix->unicodeRange[j] = OS2->unicodeRange[j]; - for (unsigned j = 0; j < 2; j++) - prefix->codePageRange[j] = OS2->codePageRange[j]; - break; - } - case 'head': - { - if (dataLength < tableOffset + sizeof(headTable)) - return false; - - haveHead = true; - const headTable* head = reinterpret_cast<const headTable*>(data + tableOffset); - prefix->checkSumAdjustment = head->checkSumAdjustment; - break; - } - case 'name': - { - if (dataLength < tableOffset + offsetof(nameTable, nameRecords)) - return false; - - haveName = true; - const nameTable* name = reinterpret_cast<const nameTable*>(data + tableOffset); - for (int j = 0; j < name->count; j++) { - if (dataLength < tableOffset + offsetof(nameTable, nameRecords) + (j + 1) * sizeof(nameRecord)) - return false; - if (name->nameRecords[j].platformID == 3 && name->nameRecords[j].encodingID == 1 && name->nameRecords[j].languageID == 0x0409) { - if (dataLength < tableOffset + name->stringOffset + name->nameRecords[j].offset + name->nameRecords[j].length) - return false; - - unsigned short nameLength = name->nameRecords[j].length; - const BigEndianUShort* nameString = reinterpret_cast<const BigEndianUShort*>(data + tableOffset + name->stringOffset + name->nameRecords[j].offset); - - switch (name->nameRecords[j].nameID) { - case 1: - familyNameLength = nameLength; - familyName = nameString; - break; - case 2: - subfamilyNameLength = nameLength; - subfamilyName = nameString; - break; - case 4: - fullNameLength = nameLength; - fullName = nameString; - break; - case 5: - versionStringLength = nameLength; - versionString = nameString; - break; - default: - break; - } - } - } - break; - } - default: - break; - } - if (haveOS2 && haveHead && haveName) - break; - } - - prefix->charset = DEFAULT_CHARSET; - prefix->magicNumber = 0x504c; - prefix->reserved[0] = 0; - prefix->reserved[1] = 0; - prefix->reserved[2] = 0; - prefix->reserved[3] = 0; - prefix->padding1 = 0; - - appendBigEndianStringToEOTHeader(eotHeader, familyName, familyNameLength); - appendBigEndianStringToEOTHeader(eotHeader, subfamilyName, subfamilyNameLength); - appendBigEndianStringToEOTHeader(eotHeader, versionString, versionStringLength); - - // If possible, ensure that the family name is a prefix of the full name. - if (fullNameLength >= familyNameLength && memcmp(familyName, fullName, familyNameLength)) { - overlaySrc = reinterpret_cast<const char*>(fullName) - data; - overlayDst = reinterpret_cast<const char*>(familyName) - data; - overlayLength = familyNameLength; - } - - appendBigEndianStringToEOTHeader(eotHeader, fullName, fullNameLength); - - unsigned short padding = 0; - eotHeader.append(reinterpret_cast<UInt8*>(&padding), sizeof(padding)); - - prefix->eotSize = eotHeader.size() + fontData->size(); - - return true; -} - -HANDLE renameAndActivateFont(SharedBuffer* fontData, const String& fontName) -{ - size_t originalDataSize = fontData->size(); - const sfntHeader* sfnt = reinterpret_cast<const sfntHeader*>(fontData->data()); - - unsigned t; - for (t = 0; t < sfnt->numTables; ++t) { - if (sfnt->tables[t].tag == 'name') - break; - } - if (t == sfnt->numTables) - return 0; - - const int nameRecordCount = 5; - - // Rounded up to a multiple of 4 to simplify the checksum calculation. - size_t nameTableSize = ((offsetof(nameTable, nameRecords) + nameRecordCount * sizeof(nameRecord) + fontName.length() * sizeof(UChar)) & ~3) + 4; - - Vector<char> rewrittenFontData(fontData->size() + nameTableSize); - char* data = rewrittenFontData.data(); - memcpy(data, fontData->data(), originalDataSize); - - // Make the table directory entry point to the new 'name' table. - sfntHeader* rewrittenSfnt = reinterpret_cast<sfntHeader*>(data); - rewrittenSfnt->tables[t].length = nameTableSize; - rewrittenSfnt->tables[t].offset = originalDataSize; - - // Write the new 'name' table after the original font data. - nameTable* name = reinterpret_cast<nameTable*>(data + originalDataSize); - name->format = 0; - name->count = nameRecordCount; - name->stringOffset = offsetof(nameTable, nameRecords) + nameRecordCount * sizeof(nameRecord); - for (unsigned i = 0; i < nameRecordCount; ++i) { - name->nameRecords[i].platformID = 3; - name->nameRecords[i].encodingID = 1; - name->nameRecords[i].languageID = 0x0409; - name->nameRecords[i].offset = 0; - name->nameRecords[i].length = fontName.length() * sizeof(UChar); - } - - // The required 'name' record types: Family, Style, Unique, Full and PostScript. - name->nameRecords[0].nameID = 1; - name->nameRecords[1].nameID = 2; - name->nameRecords[2].nameID = 3; - name->nameRecords[3].nameID = 4; - name->nameRecords[4].nameID = 6; - - for (unsigned i = 0; i < fontName.length(); ++i) - reinterpret_cast<BigEndianUShort*>(data + originalDataSize + name->stringOffset)[i] = fontName[i]; - - // Update the table checksum in the directory entry. - rewrittenSfnt->tables[t].checkSum = 0; - for (unsigned i = 0; i * sizeof(BigEndianULong) < nameTableSize; ++i) - rewrittenSfnt->tables[t].checkSum = rewrittenSfnt->tables[t].checkSum + reinterpret_cast<BigEndianULong*>(name)[i]; - - DWORD numFonts = 0; - HANDLE fontHandle = AddFontMemResourceEx(data, originalDataSize + nameTableSize, 0, &numFonts); - - if (fontHandle && numFonts != 1) { - RemoveFontMemResourceEx(fontHandle); - return 0; - } - - return fontHandle; -} - -} diff --git a/WebCore/platform/graphics/win/OpenTypeUtilities.h b/WebCore/platform/graphics/win/OpenTypeUtilities.h deleted file mode 100644 index ab35551..0000000 --- a/WebCore/platform/graphics/win/OpenTypeUtilities.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2008 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef OpenTypeUtilities_h -#define OpenTypeUtilities_h - -#include "PlatformString.h" -#include <wtf/Forward.h> - -namespace WebCore { - -class SharedBuffer; - -bool getEOTHeader(SharedBuffer* fontData, Vector<UInt8, 512>& eotHeader, size_t& overlayDst, size_t& overlaySrc, size_t& overlayLength); -HANDLE renameAndActivateFont(SharedBuffer*, const String&); - -} // namespace WebCore - -#endif // OpenTypeUtilities_h diff --git a/WebCore/platform/graphics/win/QTMovieWin.cpp b/WebCore/platform/graphics/win/QTMovieWin.cpp index 32aecd3..3f23698 100644 --- a/WebCore/platform/graphics/win/QTMovieWin.cpp +++ b/WebCore/platform/graphics/win/QTMovieWin.cpp @@ -658,6 +658,12 @@ void QTMovieWin::disableUnsupportedTracks(unsigned& enabledTrackCount) continue; if (!allowedTrackTypes->contains(mediaType)) { + + // Different mpeg variants import as different track types so check for the "mpeg + // characteristic" instead of hard coding the (current) list of mpeg media types. + if (GetMovieIndTrackType(m_private->m_movie, 1, 'mpeg', movieTrackCharacteristic | movieTrackEnabledOnly)) + continue; + SetTrackEnabled(currentTrack, false); --enabledTrackCount; } diff --git a/WebCore/platform/graphics/win/QTMovieWinTimer.cpp b/WebCore/platform/graphics/win/QTMovieWinTimer.cpp index d0aa3e6..f6103ea 100644 --- a/WebCore/platform/graphics/win/QTMovieWinTimer.cpp +++ b/WebCore/platform/graphics/win/QTMovieWinTimer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006, 2007 Apple Computer, Inc. All rights reserved. + * Copyright (C) 2006, 2007, 2009 Apple Computer, Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -51,6 +51,9 @@ static LRESULT CALLBACK TimerWindowWndProc(HWND hWnd, UINT message, WPARAM wPara processingCustomTimerMessage = true; sharedTimerFiredFunction(); processingCustomTimerMessage = false; + } else if (message == WM_TIMER && wParam == timerID) { + stopSharedTimer(); + sharedTimerFiredFunction(); } else return DefWindowProc(hWnd, message, wParam, lParam); return 0; @@ -79,11 +82,6 @@ void setSharedTimerFiredFunction(void (*f)()) sharedTimerFiredFunction = f; } -static void CALLBACK timerFired(HWND, UINT, UINT_PTR, DWORD) -{ - sharedTimerFiredFunction(); -} - void setSharedTimerFireDelay(double interval) { ASSERT(sharedTimerFiredFunction); @@ -99,29 +97,27 @@ void setSharedTimerFireDelay(double interval) intervalInMS = (unsigned)interval; } - if (timerID) { - KillTimer(0, timerID); - timerID = 0; - } + stopSharedTimer(); + initializeOffScreenTimerWindow(); // We don't allow nested PostMessages, since the custom messages will effectively starve // painting and user input. (Win32 has a tri-level queue with application messages > // user input > WM_PAINT/WM_TIMER.) // In addition, if the queue contains input events that have been there since the last call to // GetQueueStatus, PeekMessage or GetMessage we favor timers. - if (intervalInMS < USER_TIMER_MINIMUM && processingCustomTimerMessage && - !LOWORD(::GetQueueStatus(QS_ALLINPUT))) { + if (intervalInMS < USER_TIMER_MINIMUM + && !processingCustomTimerMessage + && !LOWORD(::GetQueueStatus(QS_ALLINPUT))) { // Windows SetTimer does not allow timeouts smaller than 10ms (USER_TIMER_MINIMUM) - initializeOffScreenTimerWindow(); PostMessage(timerWindowHandle, timerFiredMessage, 0, 0); } else - timerID = SetTimer(0, 0, intervalInMS, timerFired); + timerID = SetTimer(timerWindowHandle, timerFiredMessage, intervalInMS, 0); } void stopSharedTimer() { if (timerID) { - KillTimer(0, timerID); + KillTimer(timerWindowHandle, timerID); timerID = 0; } } |