merge mozilla-inbound to mozilla-central a=merge

This commit is contained in:
Carsten "Tomcat" Book 2015-03-09 13:46:06 +01:00
Родитель a766615691 0b4dfcc0dc
Коммит 6e5e93073a
76 изменённых файлов: 475 добавлений и 206 удалений

Просмотреть файл

@ -1817,12 +1817,12 @@ pref("ui.key.menuAccessKeyFocuses", true);
#endif
// Encrypted media extensions.
#ifdef RELEASE_BUILD
pref("media.eme.enabled", false);
pref("media.eme.apiVisible", false);
#else
pref("media.eme.enabled", true);
pref("media.eme.apiVisible", true);
#ifdef XP_WIN
pref("media.gmp-eme-adobe.enabled", true);
pref("browser.eme.ui.enabled", true);
#endif
// Play with different values of the decay time and get telemetry,
@ -1856,13 +1856,6 @@ pref("privacy.trackingprotection.ui.enabled", false);
pref("browser.tabs.remote.autostart.1", true);
#endif
// Temporary pref to allow printing in e10s windows on some platforms.
#ifdef UNIX_BUT_NOT_MAC
pref("print.enable_e10s_testing", false);
#else
pref("print.enable_e10s_testing", true);
#endif
#ifdef NIGHTLY_BUILD
// Enable e10s add-on interposition by default.
pref("extensions.interposition.enabled", true);

Просмотреть файл

@ -27,3 +27,6 @@ EXTRA_PP_JS_MODULES += [
'CustomizeMode.jsm',
'PanelWideWidgetTracker.jsm',
]
with Files('**'):
BUG_COMPONENT = ('Firefox', 'Toolbars and Customization')

Просмотреть файл

@ -18,3 +18,6 @@ EXTRA_JS_MODULES += [
'DownloadsTaskbar.jsm',
'DownloadsViewUI.jsm',
]
with Files('**'):
BUG_COMPONENT = ('Firefox', 'Downloads Panel')

Просмотреть файл

@ -41,3 +41,6 @@ LOCAL_INCLUDES += [
]
FAIL_ON_WARNINGS = True
with Files('**'):
BUG_COMPONENT = ('Firefox', 'RSS Discovery and Preview')

Просмотреть файл

@ -24,3 +24,6 @@ EXTRA_JS_MODULES.loop += [
'MozLoopService.jsm',
'MozLoopWorker.js',
]
with Files('**'):
BUG_COMPONENT = ('Loop', 'Client')

Просмотреть файл

@ -54,3 +54,6 @@ EXTRA_PP_JS_MODULES += [
FINAL_LIBRARY = 'browsercomps'
FAIL_ON_WARNINGS = True
with Files('**'):
BUG_COMPONENT = ('Firefox', 'Migration')

Просмотреть файл

@ -50,3 +50,6 @@ BROWSER_CHROME_MANIFESTS += [
if CONFIG['MOZ_SAFE_BROWSING']:
BROWSER_CHROME_MANIFESTS += ['safebrowsing/content/test/browser.ini']
with Files('safebrowsing/*'):
BUG_COMPONENT = ('Toolkit', 'Phishing Protection')

Просмотреть файл

@ -13,3 +13,6 @@ JAR_MANIFESTS += ['jar.mn']
EXTRA_PP_JS_MODULES += [
'PlacesUIUtils.jsm',
]
with Files('**'):
BUG_COMPONENT = ('Firefox', 'Bookmarks & History')

Просмотреть файл

@ -18,3 +18,6 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('windows', 'gtk2', 'gtk3', 'cocoa'):
DEFINES['HAVE_SHELL_SERVICE'] = 1
JAR_MANIFESTS += ['jar.mn']
with Files('**'):
BUG_COMPONENT = ('Firefox', 'Preferences')

Просмотреть файл

@ -8,4 +8,7 @@ BROWSER_CHROME_MANIFESTS += [
'test/browser/browser.ini',
]
JAR_MANIFESTS += ['jar.mn']
JAR_MANIFESTS += ['jar.mn']
with Files('**'):
BUG_COMPONENT = ('Firefox', 'Private Browsing')

Просмотреть файл

@ -20,3 +20,6 @@ XPCSHELL_TESTS_MANIFESTS += ['test/xpcshell/xpcshell.ini']
EXTRA_JS_MODULES.readinglist += [
'Scheduler.jsm',
]
with Files('**'):
BUG_COMPONENT = ('Firefox', 'Reading List')

Просмотреть файл

@ -8,4 +8,7 @@ BROWSER_CHROME_MANIFESTS += [
'test/browser.ini',
]
JAR_MANIFESTS += ['jar.mn']
JAR_MANIFESTS += ['jar.mn']
with Files('**'):
BUG_COMPONENT = ('Firefox', 'Search')

Просмотреть файл

@ -50,3 +50,5 @@ EXTRA_PP_JS_MODULES.sessionstore += [
'SessionStore.jsm',
]
with Files('**'):
BUG_COMPONENT = ('Firefox', 'Session Restore')

Просмотреть файл

@ -51,3 +51,6 @@ for var in ('MOZ_APP_NAME', 'MOZ_APP_VERSION'):
CXXFLAGS += CONFIG['TK_CFLAGS']
FAIL_ON_WARNINGS = True
with Files('**'):
BUG_COMPONENT = ('Firefox', 'Shell Integration')

Просмотреть файл

@ -9,4 +9,7 @@ BROWSER_CHROME_MANIFESTS += [
'test/browser.ini',
]
JAR_MANIFESTS += ['jar.mn']
JAR_MANIFESTS += ['jar.mn']
with Files('**'):
BUG_COMPONENT = ('Firefox', 'Panorama')

Просмотреть файл

@ -11,3 +11,6 @@ JAR_MANIFESTS += ['jar.mn']
BROWSER_CHROME_MANIFESTS += [
'test/browser.ini',
]
with Files('**'):
BUG_COMPONENT = ('Firefox', 'Tours')

Просмотреть файл

@ -22,7 +22,7 @@ class SoundTouch;
namespace mozilla {
struct DestroyPolicy
struct CubebDestroyPolicy
{
void operator()(cubeb_stream* aStream) const {
cubeb_stream_destroy(aStream);
@ -360,7 +360,7 @@ private:
CircularByteBuffer mBuffer;
// Owning reference to a cubeb_stream.
UniquePtr<cubeb_stream, DestroyPolicy> mCubebStream;
UniquePtr<cubeb_stream, CubebDestroyPolicy> mCubebStream;
uint32_t mBytesPerFrame;

Просмотреть файл

@ -256,6 +256,10 @@ public:
// the newer async model.
virtual bool IsAsync() const { return false; }
// Returns true if this decoder reader uses hardware accelerated video
// decoding.
virtual bool VideoIsHardwareAccelerated() const { return false; }
protected:
virtual ~MediaDecoderReader();

Просмотреть файл

@ -220,7 +220,6 @@ MediaDecoderStateMachine::MediaDecoderStateMachine(MediaDecoder* aDecoder,
mVolume(1.0),
mPlaybackRate(1.0),
mPreservesPitch(true),
mAmpleVideoFrames(MIN_VIDEO_QUEUE_SIZE),
mLowAudioThresholdUsecs(detail::LOW_AUDIO_USECS),
mAmpleAudioThresholdUsecs(detail::AMPLE_AUDIO_USECS),
mQuickBufferingLowDataThresholdUsecs(detail::QUICK_BUFFERING_LOW_DATA_USECS),
@ -579,7 +578,7 @@ bool MediaDecoderStateMachine::HaveEnoughDecodedVideo()
{
AssertCurrentThreadInMonitor();
if (static_cast<uint32_t>(VideoQueue().GetSize()) < mAmpleVideoFrames * mPlaybackRate) {
if (static_cast<uint32_t>(VideoQueue().GetSize()) < GetAmpleVideoFrames() * mPlaybackRate) {
return false;
}
@ -836,6 +835,10 @@ MediaDecoderStateMachine::OnNotDecoded(MediaData::Type aType,
} else {
mVideoDataRequest.Complete();
}
if (IsShutdown()) {
// Already shutdown;
return;
}
// If this is a decode error, delegate to the generic error path.
if (aReason == MediaDecoderReader::DECODE_ERROR) {
@ -1927,6 +1930,10 @@ MediaDecoderStateMachine::DispatchAudioDecodeTaskIfNeeded()
MOZ_ASSERT(OnStateMachineThread());
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
if (IsShutdown()) {
return NS_ERROR_FAILURE;
}
if (NeedToDecodeAudio()) {
return EnsureAudioDecodeTaskQueued();
}
@ -1973,6 +1980,10 @@ MediaDecoderStateMachine::DispatchVideoDecodeTaskIfNeeded()
MOZ_ASSERT(OnStateMachineThread());
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
if (IsShutdown()) {
return NS_ERROR_FAILURE;
}
if (NeedToDecodeVideo()) {
return EnsureVideoDecodeTaskQueued();
}
@ -2229,13 +2240,10 @@ nsresult MediaDecoderStateMachine::DecodeMetadata()
mInfo = info;
if (HasVideo()) {
mAmpleVideoFrames = (mReader->IsAsync() && mInfo.mVideo.mIsHardwareAccelerated)
? std::max<uint32_t>(sVideoQueueHWAccelSize, MIN_VIDEO_QUEUE_SIZE)
: std::max<uint32_t>(sVideoQueueDefaultSize, MIN_VIDEO_QUEUE_SIZE);
DECODER_LOG("Video decode isAsync=%d HWAccel=%d videoQueueSize=%d",
mReader->IsAsync(),
mInfo.mVideo.mIsHardwareAccelerated,
mAmpleVideoFrames);
mReader->VideoIsHardwareAccelerated(),
GetAmpleVideoFrames());
}
mDecoder->StartProgressUpdates();
@ -3504,6 +3512,14 @@ void MediaDecoderStateMachine::OnAudioSinkError()
DecodeError();
}
uint32_t MediaDecoderStateMachine::GetAmpleVideoFrames() const
{
AssertCurrentThreadInMonitor();
return (mReader->IsAsync() && mReader->VideoIsHardwareAccelerated())
? std::max<uint32_t>(sVideoQueueHWAccelSize, MIN_VIDEO_QUEUE_SIZE)
: std::max<uint32_t>(sVideoQueueDefaultSize, MIN_VIDEO_QUEUE_SIZE);
}
} // namespace mozilla
// avoid redefined macro in unified build

Просмотреть файл

@ -919,10 +919,11 @@ protected:
uint32_t mBufferingWait;
int64_t mLowDataThresholdUsecs;
// If we've got more than mAmpleVideoFrames decoded video frames waiting in
// If we've got more than this number of decoded video frames waiting in
// the video queue, we will not decode any more video frames until some have
// been consumed by the play state machine thread.
uint32_t mAmpleVideoFrames;
// Must hold monitor.
uint32_t GetAmpleVideoFrames() const;
// Low audio threshold. If we've decoded less than this much audio we
// consider our audio decode "behind", and we may skip video decoding
@ -961,7 +962,11 @@ protected:
MOZ_ASSERT(result <= mAmpleAudioThresholdUsecs, "Prerolling will never finish");
return result;
}
uint32_t VideoPrerollFrames() const { return mScheduler->IsRealTime() ? 0 : mAmpleVideoFrames / 2; }
uint32_t VideoPrerollFrames() const
{
return mScheduler->IsRealTime() ? 0 : GetAmpleVideoFrames() / 2;
}
bool DonePrerollingAudio()
{

Просмотреть файл

@ -46,7 +46,6 @@ private:
mDisplay = nsIntSize(aWidth, aHeight);
mStereoMode = StereoMode::MONO;
mHasVideo = aHasVideo;
mIsHardwareAccelerated = false;
// TODO: TrackInfo should be initialized by its specific codec decoder.
// This following call should be removed once we have that implemented.
@ -76,8 +75,6 @@ public:
bool mHasVideo;
TrackInfo mTrackInfo;
bool mIsHardwareAccelerated;
};
class AudioInfo {

Просмотреть файл

@ -33,10 +33,6 @@ void VideoFrameContainer::SetCurrentFrame(const gfxIntSize& aIntrinsicSize,
Image* aImage,
TimeStamp aTargetTime)
{
if (aImage && !aImage->IsValid()) {
return;
}
MutexAutoLock lock(mMutex);
if (aIntrinsicSize != mIntrinsicSize) {

Просмотреть файл

@ -35,6 +35,7 @@ public:
virtual void AllocateMediaResources() MOZ_OVERRIDE;
virtual void ReleaseMediaResources() MOZ_OVERRIDE;
virtual void ReleaseDecoder() MOZ_OVERRIDE;
virtual bool IsHardwareAccelerated() const MOZ_OVERRIDE;
private:
// Will create the required MediaDataDecoder if we have a AVC SPS.
@ -211,6 +212,15 @@ AVCCMediaDataDecoder::CreateDecoderAndInit(mp4_demuxer::MP4Sample* aSample)
return Init();
}
bool
AVCCMediaDataDecoder::IsHardwareAccelerated() const
{
if (mDecoder) {
return mDecoder->IsHardwareAccelerated();
}
return MediaDataDecoder::IsHardwareAccelerated();
}
// AVCCDecoderModule
AVCCDecoderModule::AVCCDecoderModule(PlatformDecoderModule* aPDM)

Просмотреть файл

@ -497,7 +497,6 @@ MP4Reader::ReadMetadata(MediaInfo* aInfo,
NS_ENSURE_TRUE(mVideo.mDecoder != nullptr, NS_ERROR_FAILURE);
nsresult rv = mVideo.mDecoder->Init();
NS_ENSURE_SUCCESS(rv, rv);
mInfo.mVideo.mIsHardwareAccelerated = mVideo.mDecoder->IsHardwareAccelerated();
// Collect telemetry from h264 AVCC SPS.
if (!mFoundSPSForTelemetry) {
@ -1100,4 +1099,10 @@ MP4Reader::SetSharedDecoderManager(SharedDecoderManager* aManager)
#endif
}
bool
MP4Reader::VideoIsHardwareAccelerated() const
{
return mVideo.mDecoder && mVideo.mDecoder->IsHardwareAccelerated();
}
} // namespace mozilla

Просмотреть файл

@ -82,6 +82,8 @@ public:
virtual bool IsAsync() const MOZ_OVERRIDE { return true; }
virtual bool VideoIsHardwareAccelerated() const MOZ_OVERRIDE;
private:
bool InitDemuxer();

Просмотреть файл

@ -75,6 +75,10 @@ public:
virtual nsresult Flush() MOZ_OVERRIDE;
virtual nsresult Drain() MOZ_OVERRIDE;
virtual nsresult Shutdown() MOZ_OVERRIDE;
virtual bool IsHardwareAccelerated() const MOZ_OVERRIDE
{
return true;
}
nsresult OutputFrame(CVPixelBufferRef aImage,
nsAutoPtr<AppleFrameRef> aFrameRef);

Просмотреть файл

@ -41,6 +41,7 @@ AppleVTDecoder::AppleVTDecoder(const mp4_demuxer::VideoDecoderConfig& aConfig,
: AppleVDADecoder(aConfig, aVideoTaskQueue, aCallback, aImageContainer)
, mFormat(nullptr)
, mSession(nullptr)
, mIsHardwareAccelerated(false)
{
MOZ_COUNT_CTOR(AppleVTDecoder);
// TODO: Verify aConfig.mime_type.
@ -314,8 +315,9 @@ AppleVTDecoder::InitializeSession()
if (rv != noErr) {
LOG("AppleVTDecoder: system doesn't support hardware acceleration");
}
mIsHardwareAccelerated = rv == noErr && isUsingHW == kCFBooleanTrue;
LOG("AppleVTDecoder: %s hardware accelerated decoding",
(rv == noErr && isUsingHW == kCFBooleanTrue) ? "using" : "not using");
mIsHardwareAccelerated ? "using" : "not using");
} else {
LOG("AppleVTDecoder: couldn't determine hardware acceleration status.");
}

Просмотреть файл

@ -25,6 +25,10 @@ public:
virtual nsresult Flush() MOZ_OVERRIDE;
virtual nsresult Drain() MOZ_OVERRIDE;
virtual nsresult Shutdown() MOZ_OVERRIDE;
virtual bool IsHardwareAccelerated() const MOZ_OVERRIDE
{
return mIsHardwareAccelerated;
}
private:
CMVideoFormatDescriptionRef mFormat;
@ -37,6 +41,7 @@ private:
nsresult WaitForAsynchronousFrames();
CFDictionaryRef CreateDecoderSpecification();
CFDictionaryRef CreateDecoderExtensions();
bool mIsHardwareAccelerated;
};
} // namespace mozilla

Просмотреть файл

@ -4,7 +4,7 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
SOURCES += [
UNIFIED_SOURCES += [
'MockMediaResource.cpp',
'TestAudioCompactor.cpp',
'TestGMPCrossOrigin.cpp',
@ -16,12 +16,12 @@ SOURCES += [
]
if CONFIG['MOZ_EME']:
SOURCES += [
UNIFIED_SOURCES += [
'TestEME.cpp',
]
if CONFIG['MOZ_WEBM_ENCODER']:
SOURCES += [
UNIFIED_SOURCES += [
'TestVideoTrackEncoder.cpp',
'TestVorbisTrackEncoder.cpp',
'TestWebMWriter.cpp',

Просмотреть файл

@ -334,8 +334,8 @@ MediaSource::Enabled(JSContext* cx, JSObject* aGlobal)
return false;
}
// Check whether it's enabled everywhere or just YouTube.
bool restrict = Preferences::GetBool("media.mediasource.youtubeonly", false);
// Check whether it's enabled everywhere or just whitelisted sites.
bool restrict = Preferences::GetBool("media.mediasource.whitelist", false);
if (!restrict) {
return true;
}
@ -359,7 +359,8 @@ MediaSource::Enabled(JSContext* cx, JSObject* aGlobal)
}
return eTLDplusOne.EqualsLiteral("youtube.com") ||
eTLDplusOne.EqualsLiteral("youtube-nocookie.com");
eTLDplusOne.EqualsLiteral("youtube-nocookie.com") ||
eTLDplusOne.EqualsLiteral("netflix.com");
}
bool

Просмотреть файл

@ -418,6 +418,14 @@ nsRefPtr<ShutdownPromise>
MediaSourceReader::Shutdown()
{
mSeekPromise.RejectIfExists(NS_ERROR_FAILURE, __func__);
// Any previous requests we've been waiting on are now unwanted.
mAudioRequest.DisconnectIfExists();
mVideoRequest.DisconnectIfExists();
// Additionally, reject any outstanding promises _we_ made that we might have
// been waiting on the above to fulfill.
mAudioPromise.RejectIfExists(CANCELED, __func__);
mVideoPromise.RejectIfExists(CANCELED, __func__);
MOZ_ASSERT(mMediaSourceShutdownPromise.IsEmpty());
nsRefPtr<ShutdownPromise> p = mMediaSourceShutdownPromise.Ensure(__func__);

Просмотреть файл

@ -142,10 +142,16 @@ public:
#endif
virtual bool IsAsync() const MOZ_OVERRIDE {
ReentrantMonitorAutoEnter decoderMon(mDecoder->GetReentrantMonitor());
return (!GetAudioReader() || GetAudioReader()->IsAsync()) &&
(!GetVideoReader() || GetVideoReader()->IsAsync());
}
virtual bool VideoIsHardwareAccelerated() const MOZ_OVERRIDE {
ReentrantMonitorAutoEnter decoderMon(mDecoder->GetReentrantMonitor());
return GetVideoReader() && GetVideoReader()->VideoIsHardwareAccelerated();
}
// Returns true if aReader is a currently active audio or video
bool IsActiveReader(MediaDecoderReader* aReader);

Просмотреть файл

@ -47,7 +47,7 @@ nsresult
SourceBufferResource::Read(char* aBuffer, uint32_t aCount, uint32_t* aBytes)
{
SBR_DEBUGV("Read(aBuffer=%p, aCount=%u, aBytes=%p)",
aBytes, aCount, aBytes);
aBuffer, aCount, aBytes);
ReentrantMonitorAutoEnter mon(mMonitor);
return ReadInternal(aBuffer, aCount, aBytes, /* aMayBlock = */ true);
@ -74,7 +74,7 @@ SourceBufferResource::ReadInternal(char* aBuffer, uint32_t aCount, uint32_t* aBy
uint32_t available = GetLength() - readOffset;
uint32_t count = std::min(aCount, available);
SBR_DEBUGV("readOffset=%llu GetLength()=%u available=%u count=%u mEnded=%d",
this, readOffset, GetLength(), available, count, mEnded);
readOffset, GetLength(), available, count, mEnded);
if (available == 0) {
SBR_DEBUGV("reached EOF");
*aBytes = 0;

Просмотреть файл

@ -6,7 +6,7 @@
/*
user_pref("media.mediasource.enabled", true);
user_pref("media.mediasource.youtubeonly", false);
user_pref("media.mediasource.whitelist", false);
*/
function boom()

Просмотреть файл

@ -5,7 +5,7 @@
/*
user_pref("media.mediasource.enabled", true);
user_pref("media.mediasource.youtubeonly", false);
user_pref("media.mediasource.whitelist", false);
*/
function boom()

Просмотреть файл

@ -1,4 +1,4 @@
test-pref(media.mediasource.enabled,true) test-pref(media.mediasource.youtubeonly,false) load 926665.html
test-pref(media.mediasource.enabled,true) test-pref(media.mediasource.youtubeonly,false) load 931388.html
test-pref(media.mediasource.enabled,true) test-pref(media.mediasource.youtubeonly,false) load 1005366.html
test-pref(media.mediasource.enabled,true) test-pref(media.mediasource.youtubeonly,false) load 1059035.html
test-pref(media.mediasource.enabled,true) test-pref(media.mediasource.whitelist,false) load 926665.html
test-pref(media.mediasource.enabled,true) test-pref(media.mediasource.whitelist,false) load 931388.html
test-pref(media.mediasource.enabled,true) test-pref(media.mediasource.whitelist,false) load 1005366.html
test-pref(media.mediasource.enabled,true) test-pref(media.mediasource.whitelist,false) load 1059035.html

Просмотреть файл

@ -19,7 +19,7 @@ function runWithMSE(testFunction) {
addLoadEvent(function () {
SpecialPowers.pushPrefEnv({"set": [
[ "media.mediasource.enabled", true ],
[ "media.mediasource.youtubeonly", false ],
[ "media.mediasource.whitelist", false ],
]},
bootstrapTest);
});

Просмотреть файл

@ -22,7 +22,7 @@ function test() {
SpecialPowers.pushPrefEnv({"set":
[
["media.mediasource.enabled", false],
["media.mediasource.youtubeonly", false],
["media.mediasource.whitelist", false],
]
},
test);

Просмотреть файл

@ -371,8 +371,11 @@ skip-if = buildapp == 'b2g' || toolkit == 'android' || e10s # bug 1043403, bug 1
skip-if = buildapp == 'b2g' || toolkit == 'android' || e10s || (os == 'win' && !debug) # bug 1043403, bug 1057908, bug 1140675
[test_eme_non_fragmented.html]
skip-if = buildapp == 'b2g' || toolkit == 'android' || e10s # bug 1043403, bug 1057908
[test_eme_obs_notification.html]
skip-if = buildapp == 'b2g' || toolkit == 'android' || e10s # bug 1043403, bug 1057908
#[test_eme_obs_notification.html]
#skip-if = buildapp == 'b2g' || toolkit == 'android' || e10s # bug 1043403, bug 1057908
# Disabled (bug 1140778) since this test fails and we don't want to remove the
# functionality being tested by this test. We should still test other observers
# in future however, so I'm not removing the test, just disabling it.
[test_eme_persistent_sessions.html]
skip-if = buildapp == 'b2g' || toolkit == 'android' || e10s # bug 1043403, bug 1057908
[test_eme_playback.html]

Просмотреть файл

@ -54,7 +54,7 @@ addLoadEvent(function() {
SpecialPowers.pushPrefEnv({"set":
[
["media.mediasource.enabled", true],
["media.mediasource.youtubeonly", false],
["media.mediasource.whitelist", false],
]
}, test);
});

Просмотреть файл

@ -28,7 +28,7 @@ addLoadEvent(function() {
SpecialPowers.pushPrefEnv({"set":
[
["media.mediasource.enabled", false],
["media.mediasource.youtubeonly", false],
["media.mediasource.whitelist", false],
]
}, test);
});

Просмотреть файл

@ -93,7 +93,7 @@ function beginTest() {
var prefs = [
[ "media.mediasource.enabled", true ],
[ "media.mediasource.youtubeonly", false ],
[ "media.mediasource.whitelist", false ],
[ "media.mediasource.mp4.enabled", true ],
];

Просмотреть файл

@ -47,7 +47,7 @@ function beginTest() {
var prefs = [
[ "media.mediasource.enabled", true ],
[ "media.mediasource.youtubeonly", false ],
[ "media.mediasource.whitelist", false ],
[ "media.mediasource.mp4.enabled", true ],
];

Просмотреть файл

@ -89,7 +89,7 @@ function beginTest() {
var prefs = [
[ "media.mediasource.enabled", true ],
[ "media.mediasource.youtubeonly", false ],
[ "media.mediasource.whitelist", false ],
[ "media.mediasource.mp4.enabled", true ],
];

Просмотреть файл

@ -61,7 +61,7 @@ function beginTest() {
var prefs = [
[ "media.mediasource.enabled", true ],
[ "media.mediasource.youtubeonly", false ],
[ "media.mediasource.whitelist", false ],
[ "media.mediasource.mp4.enabled", true ],
];

Просмотреть файл

@ -103,7 +103,7 @@ function beginTest() {
var prefs = [
[ "media.mediasource.enabled", true ],
[ "media.mediasource.youtubeonly", false ],
[ "media.mediasource.whitelist", false ],
[ "media.mediasource.mp4.enabled", true ],
];

Просмотреть файл

@ -294,7 +294,7 @@ function beginTest() {
var prefs = [
[ "media.mediasource.enabled", true ],
[ "media.mediasource.youtubeonly", false ],
[ "media.mediasource.whitelist", false ],
[ "media.mediasource.mp4.enabled", true ],
];

Просмотреть файл

@ -78,7 +78,7 @@ function beginTest() {
var prefs = [
[ "media.mediasource.enabled", true ],
[ "media.mediasource.youtubeonly", false ],
[ "media.mediasource.whitelist", false ],
[ "media.mediasource.mp4.enabled", true ],
];

Просмотреть файл

@ -259,7 +259,9 @@ SVGFragmentIdentifier::ProcessFragmentIdentifier(nsIDocument* aDocument,
*rootElement->mCurrentViewID = aAnchorName;
rootElement->mUseCurrentView = true;
rootElement->InvalidateTransformNotifyFrame();
return true;
// not an svgView()-style fragment identifier, return false so the caller
// continues processing to match any :target pseudo elements
return false;
}
bool wasOverridden = !!rootElement->mCurrentViewID;

Просмотреть файл

@ -29,7 +29,9 @@ class SVGFragmentIdentifier
public:
/**
* Process the SVG fragment identifier, if there is one.
* @return true if we found something we recognised
* @return true if we found a valid svgView()-style fragment identifier,
* in which case further processing by the caller can stop. Otherwise return
* false as we may have an ordinary anchor which needs to be :target matched.
*/
static bool ProcessFragmentIdentifier(nsIDocument *aDocument,
const nsAString &aAnchorName);

Просмотреть файл

@ -6,6 +6,11 @@
namespace mozilla {
namespace embedding {
struct CStringKeyValue {
nsCString key;
nsCString value;
};
struct PrintData {
int32_t startPageRange;
int32_t endPageRange;
@ -76,7 +81,17 @@ struct PrintData {
bool isIFrameSelected;
bool isRangeSelection;
/* TODO: OS X specific things - specifically, an array of names for the
/**
* GTK-specific things. Some of these might look like dupes of the
* information we're already passing, but the generalized settings that
* we hold in nsIPrintSettings don't map perfectly to GTK's GtkPrintSettings,
* so there are some nuances. GtkPrintSettings, for example, stores both an
* internal name for paper size, as well as the display name.
*/
CStringKeyValue[] GTKPrintSettings;
/**
* TODO: OS X specific things - specifically, an array of names for the
* document to be supplied by nsIWebBrowserPrint::enumerateDocumentNames
*/
};

Просмотреть файл

@ -87,6 +87,7 @@ public:
explicit BorrowedCGContext(DrawTarget *aDT)
: mDT(aDT)
{
MOZ_ASSERT(aDT, "Caller should check for nullptr");
cg = BorrowCGContextFromDrawTarget(aDT);
}
@ -95,6 +96,7 @@ public:
// time.
CGContextRef Init(DrawTarget *aDT)
{
MOZ_ASSERT(aDT, "Caller should check for nullptr");
MOZ_ASSERT(!mDT, "Can't initialize twice!");
mDT = aDT;
cg = BorrowCGContextFromDrawTarget(aDT);

Просмотреть файл

@ -13,16 +13,10 @@
namespace mozilla {
namespace layers {
// Maximum number of ms we're willing to wait for
// the YUV -> RGB conversion to take before marking
// the texture as invalid.
static const uint32_t kMaxWaitSyncMs = 5;
D3D9SurfaceImage::D3D9SurfaceImage()
: Image(nullptr, ImageFormat::D3D9_RGB32_TEXTURE)
, mSize(0, 0)
, mIsValid(true)
{}
D3D9SurfaceImage::~D3D9SurfaceImage()
@ -142,6 +136,9 @@ D3D9SurfaceImage::SetData(const Data& aData)
hr = device->StretchRect(surface, &src, textureSurface, nullptr, D3DTEXF_NONE);
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
// Flush the draw command now, so that by the time we come to draw this
// image, we're less likely to need to wait for the draw operation to
// complete.
RefPtr<IDirect3DQuery9> query;
hr = device->CreateQuery(D3DQUERYTYPE_EVENT, byRef(query));
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
@ -151,28 +148,34 @@ D3D9SurfaceImage::SetData(const Data& aData)
mTexture = texture;
mShareHandle = shareHandle;
mSize = gfx::IntSize(region.width, region.height);
mQuery = query;
int iterations = 0;
while (true) {
HRESULT hr = query->GetData(nullptr, 0, D3DGETDATA_FLUSH);
if (hr == S_FALSE) {
Sleep(1);
iterations++;
continue;
}
if (FAILED(hr) || iterations >= kMaxWaitSyncMs) {
mIsValid = false;
}
break;
}
return S_OK;
}
bool
D3D9SurfaceImage::IsValid()
void
D3D9SurfaceImage::EnsureSynchronized()
{
return mIsValid;
RefPtr<IDirect3DQuery9> query = mQuery;
if (!query) {
// Not setup, or already synchronized.
return;
}
int iterations = 0;
while (iterations < 10 && S_FALSE == query->GetData(nullptr, 0, D3DGETDATA_FLUSH)) {
Sleep(1);
iterations++;
}
mQuery = nullptr;
}
HANDLE
D3D9SurfaceImage::GetShareHandle()
{
// Ensure the image has completed its synchronization,
// and safe to used by the caller on another device.
EnsureSynchronized();
return mShareHandle;
}
const D3DSURFACE_DESC&
@ -190,6 +193,7 @@ D3D9SurfaceImage::GetSize()
TextureClient*
D3D9SurfaceImage::GetTextureClient(CompositableClient* aClient)
{
EnsureSynchronized();
if (!mTextureClient) {
RefPtr<SharedTextureClientD3D9> textureClient =
new SharedTextureClientD3D9(aClient->GetForwarder(),
@ -212,6 +216,9 @@ D3D9SurfaceImage::GetAsSourceSurface()
return nullptr;
}
// Ensure that the texture is ready to be used.
EnsureSynchronized();
// Readback the texture from GPU memory into system memory, so that
// we can copy it into the Cairo image. This is expensive.
RefPtr<IDirect3DSurface9> textureSurface;

Просмотреть файл

@ -41,6 +41,12 @@ public:
// Returns the description of the shared surface.
const D3DSURFACE_DESC& GetDesc() const;
// Returns the HANDLE that can be used to open the image as a shared resource.
// If the operation to copy the original resource to the shared resource
// hasn't finished yet, this function blocks until the synchronization is
// complete.
HANDLE GetShareHandle();
gfx::IntSize GetSize() MOZ_OVERRIDE;
virtual TemporaryRef<gfx::SourceSurface> GetAsSourceSurface() MOZ_OVERRIDE;
@ -48,16 +54,18 @@ public:
virtual TextureClient* GetTextureClient(CompositableClient* aClient) MOZ_OVERRIDE;
virtual uint8_t* GetBuffer() MOZ_OVERRIDE { return nullptr; }
virtual bool IsValid() MOZ_OVERRIDE;
private:
// Blocks the calling thread until the copy operation started in SetData()
// is complete, whereupon the texture is safe to use.
void EnsureSynchronized();
gfx::IntSize mSize;
RefPtr<IDirect3DTexture9> mTexture;
RefPtr<IDirect3DQuery9> mQuery;
RefPtr<TextureClient> mTextureClient;
HANDLE mShareHandle;
D3DSURFACE_DESC mDesc;
bool mIsValid;
};
} // namepace layers

Просмотреть файл

@ -168,8 +168,6 @@ public:
virtual TemporaryRef<gfx::SourceSurface> GetAsSourceSurface() = 0;
virtual bool IsValid() { return true; }
virtual GrallocImage* AsGrallocImage()
{
return nullptr;

Просмотреть файл

@ -44,13 +44,16 @@ gfxQuartzNativeDrawing::BeginNativeDrawing()
IntSize(mNativeRect.width, mNativeRect.height),
SurfaceFormat::B8G8R8A8);
transform.PostTranslate(-mNativeRect.x, -mNativeRect.y);
mTempDrawTarget->SetTransform(transform);
if (mTempDrawTarget) {
transform.PostTranslate(-mNativeRect.x, -mNativeRect.y);
mTempDrawTarget->SetTransform(transform);
}
dt = mTempDrawTarget;
}
mCGContext = mBorrowedContext.Init(dt);
MOZ_ASSERT(mCGContext);
if (dt) {
mCGContext = mBorrowedContext.Init(dt);
MOZ_ASSERT(mCGContext);
}
return mCGContext;
}

Просмотреть файл

@ -194,14 +194,14 @@ class LifoAlloc
// Append used chunks to the end of this LifoAlloc. We act as if all the
// chunks in |this| are used, even if they're not, so memory may be wasted.
void appendUsed(BumpChunk *start, BumpChunk *latest, BumpChunk *end) {
MOZ_ASSERT(start && latest && end);
void appendUsed(BumpChunk *otherFirst, BumpChunk *otherLatest, BumpChunk *otherLast) {
MOZ_ASSERT(otherFirst && otherLatest && otherLast);
if (last)
last->setNext(start);
last->setNext(otherFirst);
else
first = latest = start;
last = end;
this->latest = latest;
first = otherFirst;
latest = otherLatest;
last = otherLast;
}
void incrementCurSize(size_t size) {

Просмотреть файл

@ -6,6 +6,7 @@
<div>
<object type="image/svg+xml" width="100" height="100" data="fragmentIdentifier-rect-01.svg#limeView" />
<object type="image/svg+xml" width="100" height="100" data="fragmentIdentifier-rect-01.svg#svgView(viewBox(0,200,100,100))" />
<object type="image/svg+xml" width="100" height="100" data="fragmentIdentifier-rect-01.svg#view" />
</div>
<div>
<object type="image/svg+xml" width="100" height="100" data="fragmentIdentifier-rect-01.svg#svgView(viewBox(0,0,100,100);transform(translate(0,200)))" />

Просмотреть файл

@ -1,9 +1,19 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.1"
xmlns:xlink="http://www.w3.org/1999/xlink">
<style>
view:target + a rect {
fill: lime;
}
</style>
<view id="limeView" viewBox="0 200 100 100"/>
<rect fill="red" height="100%" width="100%"/>
<rect fill="lime" x="0" y="200" height="100" width="100"/>
<view id="view" viewBox="200 200 100 100"/>
<a xlink:href="#view">
<rect fill="red" x="200" y="200" height="100" width="100"/>
</a>
</svg>

До

Ширина:  |  Высота:  |  Размер: 270 B

После

Ширина:  |  Высота:  |  Размер: 495 B

Просмотреть файл

@ -10,7 +10,6 @@
#include "gmp-api/gmp-decryption.h"
#include "mozilla/Endian.h"
#include "pk11pub.h"
using namespace mozilla;

Просмотреть файл

@ -395,24 +395,29 @@ Decode6Bit(string& aStr)
}
static bool
DecodeBase64(string& aEncoded, vector<uint8_t>& aOutDecoded)
DecodeBase64KeyOrId(string& aEncoded, vector<uint8_t>& aOutDecoded)
{
if (!Decode6Bit(aEncoded)) {
if (aEncoded.size() != 22 || // Can't decode to 16 byte CENC key or keyId.
!Decode6Bit(aEncoded)) {
return false;
}
// The number of bytes we haven't yet filled in the current byte, mod 8.
int shift = 0;
aOutDecoded.resize(aEncoded.length() * 6 / 8);
aOutDecoded.reserve(aEncoded.length() * 6 / 8 + 1);
auto out = aOutDecoded.begin();
aOutDecoded.resize(16);
vector<uint8_t>::iterator out = aOutDecoded.begin();
for (size_t i = 0; i < aEncoded.length(); i++) {
if (!shift) {
*out = aEncoded[i] << 2;
} else {
*out |= aEncoded[i] >> (6 - shift);
*(++out) = aEncoded[i] << (shift + 2);
out++;
if (out == aOutDecoded.end()) {
// Hit last 6bit octed in encoded, which is padding and can be ignored.
break;
}
*out = aEncoded[i] << (shift + 2);
}
shift = (shift + 2) % 8;
}
@ -423,7 +428,8 @@ DecodeBase64(string& aEncoded, vector<uint8_t>& aOutDecoded)
static bool
DecodeKey(string& aEncoded, Key& aOutDecoded)
{
return DecodeBase64(aEncoded, aOutDecoded) &&
return
DecodeBase64KeyOrId(aEncoded, aOutDecoded) &&
// Key should be 128 bits long.
aOutDecoded.size() == CLEARKEY_KEY_LEN;
}
@ -477,7 +483,7 @@ ParseKeyObject(ParserContext& aCtx, KeyIdPair& aOutKey)
return !key.empty() &&
!keyId.empty() &&
DecodeBase64(keyId, aOutKey.mKeyId) &&
DecodeBase64KeyOrId(keyId, aOutKey.mKeyId) &&
DecodeKey(key, aOutKey.mKey) &&
GetNextSymbol(aCtx) == '}';
}

Просмотреть файл

@ -17,6 +17,7 @@
#include "WMFAACDecoder.h"
#include <algorithm>
#include <stdint.h>
#include <vector>
using std::vector;

Просмотреть файл

@ -15,6 +15,7 @@
*/
#include "WMFH264Decoder.h"
#include <algorithm>
namespace wmf {

Просмотреть файл

@ -55,7 +55,7 @@ LinkMfplat()
static bool sInitOk = false;
if (!sInitDone) {
sInitDone = true;
auto handle = GetModuleHandle("mfplat.dll");
auto handle = GetModuleHandleA("mfplat.dll");
#define MFPLAT_FUNC(_func) \
if (!(_func = (decltype(_func))(GetProcAddress(handle, #_func)))) { \
return false; \
@ -74,9 +74,9 @@ EnsureLibs()
static bool sInitOk = false;
if (!sInitDone) {
sInitOk = LinkMfplat() &&
!!GetModuleHandle("msauddecmft.dll") &&
!!GetModuleHandle("msmpeg2adec.dll") &&
!!GetModuleHandle("msmpeg2vdec.dll");
!!GetModuleHandleA("msauddecmft.dll") &&
!!GetModuleHandleA("msmpeg2adec.dll") &&
!!GetModuleHandleA("msmpeg2vdec.dll");
sInitDone = true;
}
return sInitOk;
@ -183,7 +183,7 @@ CreateMFT(const CLSID& clsid,
const char* aDllName,
CComPtr<IMFTransform>& aOutMFT)
{
HMODULE module = ::GetModuleHandle(aDllName);
HMODULE module = ::GetModuleHandleA(aDllName);
if (!module) {
LOG("Failed to get %S\n", aDllName);
return E_FAIL;

Просмотреть файл

@ -146,6 +146,10 @@ MP4Sample* SampleIterator::GetNext()
sample->crypto.plain_sizes.AppendElement(reader.ReadU16());
sample->crypto.encrypted_sizes.AppendElement(reader.ReadU32());
}
} else {
// No subsample information means the entire sample is encrypted.
sample->crypto.plain_sizes.AppendElement(0);
sample->crypto.encrypted_sizes.AppendElement(sample->size);
}
}

Просмотреть файл

@ -453,9 +453,9 @@ pref("media.mediasource.enabled", false);
#endif
#ifdef RELEASE_BUILD
pref("media.mediasource.youtubeonly", true);
pref("media.mediasource.whitelist", true);
#else
pref("media.mediasource.youtubeonly", false);
pref("media.mediasource.whitelist", false);
#endif // RELEASE_BUILD
pref("media.mediasource.mp4.enabled", true);

Просмотреть файл

@ -3656,3 +3656,5 @@ WebSocketChannel::SaveNetworkStats(bool enforce)
} // namespace mozilla::net
} // namespace mozilla
#undef CLOSE_GOING_AWAY

Просмотреть файл

@ -18,9 +18,7 @@ EXPORTS.mozilla.net += [
'WebSocketChannelParent.h',
]
# These files cannot be built in unified mode because they want to force NSPR
# logging.
SOURCES += [
UNIFIED_SOURCES += [
'BaseWebSocketChannel.cpp',
'WebSocketChannel.cpp',
'WebSocketChannelChild.cpp',

Просмотреть файл

@ -15,9 +15,7 @@ EXPORTS.mozilla.net += [
'WyciwygChannelParent.h',
]
# These files cannot be built in unified mode because they want to force NSPR
# logging.
SOURCES += [
UNIFIED_SOURCES += [
'nsWyciwyg.cpp',
'nsWyciwygChannel.cpp',
'nsWyciwygProtocolHandler.cpp',

Просмотреть файл

@ -161,7 +161,7 @@ user_pref("layout.spammy_warnings.enabled", false);
// Enable Media Source Extensions for testing
user_pref("media.mediasource.enabled", true);
user_pref("media.mediasource.youtubeonly", false);
user_pref("media.mediasource.whitelist", false);
user_pref("media.mediasource.mp4.enabled", true);
user_pref("media.mediasource.webm.enabled", true);

Просмотреть файл

@ -69,22 +69,6 @@ var gSavePrintSettings = false;
var gFocusedElement = null;
var PrintUtils = {
bailOut: function () {
let pref = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefBranch);
let allow_for_testing = false;
try {
allow_for_testing = pref.getBoolPref("print.enable_e10s_testing");
} catch(e) {
// The pref wasn't set, so I guess we're not overriding.
}
if (this.usingRemoteTabs && !allow_for_testing) {
alert("e10s printing is not implemented yet. Bug 927188.");
return true;
}
return false;
},
/**
* Shows the page setup dialog, and saves any settings changed in
* that dialog if print.save_print_settings is set to true.
@ -92,9 +76,6 @@ var PrintUtils = {
* @return true on success, false on failure
*/
showPageSetup: function () {
if (this.bailOut()) {
return;
}
try {
var printSettings = this.getPrintSettings();
var PRINTPROMPTSVC = Components.classes["@mozilla.org/embedcomp/printingprompt-service;1"]
@ -132,10 +113,6 @@ var PrintUtils = {
*/
print: function (aWindow, aBrowser)
{
if (this.bailOut()) {
return;
}
if (!aWindow) {
// If we're using remote browsers, chances are that window.content will
// not be defined.
@ -205,9 +182,6 @@ var PrintUtils = {
*/
printPreview: function (aListenerObj)
{
if (this.bailOut()) {
return;
}
// if we're already in PP mode, don't set the listener; chances
// are it is null because someone is calling printPreview() to
// get us to refresh the display.

Просмотреть файл

@ -80,9 +80,7 @@ nsTArray<nsString>* GlobalPrinters::mGlobalPrinterList = nullptr;
//---------------
nsDeviceContextSpecGTK::nsDeviceContextSpecGTK()
: mPrintJob(nullptr)
, mGtkPrinter(nullptr)
, mGtkPrintSettings(nullptr)
: mGtkPrintSettings(nullptr)
, mGtkPageSetup(nullptr)
{
DO_PR_DEBUG_LOG(("nsDeviceContextSpecGTK::nsDeviceContextSpecGTK()\n"));
@ -120,6 +118,10 @@ NS_IMETHODIMP nsDeviceContextSpecGTK::GetSurfaceForPrinter(gfxASurface **aSurfac
DO_PR_DEBUG_LOG(("\"%s\", %f, %f\n", mPath, width, height));
nsresult rv;
// We shouldn't be attempting to get a surface if we've already got a spool
// file.
MOZ_ASSERT(!mSpoolFile);
// Spool file. Use Glib's temporary file function since we're
// already dependent on the gtk software stack.
gchar *buf;
@ -158,28 +160,19 @@ NS_IMETHODIMP nsDeviceContextSpecGTK::GetSurfaceForPrinter(gfxASurface **aSurfac
format = nsIPrintSettings::kOutputFormatPS;
} else {
const gchar* fmtGTK = gtk_print_settings_get(mGtkPrintSettings, GTK_PRINT_SETTINGS_OUTPUT_FILE_FORMAT);
if (!fmtGTK && GTK_IS_PRINTER(mGtkPrinter)) {
// Likely not print-to-file, check printer's capabilities
// Prior to gtk 2.24, gtk_printer_accepts_pdf() and
// gtk_printer_accepts_ps() always returned true regardless of the
// printer's capability.
if (gtk_major_version > 2 ||
(gtk_major_version == 2 && gtk_minor_version >= 24)) {
format =
gtk_printer_accepts_pdf(mGtkPrinter) ?
static_cast<int16_t>(nsIPrintSettings::kOutputFormatPDF) :
static_cast<int16_t>(nsIPrintSettings::kOutputFormatPS);
if (fmtGTK) {
if (nsDependentCString(fmtGTK).EqualsIgnoreCase("pdf")) {
format = nsIPrintSettings::kOutputFormatPDF;
} else {
format = nsIPrintSettings::kOutputFormatPS;
}
} else if (nsDependentCString(fmtGTK).EqualsIgnoreCase("pdf")) {
format = nsIPrintSettings::kOutputFormatPDF;
} else {
format = nsIPrintSettings::kOutputFormatPS;
}
}
// If we haven't found the format at this point, we're sunk. :(
if (format == nsIPrintSettings::kOutputFormatNative) {
return NS_ERROR_FAILURE;
}
}
if (format == nsIPrintSettings::kOutputFormatPDF) {
@ -217,7 +210,10 @@ NS_IMETHODIMP nsDeviceContextSpecGTK::Init(nsIWidget *aWidget,
(gtk_major_version == 2 && gtk_minor_version < 10))
return NS_ERROR_NOT_AVAILABLE; // I'm so sorry bz
mPrintSettings = aPS;
mPrintSettings = do_QueryInterface(aPS);
if (!mPrintSettings)
return NS_ERROR_NO_INTERFACE;
mIsPPreview = aIsPrintPreview;
// This is only set by embedders
@ -226,13 +222,8 @@ NS_IMETHODIMP nsDeviceContextSpecGTK::Init(nsIWidget *aWidget,
mToPrinter = !toFile && !aIsPrintPreview;
nsCOMPtr<nsPrintSettingsGTK> printSettingsGTK(do_QueryInterface(aPS));
if (!printSettingsGTK)
return NS_ERROR_NO_INTERFACE;
mGtkPrinter = printSettingsGTK->GetGtkPrinter();
mGtkPrintSettings = printSettingsGTK->GetGtkPrintSettings();
mGtkPageSetup = printSettingsGTK->GetGtkPageSetup();
mGtkPrintSettings = mPrintSettings->GetGtkPrintSettings();
mGtkPageSetup = mPrintSettings->GetGtkPageSetup();
// This is a horrible workaround for some printer driver bugs that treat custom page sizes different
// to standard ones. If our paper object matches one of a standard one, use a standard paper size
@ -279,31 +270,81 @@ ns_release_macro(gpointer aData) {
NS_RELEASE(spoolFile);
}
/* static */
gboolean nsDeviceContextSpecGTK::PrinterEnumerator(GtkPrinter *aPrinter,
gpointer aData) {
nsDeviceContextSpecGTK *spec = (nsDeviceContextSpecGTK*)aData;
// Find the printer whose name matches the one inside the settings.
nsXPIDLString printerName;
nsresult rv =
spec->mPrintSettings->GetPrinterName(getter_Copies(printerName));
if (NS_SUCCEEDED(rv) && printerName) {
NS_ConvertUTF16toUTF8 requestedName(printerName);
const char* currentName = gtk_printer_get_name(aPrinter);
if (requestedName.Equals(currentName)) {
nsDeviceContextSpecGTK::StartPrintJob(spec, aPrinter);
return TRUE;
}
}
// We haven't found it yet - keep searching...
return FALSE;
}
/* static */
void nsDeviceContextSpecGTK::StartPrintJob(nsDeviceContextSpecGTK* spec,
GtkPrinter* printer) {
GtkPrintJob* job = gtk_print_job_new(spec->mTitle.get(),
printer,
spec->mGtkPrintSettings,
spec->mGtkPageSetup);
if (!gtk_print_job_set_source_file(job, spec->mSpoolName.get(), nullptr))
return;
NS_ADDREF(spec->mSpoolFile.get());
gtk_print_job_send(job, print_callback, spec->mSpoolFile, ns_release_macro);
}
void
nsDeviceContextSpecGTK::EnumeratePrinters()
{
gtk_enumerate_printers(&nsDeviceContextSpecGTK::PrinterEnumerator, this,
nullptr, TRUE);
}
NS_IMETHODIMP nsDeviceContextSpecGTK::BeginDocument(const nsAString& aTitle, char16_t * aPrintToFileName,
int32_t aStartPage, int32_t aEndPage)
{
if (mToPrinter) {
if (!GTK_IS_PRINTER(mGtkPrinter))
return NS_ERROR_FAILURE;
mPrintJob = gtk_print_job_new(NS_ConvertUTF16toUTF8(aTitle).get(), mGtkPrinter,
mGtkPrintSettings, mGtkPageSetup);
}
mTitle.Truncate();
AppendUTF16toUTF8(aTitle, mTitle);
return NS_OK;
}
NS_IMETHODIMP nsDeviceContextSpecGTK::EndDocument()
{
if (mToPrinter) {
if (!mPrintJob)
return NS_OK; // The operation was aborted.
// At this point, we might have a GtkPrinter set up in nsPrintSettingsGTK,
// or we might not. In the single-process case, we probably will, as this
// is populated by the print settings dialog, or set to the default
// printer.
// In the multi-process case, we proxy the print settings dialog over to
// the parent process, and only get the name of the printer back on the
// content process side. In that case, we need to enumerate the printers
// on the content side, and find a printer with a matching name.
if (!gtk_print_job_set_source_file(mPrintJob, mSpoolName.get(), nullptr))
return NS_ERROR_GFX_PRINTER_COULD_NOT_OPEN_FILE;
NS_ADDREF(mSpoolFile.get());
gtk_print_job_send(mPrintJob, print_callback, mSpoolFile, ns_release_macro);
GtkPrinter* printer = mPrintSettings->GetGtkPrinter();
if (printer) {
// We have a printer, so we can print right away.
nsDeviceContextSpecGTK::StartPrintJob(this, printer);
} else {
// We don't have a printer. We have to enumerate the printers and find
// one with a matching name.
nsCOMPtr<nsIRunnable> event =
NS_NewRunnableMethod(this, &nsDeviceContextSpecGTK::EnumeratePrinters);
NS_DispatchToCurrentThread(event);
}
} else {
// Handle print-to-file ourselves for the benefit of embedders
nsXPIDLString targetPath;

Просмотреть файл

@ -27,6 +27,8 @@ typedef enum
pmPostScript
} PrintMethod;
class nsPrintSettingsGTK;
class nsDeviceContextSpecGTK : public nsIDeviceContextSpec
{
public:
@ -45,22 +47,26 @@ public:
NS_IMETHOD EndPage() MOZ_OVERRIDE { return NS_OK; }
static nsresult GetPrintMethod(const char *aPrinter, PrintMethod &aMethod);
protected:
virtual ~nsDeviceContextSpecGTK();
nsCOMPtr<nsIPrintSettings> mPrintSettings;
nsCOMPtr<nsPrintSettingsGTK> mPrintSettings;
bool mToPrinter : 1; /* If true, print to printer */
bool mIsPPreview : 1; /* If true, is print preview */
char mPath[PATH_MAX]; /* If toPrinter = false, dest file */
char mPrinter[256]; /* Printer name */
GtkPrintJob* mPrintJob;
GtkPrinter* mGtkPrinter;
GtkPrintSettings* mGtkPrintSettings;
GtkPageSetup* mGtkPageSetup;
nsCString mSpoolName;
nsCOMPtr<nsIFile> mSpoolFile;
nsCString mTitle;
private:
void EnumeratePrinters();
static gboolean PrinterEnumerator(GtkPrinter *aPrinter, gpointer aData);
static void StartPrintJob(nsDeviceContextSpecGTK *spec,
GtkPrinter *printer);
};
//-------------------------------------------------------------------------

Просмотреть файл

@ -2,9 +2,11 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsPrintOptionsGTK.h"
#include "nsPrintSettingsGTK.h"
using namespace mozilla::embedding;
/** ---------------------------------------------------
* See documentation in nsPrintOptionsWin.h
@ -23,6 +25,70 @@ nsPrintOptionsGTK::~nsPrintOptionsGTK()
{
}
static void
serialize_gtk_printsettings_to_printdata(const gchar *key,
const gchar *value,
gpointer aData)
{
PrintData* data = (PrintData*)aData;
CStringKeyValue pair;
pair.key() = key;
pair.value() = value;
data->GTKPrintSettings().AppendElement(pair);
}
NS_IMETHODIMP
nsPrintOptionsGTK::SerializeToPrintData(nsIPrintSettings* aSettings,
nsIWebBrowserPrint* aWBP,
PrintData* data)
{
nsresult rv = nsPrintOptions::SerializeToPrintData(aSettings, aWBP, data);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsPrintSettingsGTK> settingsGTK(do_QueryInterface(aSettings));
NS_ENSURE_STATE(settingsGTK);
GtkPrintSettings* gtkPrintSettings = settingsGTK->GetGtkPrintSettings();
NS_ENSURE_STATE(gtkPrintSettings);
gtk_print_settings_foreach(
gtkPrintSettings,
serialize_gtk_printsettings_to_printdata,
data);
return NS_OK;
}
NS_IMETHODIMP
nsPrintOptionsGTK::DeserializeToPrintSettings(const PrintData& data,
nsIPrintSettings* settings)
{
nsCOMPtr<nsPrintSettingsGTK> settingsGTK(do_QueryInterface(settings));
NS_ENSURE_STATE(settingsGTK);
nsresult rv = nsPrintOptions::DeserializeToPrintSettings(data, settings);
NS_ENSURE_SUCCESS(rv, rv);
// Instead of re-using the GtkPrintSettings that nsIPrintSettings is
// wrapping, we'll create a new one to deserialize to and replace it
// within nsIPrintSettings.
GtkPrintSettings* newGtkPrintSettings = gtk_print_settings_new();
for (uint32_t i = 0; i < data.GTKPrintSettings().Length(); ++i) {
CStringKeyValue pair = data.GTKPrintSettings()[i];
gtk_print_settings_set(newGtkPrintSettings,
pair.key().get(),
pair.value().get());
}
settingsGTK->SetGtkPrintSettings(newGtkPrintSettings);
// nsPrintSettingsGTK is holding a reference to newGtkPrintSettings
g_object_unref(newGtkPrintSettings);
newGtkPrintSettings = nullptr;
return NS_OK;
}
/* nsIPrintSettings CreatePrintSettings (); */
nsresult nsPrintOptionsGTK::_CreatePrintSettings(nsIPrintSettings **_retval)
{
@ -35,4 +101,3 @@ nsresult nsPrintOptionsGTK::_CreatePrintSettings(nsIPrintSettings **_retval)
return NS_OK;
}

Просмотреть файл

@ -9,6 +9,13 @@
#include "nsPrintOptionsImpl.h"
namespace mozilla
{
namespace embedding
{
struct PrintData;
} // namespace embedding
} // namespace mozilla
//*****************************************************************************
//*** nsPrintOptions
@ -19,8 +26,13 @@ public:
nsPrintOptionsGTK();
virtual ~nsPrintOptionsGTK();
virtual nsresult _CreatePrintSettings(nsIPrintSettings **_retval);
NS_IMETHODIMP SerializeToPrintData(nsIPrintSettings* aSettings,
nsIWebBrowserPrint* aWBP,
mozilla::embedding::PrintData* data);
NS_IMETHODIMP DeserializeToPrintSettings(const mozilla::embedding::PrintData& data,
nsIPrintSettings* settings);
virtual nsresult _CreatePrintSettings(nsIPrintSettings **_retval);
};

Просмотреть файл

@ -198,8 +198,19 @@ nsPrintSettingsGTK::SetGtkPrinter(GtkPrinter *aPrinter)
{
if (mGTKPrinter)
g_object_unref(mGTKPrinter);
mGTKPrinter = (GtkPrinter*) g_object_ref(aPrinter);
// Prior to gtk 2.24, gtk_printer_accepts_pdf() and
// gtk_printer_accepts_ps() always returned true regardless of the
// printer's capability.
bool shouldTrustGTK =
(gtk_major_version > 2 ||
(gtk_major_version == 2 && gtk_minor_version >= 24));
bool acceptsPDF = shouldTrustGTK && gtk_printer_accepts_pdf(mGTKPrinter);
SetOutputFormat(acceptsPDF ? nsIPrintSettings::kOutputFormatPDF
: nsIPrintSettings::kOutputFormatPS);
}
/**
@ -758,9 +769,11 @@ nsPrintSettingsGTK::SetResolution(int32_t aResolution)
NS_IMETHODIMP
nsPrintSettingsGTK::GetDuplex(int32_t *aDuplex)
{
if (!gtk_print_settings_has_key(mPrintSettings, GTK_PRINT_SETTINGS_DUPLEX))
return NS_ERROR_FAILURE;
*aDuplex = gtk_print_settings_get_duplex(mPrintSettings);
if (!gtk_print_settings_has_key(mPrintSettings, GTK_PRINT_SETTINGS_DUPLEX)) {
*aDuplex = GTK_PRINT_DUPLEX_SIMPLEX;
} else {
*aDuplex = gtk_print_settings_get_duplex(mPrintSettings);
}
return NS_OK;
}