Restore winxp
This commit is contained in:
parent
277045c132
commit
3e27fff9b4
|
@ -4,6 +4,7 @@
|
|||
|
||||
ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
|
||||
ac_add_options --enable-jemalloc
|
||||
ac_add_options --enable-require-all-d3dc-versions
|
||||
|
||||
if [ -f /c/builds/gapi.data ]; then
|
||||
_gapi_keyfile=c:/builds/gapi.data
|
||||
|
|
|
@ -6,6 +6,7 @@ ac_add_options --enable-debug
|
|||
ac_add_options --enable-dmd
|
||||
ac_add_options --enable-profiling # needed for --enable-dmd to work on Windows
|
||||
ac_add_options --enable-verify-mar
|
||||
ac_add_options --enable-require-all-d3dc-versions
|
||||
|
||||
# Needed to enable breakpad in application.ini
|
||||
export MOZILLA_OFFICIAL=1
|
||||
|
|
|
@ -57,6 +57,9 @@ DEFINES += -DMOZ_ANGLE_RENDERER=$(MOZ_ANGLE_RENDERER)
|
|||
ifdef MOZ_D3DCOMPILER_VISTA_DLL
|
||||
DEFINES += -DMOZ_D3DCOMPILER_VISTA_DLL=$(MOZ_D3DCOMPILER_VISTA_DLL)
|
||||
endif
|
||||
ifdef MOZ_D3DCOMPILER_XP_DLL
|
||||
DEFINES += -DMOZ_D3DCOMPILER_XP_DLL=$(MOZ_D3DCOMPILER_XP_DLL)
|
||||
endif
|
||||
endif
|
||||
|
||||
DEFINES += -DMOZ_CHILD_PROCESS_NAME=$(MOZ_CHILD_PROCESS_NAME)
|
||||
|
|
|
@ -574,6 +574,10 @@
|
|||
#ifdef MOZ_D3DCOMPILER_VISTA_DLL
|
||||
@BINPATH@/@MOZ_D3DCOMPILER_VISTA_DLL@
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_D3DCOMPILER_XP_DLL
|
||||
@BINPATH@/@MOZ_D3DCOMPILER_XP_DLL@
|
||||
#endif
|
||||
#endif # MOZ_ANGLE_RENDERER
|
||||
|
||||
; [Browser Chrome Files]
|
||||
|
|
|
@ -43,10 +43,10 @@
|
|||
#ifdef HAVE_64BIT_BUILD
|
||||
!define HAVE_64BIT_BUILD
|
||||
!define ARCH "x64"
|
||||
!define MinSupportedVer "Microsoft Windows 7 x64"
|
||||
!define MinSupportedVer "Microsoft Windows XP x64"
|
||||
#else
|
||||
!define ARCH "x86"
|
||||
!define MinSupportedVer "Microsoft Windows 7"
|
||||
!define MinSupportedVer "Microsoft Windows XP"
|
||||
#endif
|
||||
|
||||
!define MinSupportedCPU "SSE2"
|
||||
|
|
|
@ -1043,7 +1043,7 @@ Function .onInit
|
|||
System::Call "kernel32::IsProcessorFeaturePresent(i 10)i .R7"
|
||||
|
||||
; Windows NT 6.0 and lower are not supported on any architecture.
|
||||
${Unless} ${AtLeastWin7}
|
||||
${Unless} ${AtLeastWinXP}
|
||||
${If} "$R7" == "0"
|
||||
strCpy $R7 "$(WARN_MIN_SUPPORTED_OSVER_CPU_MSG)"
|
||||
${Else}
|
||||
|
|
|
@ -33,12 +33,6 @@ NSDISTMODE = copy
|
|||
|
||||
include $(topsrcdir)/config/config.mk
|
||||
|
||||
ifeq ($(OS_ARCH),WINNT)
|
||||
# Rebuild firefox.exe if the manifest changes - it's included by splash.rc.
|
||||
# (this dependency should really be just for firefox.exe, not other targets)
|
||||
EXTRA_DEPS += $(PROGRAM).manifest
|
||||
endif
|
||||
|
||||
PROGRAMS_DEST = $(DIST)/bin
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
|
|
@ -6,8 +6,6 @@
|
|||
#include <windows.h>
|
||||
#include "nsNativeAppSupportWin.h"
|
||||
|
||||
1 24 "palemoon.exe.manifest"
|
||||
|
||||
IDI_APPICON ICON FIREFOX_ICO
|
||||
IDI_DOCUMENT ICON DOCUMENT_ICO
|
||||
IDI_APPLICATION ICON FIREFOX_ICO
|
||||
|
|
|
@ -186,6 +186,10 @@
|
|||
#ifdef MOZ_D3DCOMPILER_VISTA_DLL
|
||||
@BINPATH@/@MOZ_D3DCOMPILER_VISTA_DLL@
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_D3DCOMPILER_XP_DLL
|
||||
@BINPATH@/@MOZ_D3DCOMPILER_XP_DLL@
|
||||
#endif
|
||||
#endif # MOZ_ANGLE_RENDERER
|
||||
|
||||
; [Browser Chrome Files]
|
||||
|
|
|
@ -43,10 +43,10 @@
|
|||
#ifdef HAVE_64BIT_BUILD
|
||||
!define HAVE_64BIT_BUILD
|
||||
!define ARCH "x64"
|
||||
!define MinSupportedVer "Microsoft Windows 7 x64"
|
||||
!define MinSupportedVer "Microsoft Windows XP x64"
|
||||
#else
|
||||
!define ARCH "x86"
|
||||
!define MinSupportedVer "Microsoft Windows 7"
|
||||
!define MinSupportedVer "Microsoft Windows XP"
|
||||
#endif
|
||||
|
||||
!define MinSupportedCPU "SSE2"
|
||||
|
|
|
@ -1043,7 +1043,7 @@ Function .onInit
|
|||
System::Call "kernel32::IsProcessorFeaturePresent(i 10)i .R7"
|
||||
|
||||
; Windows NT 6.0 and lower are not supported on any architecture.
|
||||
${Unless} ${AtLeastWin7}
|
||||
${Unless} ${AtLeastWinXP}
|
||||
${If} "$R7" == "0"
|
||||
strCpy $R7 "$(WARN_MIN_SUPPORTED_OSVER_CPU_MSG)"
|
||||
${Else}
|
||||
|
|
|
@ -219,6 +219,7 @@ def old_configure_options(*options):
|
|||
'--enable-readline',
|
||||
'--enable-reflow-perf',
|
||||
'--enable-release',
|
||||
'--enable-require-all-d3dc-versions',
|
||||
'--enable-safe-browsing',
|
||||
'--enable-sandbox',
|
||||
'--enable-signmar',
|
||||
|
|
|
@ -194,9 +194,9 @@ def valid_ucrt_sdk_dir(windows_sdk_dir, windows_sdk_dir_env):
|
|||
# contain the Universal CRT SDK. When the main SDK is 8.1, there
|
||||
# is, however, supposed to be a reduced install of the SDK 10
|
||||
# with the UCRT.
|
||||
if version != 'include':
|
||||
sdks[d] = Version(version), sdk
|
||||
continue
|
||||
#if version != 'include':
|
||||
sdks[d] = Version(version), sdk
|
||||
continue
|
||||
if d == windows_sdk_dir_env:
|
||||
# When WINDOWSSDKDIR is set in the environment and we can't find the
|
||||
# Universal CRT SDK, chances are this is a start-shell-msvc*.bat
|
||||
|
|
|
@ -576,9 +576,16 @@ DecoderDoctorDocumentWatcher::SynthesizeAnalysis()
|
|||
// going through expected decoders from most to least desirable.
|
||||
#if defined(XP_WIN)
|
||||
if (!formatsRequiringWMF.IsEmpty()) {
|
||||
DD_INFO("DecoderDoctorDocumentWatcher[%p, doc=%p]::SynthesizeAnalysis() - unplayable formats: %s -> Cannot play media because WMF was not found",
|
||||
this, mDocument, NS_ConvertUTF16toUTF8(formatsRequiringWMF).get());
|
||||
ReportAnalysis(mDocument, sMediaWMFNeeded, false, formatsRequiringWMF);
|
||||
if (IsVistaOrLater()) {
|
||||
DD_INFO("DecoderDoctorDocumentWatcher[%p, doc=%p]::SynthesizeAnalysis() - unplayable formats: %s -> Cannot play media because WMF was not found",
|
||||
this, mDocument, NS_ConvertUTF16toUTF8(formatsRequiringWMF).get());
|
||||
ReportAnalysis(mDocument, sMediaWMFNeeded, false, formatsRequiringWMF);
|
||||
} else {
|
||||
DD_INFO("DecoderDoctorDocumentWatcher[%p, doc=%p]::SynthesizeAnalysis() - unplayable formats: %s -> Cannot play media before Windows Vista",
|
||||
this, mDocument, NS_ConvertUTF16toUTF8(formatsRequiringWMF).get());
|
||||
ReportAnalysis(mDocument, sMediaUnsupportedBeforeWindowsVista,
|
||||
false, formatsRequiringWMF);
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1841,18 +1841,20 @@ MediaManager::GetNonE10sParent()
|
|||
MediaManager::StartupInit()
|
||||
{
|
||||
#ifdef WIN32
|
||||
// Bug 1107702 - Some Windows versions fail in GetAdaptersInfo (and others)
|
||||
// if the first(?) call occurs after the process size is over 2GB (kb/2588507).
|
||||
// Attempt to 'prime' the pump by making a call at startup.
|
||||
unsigned long out_buf_len = sizeof(IP_ADAPTER_INFO);
|
||||
PIP_ADAPTER_INFO pAdapterInfo = (IP_ADAPTER_INFO *) moz_xmalloc(out_buf_len);
|
||||
if (GetAdaptersInfo(pAdapterInfo, &out_buf_len) == ERROR_BUFFER_OVERFLOW) {
|
||||
free(pAdapterInfo);
|
||||
pAdapterInfo = (IP_ADAPTER_INFO *) moz_xmalloc(out_buf_len);
|
||||
GetAdaptersInfo(pAdapterInfo, &out_buf_len);
|
||||
}
|
||||
if (pAdapterInfo) {
|
||||
free(pAdapterInfo);
|
||||
if (IsVistaOrLater() && !IsWin8OrLater()) {
|
||||
// Bug 1107702 - Older Windows fail in GetAdaptersInfo (and others) if the
|
||||
// first(?) call occurs after the process size is over 2GB (kb/2588507).
|
||||
// Attempt to 'prime' the pump by making a call at startup.
|
||||
unsigned long out_buf_len = sizeof(IP_ADAPTER_INFO);
|
||||
PIP_ADAPTER_INFO pAdapterInfo = (IP_ADAPTER_INFO *) moz_xmalloc(out_buf_len);
|
||||
if (GetAdaptersInfo(pAdapterInfo, &out_buf_len) == ERROR_BUFFER_OVERFLOW) {
|
||||
free(pAdapterInfo);
|
||||
pAdapterInfo = (IP_ADAPTER_INFO *) moz_xmalloc(out_buf_len);
|
||||
GetAdaptersInfo(pAdapterInfo, &out_buf_len);
|
||||
}
|
||||
if (pAdapterInfo) {
|
||||
free(pAdapterInfo);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -2078,11 +2080,19 @@ MediaManager::GetUserMedia(nsPIDOMWindowInner* aWindow,
|
|||
case MediaSourceEnum::Application:
|
||||
case MediaSourceEnum::Window:
|
||||
// Deny screensharing request if support is disabled, or
|
||||
// the requesting document is not from a host on the whitelist
|
||||
// the requesting document is not from a host on the whitelist, or
|
||||
// we're on WinXP until proved that it works
|
||||
if (!Preferences::GetBool(((videoType == MediaSourceEnum::Browser)?
|
||||
"media.getusermedia.browser.enabled" :
|
||||
"media.getusermedia.screensharing.enabled"),
|
||||
false) ||
|
||||
#if defined(XP_WIN)
|
||||
(
|
||||
// Allow tab sharing for all platforms including XP
|
||||
(videoType != MediaSourceEnum::Browser) &&
|
||||
!Preferences::GetBool("media.getusermedia.screensharing.allow_on_old_platforms",
|
||||
false) && !IsVistaOrLater()) ||
|
||||
#endif
|
||||
(!privileged && !HostIsHttps(*docURI))) {
|
||||
RefPtr<MediaStreamError> error =
|
||||
new MediaStreamError(aWindow,
|
||||
|
|
|
@ -140,12 +140,26 @@ MediaKeySystemAccess::GetKeySystemStatus(const nsAString& aKeySystem,
|
|||
aOutMessage = NS_LITERAL_CSTRING("Adobe EME disabled");
|
||||
return MediaKeySystemStatus::Cdm_disabled;
|
||||
}
|
||||
#ifdef XP_WIN
|
||||
// Win Vista and later only.
|
||||
if (!IsVistaOrLater()) {
|
||||
aOutMessage = NS_LITERAL_CSTRING("Minimum Windows version (Vista) not met for Adobe EME");
|
||||
return MediaKeySystemStatus::Cdm_not_supported;
|
||||
}
|
||||
#endif
|
||||
return EnsureCDMInstalled(aKeySystem, aOutMessage);
|
||||
}
|
||||
}
|
||||
|
||||
if (IsWidevineKeySystem(aKeySystem)) {
|
||||
if (Preferences::GetBool("media.gmp-widevinecdm.visible", false)) {
|
||||
#ifdef XP_WIN
|
||||
// Win Vista and later only.
|
||||
if (!IsVistaOrLater()) {
|
||||
aOutMessage = NS_LITERAL_CSTRING("Minimum Windows version (Vista) not met for Widevine EME");
|
||||
return MediaKeySystemStatus::Cdm_not_supported;
|
||||
}
|
||||
#endif
|
||||
if (!Preferences::GetBool("media.gmp-widevinecdm.enabled", false)) {
|
||||
aOutMessage = NS_LITERAL_CSTRING("Widevine EME disabled");
|
||||
return MediaKeySystemStatus::Cdm_disabled;
|
||||
|
|
|
@ -1521,6 +1521,11 @@ TEST(GeckoMediaPlugins, GMPPluginVoucher) {
|
|||
|
||||
#if defined(XP_WIN)
|
||||
TEST(GeckoMediaPlugins, GMPOutputProtection) {
|
||||
// Output Protection is not available pre-Vista.
|
||||
if (!IsVistaOrLater()) {
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<GMPStorageTest> runner = new GMPStorageTest();
|
||||
runner->DoTest(&GMPStorageTest::TestOutputProtection);
|
||||
}
|
||||
|
|
|
@ -44,6 +44,10 @@
|
|||
#include "MP4Decoder.h"
|
||||
#include "mozilla/dom/RemoteVideoDecoder.h"
|
||||
|
||||
#ifdef XP_WIN
|
||||
#include "mozilla/WindowsVersion.h"
|
||||
#endif
|
||||
|
||||
#include "mp4_demuxer/H264.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
@ -360,7 +364,16 @@ PDMFactory::CreatePDMs()
|
|||
}
|
||||
#endif
|
||||
#ifdef XP_WIN
|
||||
if (MediaPrefs::PDMWMFEnabled()) {
|
||||
if (MediaPrefs::PDMWMFEnabled() && IsVistaOrLater() && !IsWin7AndPre2000Compatible()) {
|
||||
// *Only* use WMF on Vista and later, as if Firefox is run in Windows 95
|
||||
// compatibility mode on Windows 7 (it does happen!) we may crash trying
|
||||
// to startup WMF. So we need to detect the OS version here, as in
|
||||
// compatibility mode IsVistaOrLater() and friends behave as if we're on
|
||||
// the emulated version of Windows. See bug 1279171.
|
||||
// Additionally, we don't want to start the RemoteDecoderModule if we
|
||||
// expect it's not going to work (i.e. on Windows older than Vista).
|
||||
// IsWin7AndPre2000Compatible() uses GetVersionEx as the user specified OS version can
|
||||
// be reflected when compatibility mode is in effect.
|
||||
m = new WMFDecoderModule();
|
||||
RefPtr<PlatformDecoderModule> remote = new dom::RemoteDecoderModule(m);
|
||||
StartupPDM(remote);
|
||||
|
|
|
@ -7,6 +7,18 @@
|
|||
#ifndef WMF_H_
|
||||
#define WMF_H_
|
||||
|
||||
#if WINVER < _WIN32_WINNT_WIN7
|
||||
#error \
|
||||
You must include WMF.h before including mozilla headers, \
|
||||
otherwise mozconfig.h will be included \
|
||||
and that sets WINVER to WinXP, \
|
||||
which makes Windows Media Foundation unavailable.
|
||||
#endif
|
||||
|
||||
#pragma push_macro("WINVER")
|
||||
#undef WINVER
|
||||
#define WINVER _WIN32_WINNT_WIN7
|
||||
|
||||
#include <windows.h>
|
||||
#include <mfapi.h>
|
||||
#include <mfidl.h>
|
||||
|
@ -23,7 +35,7 @@
|
|||
#include <codecapi.h>
|
||||
|
||||
// The Windows headers helpfully declare min and max macros, which don't
|
||||
// compile in the presence of std::min and std::max and unified builds.
|
||||
// compile in the prescence of std::min and std::max and unified builds.
|
||||
// So undef them here.
|
||||
#ifdef min
|
||||
#undef min
|
||||
|
@ -85,4 +97,8 @@ HRESULT MFCreateDXGISurfaceBuffer(REFIID riid,
|
|||
} // end namespace wmf
|
||||
} // end namespace mozilla
|
||||
|
||||
|
||||
|
||||
#pragma pop_macro("WINVER")
|
||||
|
||||
#endif
|
||||
|
|
|
@ -205,17 +205,31 @@ LoadDLLs()
|
|||
HRESULT
|
||||
MFStartup()
|
||||
{
|
||||
if (!IsVistaOrLater() || IsWin7AndPre2000Compatible()) {
|
||||
// *Only* use WMF on Vista and later, as if Firefox is run in Windows 95
|
||||
// compatibility mode on Windows 7 (it does happen!) we may crash trying
|
||||
// to startup WMF. So we need to detect the OS version here, as in
|
||||
// compatibility mode IsVistaOrLater() and friends behave as if we're on
|
||||
// the emulated version of Windows. See bug 1279171.
|
||||
// Using GetVersionEx API which takes compatibility mode into account.
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
HRESULT hr = LoadDLLs();
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
const int MF_VISTA_VERSION = (0x0001 << 16 | MF_API_VERSION);
|
||||
const int MF_WIN7_VERSION = (0x0002 << 16 | MF_API_VERSION);
|
||||
|
||||
// decltype is unusable for functions having default parameters
|
||||
DECL_FUNCTION_PTR(MFStartup, ULONG, DWORD);
|
||||
ENSURE_FUNCTION_PTR_(MFStartup, Mfplat.dll)
|
||||
return MFStartupPtr(MF_WIN7_VERSION, MFSTARTUP_FULL);
|
||||
if (!IsWin7OrLater())
|
||||
return MFStartupPtr(MF_VISTA_VERSION, MFSTARTUP_FULL);
|
||||
else
|
||||
return MFStartupPtr(MF_WIN7_VERSION, MFSTARTUP_FULL);
|
||||
}
|
||||
|
||||
HRESULT
|
||||
|
|
|
@ -268,7 +268,11 @@ MediaEngineWebRTC::EnumerateVideoDevices(dom::MediaSourceEnum aMediaSource,
|
|||
bool
|
||||
MediaEngineWebRTC::SupportsDuplex()
|
||||
{
|
||||
#ifndef XP_WIN
|
||||
return mFullDuplex;
|
||||
#else
|
||||
return IsVistaOrLater() && mFullDuplex;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -110,10 +110,12 @@ ScaledFontDWrite::ScaledFontDWrite(IDWriteFontFace *aFontFace, Float aSize,
|
|||
, mUseEmbeddedBitmap(aUseEmbeddedBitmap)
|
||||
, mForceGDIMode(aForceGDIMode)
|
||||
{
|
||||
#ifdef USE_SKIA
|
||||
mStyle = SkFontStyle(aStyle->weight,
|
||||
DWriteFontStretchFromStretch(aStyle->stretch),
|
||||
aStyle->style == NS_FONT_STYLE_NORMAL ?
|
||||
SkFontStyle::kUpright_Slant : SkFontStyle::kItalic_Slant);
|
||||
#endif
|
||||
}
|
||||
|
||||
already_AddRefed<Path>
|
||||
|
|
|
@ -9,6 +9,10 @@ ifdef MOZ_D3DCOMPILER_VISTA_DLL_PATH
|
|||
cp -fp "$(MOZ_D3DCOMPILER_VISTA_DLL_PATH)" "$(DIST)/bin"
|
||||
endif
|
||||
|
||||
ifdef MOZ_D3DCOMPILER_XP_CAB
|
||||
expand '$(MOZ_D3DCOMPILER_XP_CAB)' -F:$(MOZ_D3DCOMPILER_XP_DLL) '$(DIST)/bin'
|
||||
endif
|
||||
|
||||
endif
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
|
|
@ -138,6 +138,9 @@ if CONFIG['GNU_CXX']:
|
|||
'-Wno-shadow-local',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_DIRECTX_SDK_PATH'] and not CONFIG['MOZ_HAS_WINSDK_WITH_D3D']:
|
||||
LOCAL_INCLUDES += ['%' + '%s/include/' % CONFIG['MOZ_DIRECTX_SDK_PATH']]
|
||||
|
||||
DEFINES['_CRT_SECURE_NO_DEPRECATE'] = True
|
||||
DEFINES['_HAS_EXCEPTIONS'] = 0
|
||||
|
||||
|
|
|
@ -36,7 +36,6 @@
|
|||
* Carl D. Worth <cworth@cworth.org>
|
||||
* Mathias Hasselmann <mathias.hasselmann@gmx.de>
|
||||
* Behdad Esfahbod <behdad@behdad.org>
|
||||
* Mark Straver <moonchild@palemoon.org>
|
||||
*/
|
||||
|
||||
#ifndef CAIRO_MUTEX_IMPL_PRIVATE_H
|
||||
|
@ -179,24 +178,24 @@
|
|||
#elif defined(_WIN32) /******************************************************/
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
/* We require Windows 7 features */
|
||||
#if !defined(WINVER) || (WINVER < 0x0601)
|
||||
# define WINVER 0x0601
|
||||
/* We require Windows 2000 features such as ETO_PDY */
|
||||
#if !defined(WINVER) || (WINVER < 0x0500)
|
||||
# define WINVER 0x0500
|
||||
#endif
|
||||
#if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0601)
|
||||
# define _WIN32_WINNT 0x0601
|
||||
#if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0500)
|
||||
# define _WIN32_WINNT 0x0500
|
||||
#endif
|
||||
|
||||
# include <windows.h>
|
||||
|
||||
typedef SRWLOCK cairo_mutex_impl_t;
|
||||
typedef CRITICAL_SECTION cairo_mutex_impl_t;
|
||||
|
||||
# define CAIRO_MUTEX_IMPL_WIN32 1
|
||||
# define CAIRO_MUTEX_IMPL_LOCK(mutex) AcquireSRWLockExclusive (&(mutex))
|
||||
# define CAIRO_MUTEX_IMPL_UNLOCK(mutex) ReleaseSRWLockExclusive (&(mutex))
|
||||
# define CAIRO_MUTEX_IMPL_INIT(mutex) InitializeSRWLock (&(mutex))
|
||||
# define CAIRO_MUTEX_IMPL_FINI(mutex) CAIRO_MUTEX_IMPL_NOOP
|
||||
# define CAIRO_MUTEX_IMPL_NIL_INITIALIZER SRWLOCK_INIT
|
||||
# define CAIRO_MUTEX_IMPL_LOCK(mutex) EnterCriticalSection (&(mutex))
|
||||
# define CAIRO_MUTEX_IMPL_UNLOCK(mutex) LeaveCriticalSection (&(mutex))
|
||||
# define CAIRO_MUTEX_IMPL_INIT(mutex) InitializeCriticalSection (&(mutex))
|
||||
# define CAIRO_MUTEX_IMPL_FINI(mutex) DeleteCriticalSection (&(mutex))
|
||||
# define CAIRO_MUTEX_IMPL_NIL_INITIALIZER { NULL, 0, 0, NULL, NULL, 0 }
|
||||
|
||||
#elif defined __OS2__ /******************************************************/
|
||||
|
||||
|
|
|
@ -150,6 +150,8 @@ FINAL_LIBRARY = 'xul'
|
|||
|
||||
if CONFIG['MOZ_D3DCOMPILER_VISTA_DLL']:
|
||||
DEFINES['MOZ_D3DCOMPILER_VISTA_DLL'] = CONFIG['MOZ_D3DCOMPILER_VISTA_DLL']
|
||||
if CONFIG['MOZ_D3DCOMPILER_XP_DLL']:
|
||||
DEFINES['MOZ_D3DCOMPILER_XP_DLL'] = CONFIG['MOZ_D3DCOMPILER_XP_DLL']
|
||||
|
||||
CXXFLAGS += CONFIG['MOZ_CAIRO_CFLAGS']
|
||||
CXXFLAGS += CONFIG['TK_CFLAGS']
|
||||
|
|
|
@ -461,7 +461,8 @@ gfxGDIFont::FillLogFont(LOGFONTW& aLogFont, gfxFloat aSize,
|
|||
weight = mNeedsBold ? 700 : fe->Weight();
|
||||
}
|
||||
|
||||
fe->FillLogFont(&aLogFont, weight, aSize);
|
||||
fe->FillLogFont(&aLogFont, weight, aSize,
|
||||
(mAntialiasOption == kAntialiasSubpixel) ? true : false);
|
||||
|
||||
// If GDI synthetic italic is wanted, force the lfItalic field to true
|
||||
if (aUseGDIFakeItalic) {
|
||||
|
|
|
@ -37,6 +37,11 @@ using namespace mozilla;
|
|||
|
||||
#define ROUND(x) floor((x) + 0.5)
|
||||
|
||||
|
||||
#ifndef CLEARTYPE_QUALITY
|
||||
#define CLEARTYPE_QUALITY 5
|
||||
#endif
|
||||
|
||||
#define LOG_FONTLIST(args) MOZ_LOG(gfxPlatform::GetLog(eGfxLog_fontlist), \
|
||||
LogLevel::Debug, args)
|
||||
#define LOG_FONTLIST_ENABLED() MOZ_LOG_TEST( \
|
||||
|
@ -217,7 +222,16 @@ GDIFontEntry::IsSymbolFont()
|
|||
gfxFont *
|
||||
GDIFontEntry::CreateFontInstance(const gfxFontStyle* aFontStyle, bool aNeedsBold)
|
||||
{
|
||||
return new gfxGDIFont(this, aFontStyle, aNeedsBold);
|
||||
bool isXP = !IsVistaOrLater();
|
||||
|
||||
bool useClearType = isXP && !aFontStyle->systemFont &&
|
||||
(gfxWindowsPlatform::GetPlatform()->UseClearTypeAlways() ||
|
||||
(mIsDataUserFont &&
|
||||
gfxWindowsPlatform::GetPlatform()->UseClearTypeForDownloadableFonts()));
|
||||
|
||||
return new gfxGDIFont(this, aFontStyle, aNeedsBold,
|
||||
(useClearType ? gfxFont::kAntialiasSubpixel
|
||||
: gfxFont::kAntialiasDefault));
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -249,7 +263,8 @@ GDIFontEntry::CopyFontTable(uint32_t aTableTag, nsTArray<uint8_t>& aBuffer)
|
|||
|
||||
void
|
||||
GDIFontEntry::FillLogFont(LOGFONTW *aLogFont,
|
||||
uint16_t aWeight, gfxFloat aSize)
|
||||
uint16_t aWeight, gfxFloat aSize,
|
||||
bool aUseCleartype)
|
||||
{
|
||||
memcpy(aLogFont, &mLogFont, sizeof(LOGFONTW));
|
||||
|
||||
|
@ -275,6 +290,8 @@ GDIFontEntry::FillLogFont(LOGFONTW *aLogFont,
|
|||
if (mIsDataUserFont) {
|
||||
aLogFont->lfItalic = 0;
|
||||
}
|
||||
|
||||
aLogFont->lfQuality = (aUseCleartype ? CLEARTYPE_QUALITY : DEFAULT_QUALITY);
|
||||
}
|
||||
|
||||
#define MISSING_GLYPH 0x1F // glyph index returned for missing characters
|
||||
|
@ -860,8 +877,15 @@ gfxGDIFontList::MakePlatformFont(const nsAString& aFontName,
|
|||
gfxWindowsFontType(isCFF ? GFX_FONT_TYPE_PS_OPENTYPE : GFX_FONT_TYPE_TRUETYPE) /*type*/,
|
||||
aStyle, w, aStretch, winUserFontData, false);
|
||||
|
||||
if (fe) {
|
||||
fe->mIsDataUserFont = true;
|
||||
if (!fe)
|
||||
return fe;
|
||||
|
||||
fe->mIsDataUserFont = true;
|
||||
|
||||
// Uniscribe doesn't place CFF fonts loaded privately
|
||||
// via AddFontMemResourceEx on XP/Vista
|
||||
if (isCFF && !IsWin7OrLater()) {
|
||||
fe->mForceGDI = true;
|
||||
}
|
||||
|
||||
return fe;
|
||||
|
|
|
@ -112,7 +112,8 @@ public:
|
|||
|
||||
virtual bool IsSymbolFont();
|
||||
|
||||
void FillLogFont(LOGFONTW *aLogFont, uint16_t aWeight, gfxFloat aSize);
|
||||
void FillLogFont(LOGFONTW *aLogFont, uint16_t aWeight, gfxFloat aSize,
|
||||
bool aUseCleartype);
|
||||
|
||||
static gfxWindowsFontType DetermineFontType(const NEWTEXTMETRICW& metrics,
|
||||
DWORD fontType)
|
||||
|
|
|
@ -145,6 +145,9 @@ public:
|
|||
|
||||
NS_IMPL_ISUPPORTS(GfxD2DVramReporter, nsIMemoryReporter)
|
||||
|
||||
#define GFX_USE_CLEARTYPE_ALWAYS "gfx.font_rendering.cleartype.always_use_for_content"
|
||||
#define GFX_DOWNLOADABLE_FONTS_USE_CLEARTYPE "gfx.font_rendering.cleartype.use_for_downloadable_fonts"
|
||||
|
||||
#define GFX_CLEARTYPE_PARAMS "gfx.font_rendering.cleartype_params."
|
||||
#define GFX_CLEARTYPE_PARAMS_GAMMA "gfx.font_rendering.cleartype_params.gamma"
|
||||
#define GFX_CLEARTYPE_PARAMS_CONTRAST "gfx.font_rendering.cleartype_params.enhanced_contrast"
|
||||
|
@ -190,6 +193,10 @@ public:
|
|||
HMODULE gdi32Handle;
|
||||
PFND3DKMTQS queryD3DKMTStatistics = nullptr;
|
||||
|
||||
// GPU memory reporting is not available before Windows 7
|
||||
if (!IsWin7OrLater())
|
||||
return NS_OK;
|
||||
|
||||
if ((gdi32Handle = LoadLibrary(TEXT("gdi32.dll"))))
|
||||
queryD3DKMTStatistics = (PFND3DKMTQS)GetProcAddress(gdi32Handle, "D3DKMTQueryStatistics");
|
||||
|
||||
|
@ -312,6 +319,9 @@ NS_IMPL_ISUPPORTS(D3DSharedTexturesReporter, nsIMemoryReporter)
|
|||
gfxWindowsPlatform::gfxWindowsPlatform()
|
||||
: mRenderMode(RENDER_GDI)
|
||||
{
|
||||
mUseClearTypeForDownloadableFonts = UNINITIALIZED_VALUE;
|
||||
mUseClearTypeAlways = UNINITIALIZED_VALUE;
|
||||
|
||||
/*
|
||||
* Initialize COM
|
||||
*/
|
||||
|
@ -391,6 +401,10 @@ gfxWindowsPlatform::CanUseHardwareVideoDecoding()
|
|||
bool
|
||||
gfxWindowsPlatform::InitDWriteSupport()
|
||||
{
|
||||
if (!IsVistaOrLater()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// DWrite is only supported on Windows 7 with the platform update and higher.
|
||||
// We check this by seeing if D2D1 support is available.
|
||||
if (!Factory::SupportsD2D1()) {
|
||||
|
@ -972,6 +986,26 @@ gfxWindowsPlatform::GetPlatformCMSOutputProfile(void* &mem, size_t &mem_size)
|
|||
#endif // _WIN32
|
||||
}
|
||||
|
||||
bool
|
||||
gfxWindowsPlatform::UseClearTypeForDownloadableFonts()
|
||||
{
|
||||
if (mUseClearTypeForDownloadableFonts == UNINITIALIZED_VALUE) {
|
||||
mUseClearTypeForDownloadableFonts = Preferences::GetBool(GFX_DOWNLOADABLE_FONTS_USE_CLEARTYPE, true);
|
||||
}
|
||||
|
||||
return mUseClearTypeForDownloadableFonts;
|
||||
}
|
||||
|
||||
bool
|
||||
gfxWindowsPlatform::UseClearTypeAlways()
|
||||
{
|
||||
if (mUseClearTypeAlways == UNINITIALIZED_VALUE) {
|
||||
mUseClearTypeAlways = Preferences::GetBool(GFX_USE_CLEARTYPE_ALWAYS, false);
|
||||
}
|
||||
|
||||
return mUseClearTypeAlways;
|
||||
}
|
||||
|
||||
void
|
||||
gfxWindowsPlatform::GetDLLVersion(char16ptr_t aDLLPath, nsAString& aVersion)
|
||||
{
|
||||
|
@ -1115,7 +1149,14 @@ gfxWindowsPlatform::FontsPrefsChanged(const char *aPref)
|
|||
|
||||
gfxPlatform::FontsPrefsChanged(aPref);
|
||||
|
||||
if (aPref && !strncmp(GFX_CLEARTYPE_PARAMS, aPref, strlen(GFX_CLEARTYPE_PARAMS))) {
|
||||
if (!aPref) {
|
||||
mUseClearTypeForDownloadableFonts = UNINITIALIZED_VALUE;
|
||||
mUseClearTypeAlways = UNINITIALIZED_VALUE;
|
||||
} else if (!strcmp(GFX_DOWNLOADABLE_FONTS_USE_CLEARTYPE, aPref)) {
|
||||
mUseClearTypeForDownloadableFonts = UNINITIALIZED_VALUE;
|
||||
} else if (!strcmp(GFX_USE_CLEARTYPE_ALWAYS, aPref)) {
|
||||
mUseClearTypeAlways = UNINITIALIZED_VALUE;
|
||||
} else if (!strncmp(GFX_CLEARTYPE_PARAMS, aPref, strlen(GFX_CLEARTYPE_PARAMS))) {
|
||||
SetupClearTypeParams();
|
||||
} else {
|
||||
clearTextFontCaches = false;
|
||||
|
@ -1363,13 +1404,17 @@ gfxWindowsPlatform::InitializeD3D9Config()
|
|||
return;
|
||||
}
|
||||
|
||||
d3d9.SetDefaultFromPref(
|
||||
gfxPrefs::GetLayersAllowD3D9FallbackPrefName(),
|
||||
true,
|
||||
gfxPrefs::GetLayersAllowD3D9FallbackPrefDefault());
|
||||
if (!IsVistaOrLater()) {
|
||||
d3d9.EnableByDefault();
|
||||
} else {
|
||||
d3d9.SetDefaultFromPref(
|
||||
gfxPrefs::GetLayersAllowD3D9FallbackPrefName(),
|
||||
true,
|
||||
gfxPrefs::GetLayersAllowD3D9FallbackPrefDefault());
|
||||
|
||||
if (!d3d9.IsEnabled() && gfxPrefs::LayersPreferD3D9()) {
|
||||
d3d9.UserEnable("Direct3D9 enabled via layers.prefer-d3d9");
|
||||
if (!d3d9.IsEnabled() && gfxPrefs::LayersPreferD3D9()) {
|
||||
d3d9.UserEnable("Direct3D9 enabled via layers.prefer-d3d9");
|
||||
}
|
||||
}
|
||||
|
||||
nsCString message;
|
||||
|
@ -1517,6 +1562,11 @@ gfxWindowsPlatform::InitializeD2DConfig()
|
|||
NS_LITERAL_CSTRING("FEATURE_FAILURE_D2D_D3D11_COMP"));
|
||||
return;
|
||||
}
|
||||
if (!IsVistaOrLater()) {
|
||||
d2d1.DisableByDefault(FeatureStatus::Unavailable, "Direct2D is not available on Windows XP",
|
||||
NS_LITERAL_CSTRING("FEATURE_FAILURE_D2D_XP"));
|
||||
return;
|
||||
}
|
||||
|
||||
d2d1.SetDefaultFromPref(
|
||||
gfxPrefs::GetDirect2DDisabledPrefName(),
|
||||
|
@ -1605,12 +1655,14 @@ gfxWindowsPlatform::InitGPUProcessSupport()
|
|||
"Not using GPU Process since D3D11 is unavailable",
|
||||
NS_LITERAL_CSTRING("FEATURE_FAILURE_NO_D3D11"));
|
||||
} else if (!IsWin7SP1OrLater()) {
|
||||
// On Windows 7 Pre-SP1, DXGI 1.2 is not available and remote presentation
|
||||
// for D3D11 will not work. Rather than take a regression and use D3D9, we
|
||||
// revert back to in-process rendering.
|
||||
// For Windows XP, we simply don't care enough to support this
|
||||
// configuration. On Windows Vista and 7 Pre-SP1, DXGI 1.2 is not
|
||||
// available and remote presentation for D3D11 will not work. Rather
|
||||
// than take a regression and use D3D9, we revert back to in-process
|
||||
// rendering.
|
||||
gpuProc.Disable(
|
||||
FeatureStatus::Unavailable,
|
||||
"Windows 7 Pre-SP1 cannot use the GPU process",
|
||||
"Windows XP, Vista, and 7 Pre-SP1 cannot use the GPU process",
|
||||
NS_LITERAL_CSTRING("FEATURE_FAILURE_OLD_WINDOWS"));
|
||||
} else if (!IsWin8OrLater()) {
|
||||
// Windows 7 SP1 can have DXGI 1.2 only via the Platform Update, so we
|
||||
|
@ -1633,6 +1685,10 @@ gfxWindowsPlatform::InitGPUProcessSupport()
|
|||
bool
|
||||
gfxWindowsPlatform::DwmCompositionEnabled()
|
||||
{
|
||||
if (!IsVistaOrLater()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(WinUtils::dwmIsCompositionEnabledPtr);
|
||||
BOOL dwmEnabled = false;
|
||||
|
||||
|
|
|
@ -183,6 +183,11 @@ public:
|
|||
|
||||
mozilla::gfx::BackendType GetContentBackendFor(mozilla::layers::LayersBackend aLayers) override;
|
||||
|
||||
// ClearType is not always enabled even when available (e.g. Windows XP)
|
||||
// if either of these prefs are enabled and apply, use ClearType rendering
|
||||
bool UseClearTypeForDownloadableFonts();
|
||||
bool UseClearTypeAlways();
|
||||
|
||||
static void GetDLLVersion(char16ptr_t aDLLPath, nsAString& aVersion);
|
||||
|
||||
// returns ClearType tuning information for each display
|
||||
|
@ -239,6 +244,9 @@ protected:
|
|||
protected:
|
||||
RenderMode mRenderMode;
|
||||
|
||||
int8_t mUseClearTypeForDownloadableFonts;
|
||||
int8_t mUseClearTypeAlways;
|
||||
|
||||
private:
|
||||
void Init();
|
||||
void InitAcceleration() override;
|
||||
|
|
|
@ -5,20 +5,45 @@
|
|||
|
||||
#include "Hal.h"
|
||||
#include "HalImpl.h"
|
||||
#include "nsITimer.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/dom/battery/Constants.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
|
||||
#include <windows.h>
|
||||
#include "mozilla/WindowsVersion.h"
|
||||
|
||||
using namespace mozilla::dom::battery;
|
||||
|
||||
namespace mozilla {
|
||||
namespace hal_impl {
|
||||
|
||||
static nsCOMPtr<nsITimer> sUpdateTimer;
|
||||
|
||||
/* Power Event API is Vista or later */
|
||||
static decltype(RegisterPowerSettingNotification)* sRegisterPowerSettingNotification = nullptr;
|
||||
static decltype(UnregisterPowerSettingNotification)* sUnregisterPowerSettingNotification = nullptr;
|
||||
static HPOWERNOTIFY sPowerHandle = nullptr;
|
||||
static HPOWERNOTIFY sCapacityHandle = nullptr;
|
||||
static HWND sHWnd = nullptr;
|
||||
|
||||
static void
|
||||
UpdateHandler(nsITimer* aTimer, void* aClosure) {
|
||||
NS_ASSERTION(!IsVistaOrLater(),
|
||||
"We shouldn't call this function for Vista or later version!");
|
||||
|
||||
static hal::BatteryInformation sLastInfo;
|
||||
hal::BatteryInformation currentInfo;
|
||||
|
||||
hal_impl::GetCurrentBatteryInformation(¤tInfo);
|
||||
if (sLastInfo.level() != currentInfo.level() ||
|
||||
sLastInfo.charging() != currentInfo.charging() ||
|
||||
sLastInfo.remainingTime() != currentInfo.remainingTime()) {
|
||||
hal::NotifyBatteryChange(currentInfo);
|
||||
sLastInfo = currentInfo;
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
LRESULT CALLBACK
|
||||
BatteryWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
|
||||
|
@ -38,56 +63,94 @@ BatteryWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
|
|||
void
|
||||
EnableBatteryNotifications()
|
||||
{
|
||||
// Create custom window to watch battery event
|
||||
// If we can get Gecko's window handle, this is unnecessary.
|
||||
if (IsVistaOrLater()) {
|
||||
// RegisterPowerSettingNotification is from Vista or later.
|
||||
// Use this API if available.
|
||||
HMODULE hUser32 = GetModuleHandleW(L"USER32.DLL");
|
||||
if (!sRegisterPowerSettingNotification)
|
||||
sRegisterPowerSettingNotification = (decltype(RegisterPowerSettingNotification)*)
|
||||
GetProcAddress(hUser32, "RegisterPowerSettingNotification");
|
||||
if (!sUnregisterPowerSettingNotification)
|
||||
sUnregisterPowerSettingNotification = (decltype(UnregisterPowerSettingNotification)*)
|
||||
GetProcAddress(hUser32, "UnregisterPowerSettingNotification");
|
||||
|
||||
if (sHWnd == nullptr) {
|
||||
WNDCLASSW wc;
|
||||
HMODULE hSelf = GetModuleHandle(nullptr);
|
||||
|
||||
if (!GetClassInfoW(hSelf, L"MozillaBatteryClass", &wc)) {
|
||||
ZeroMemory(&wc, sizeof(WNDCLASSW));
|
||||
wc.hInstance = hSelf;
|
||||
wc.lpfnWndProc = BatteryWindowProc;
|
||||
wc.lpszClassName = L"MozillaBatteryClass";
|
||||
RegisterClassW(&wc);
|
||||
if (!sRegisterPowerSettingNotification ||
|
||||
!sUnregisterPowerSettingNotification) {
|
||||
NS_ASSERTION(false, "Canot find PowerSettingNotification functions.");
|
||||
return;
|
||||
}
|
||||
|
||||
sHWnd = CreateWindowW(L"MozillaBatteryClass", L"Battery Watcher",
|
||||
0, 0, 0, 0, 0,
|
||||
nullptr, nullptr, hSelf, nullptr);
|
||||
}
|
||||
// Create custom window to watch battery event
|
||||
// If we can get Gecko's window handle, this is unnecessary.
|
||||
|
||||
if (sHWnd == nullptr) {
|
||||
return;
|
||||
}
|
||||
if (sHWnd == nullptr) {
|
||||
WNDCLASSW wc;
|
||||
HMODULE hSelf = GetModuleHandle(nullptr);
|
||||
|
||||
sPowerHandle =
|
||||
RegisterPowerSettingNotification(sHWnd,
|
||||
&GUID_ACDC_POWER_SOURCE,
|
||||
DEVICE_NOTIFY_WINDOW_HANDLE);
|
||||
sCapacityHandle =
|
||||
RegisterPowerSettingNotification(sHWnd,
|
||||
&GUID_BATTERY_PERCENTAGE_REMAINING,
|
||||
DEVICE_NOTIFY_WINDOW_HANDLE);
|
||||
if (!GetClassInfoW(hSelf, L"MozillaBatteryClass", &wc)) {
|
||||
ZeroMemory(&wc, sizeof(WNDCLASSW));
|
||||
wc.hInstance = hSelf;
|
||||
wc.lpfnWndProc = BatteryWindowProc;
|
||||
wc.lpszClassName = L"MozillaBatteryClass";
|
||||
RegisterClassW(&wc);
|
||||
}
|
||||
|
||||
sHWnd = CreateWindowW(L"MozillaBatteryClass", L"Battery Watcher",
|
||||
0, 0, 0, 0, 0,
|
||||
nullptr, nullptr, hSelf, nullptr);
|
||||
}
|
||||
|
||||
if (sHWnd == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
sPowerHandle =
|
||||
sRegisterPowerSettingNotification(sHWnd,
|
||||
&GUID_ACDC_POWER_SOURCE,
|
||||
DEVICE_NOTIFY_WINDOW_HANDLE);
|
||||
sCapacityHandle =
|
||||
sRegisterPowerSettingNotification(sHWnd,
|
||||
&GUID_BATTERY_PERCENTAGE_REMAINING,
|
||||
DEVICE_NOTIFY_WINDOW_HANDLE);
|
||||
} else
|
||||
{
|
||||
// for Windows XP. If we remove Windows XP support,
|
||||
// we should remove timer-based power notification
|
||||
sUpdateTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
|
||||
if (sUpdateTimer) {
|
||||
sUpdateTimer->InitWithFuncCallback(UpdateHandler,
|
||||
nullptr,
|
||||
Preferences::GetInt("dom.battery.timer",
|
||||
30000 /* 30s */),
|
||||
nsITimer::TYPE_REPEATING_SLACK);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DisableBatteryNotifications()
|
||||
{
|
||||
if (sPowerHandle) {
|
||||
UnregisterPowerSettingNotification(sPowerHandle);
|
||||
sPowerHandle = nullptr;
|
||||
}
|
||||
if (IsVistaOrLater()) {
|
||||
if (sPowerHandle) {
|
||||
sUnregisterPowerSettingNotification(sPowerHandle);
|
||||
sPowerHandle = nullptr;
|
||||
}
|
||||
|
||||
if (sCapacityHandle) {
|
||||
UnregisterPowerSettingNotification(sCapacityHandle);
|
||||
sCapacityHandle = nullptr;
|
||||
}
|
||||
if (sCapacityHandle) {
|
||||
sUnregisterPowerSettingNotification(sCapacityHandle);
|
||||
sCapacityHandle = nullptr;
|
||||
}
|
||||
|
||||
if (sHWnd) {
|
||||
DestroyWindow(sHWnd);
|
||||
sHWnd = nullptr;
|
||||
if (sHWnd) {
|
||||
DestroyWindow(sHWnd);
|
||||
sHWnd = nullptr;
|
||||
}
|
||||
} else
|
||||
{
|
||||
if (sUpdateTimer) {
|
||||
sUpdateTimer->Cancel();
|
||||
sUpdateTimer = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -29,6 +29,11 @@
|
|||
#include "nsContentSecurityManager.h"
|
||||
#include "nsContentUtils.h"
|
||||
|
||||
#ifdef _WIN32_WINNT
|
||||
#undef _WIN32_WINNT
|
||||
#endif
|
||||
#define _WIN32_WINNT 0x0600
|
||||
|
||||
// we need windows.h to read out registry information...
|
||||
#include <windows.h>
|
||||
#include <shellapi.h>
|
||||
|
@ -411,27 +416,41 @@ nsIconChannel::GetStockHIcon(nsIMozIconURI* aIconURI,
|
|||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
uint32_t desiredImageSize;
|
||||
aIconURI->GetImageSize(&desiredImageSize);
|
||||
nsAutoCString stockIcon;
|
||||
aIconURI->GetStockIcon(stockIcon);
|
||||
// We can only do this on Vista or above
|
||||
HMODULE hShellDLL = ::LoadLibraryW(L"shell32.dll");
|
||||
decltype(SHGetStockIconInfo)* pSHGetStockIconInfo =
|
||||
(decltype(SHGetStockIconInfo)*) ::GetProcAddress(hShellDLL,
|
||||
"SHGetStockIconInfo");
|
||||
|
||||
SHSTOCKICONID stockIconID = GetStockIconIDForName(stockIcon);
|
||||
if (stockIconID == SIID_INVALID) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
if (pSHGetStockIconInfo) {
|
||||
uint32_t desiredImageSize;
|
||||
aIconURI->GetImageSize(&desiredImageSize);
|
||||
nsAutoCString stockIcon;
|
||||
aIconURI->GetStockIcon(stockIcon);
|
||||
|
||||
SHSTOCKICONID stockIconID = GetStockIconIDForName(stockIcon);
|
||||
if (stockIconID == SIID_INVALID) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
UINT infoFlags = SHGSI_ICON;
|
||||
infoFlags |= GetSizeInfoFlag(desiredImageSize);
|
||||
|
||||
SHSTOCKICONINFO sii = {0};
|
||||
sii.cbSize = sizeof(sii);
|
||||
HRESULT hr = pSHGetStockIconInfo(stockIconID, infoFlags, &sii);
|
||||
|
||||
if (SUCCEEDED(hr)) {
|
||||
*hIcon = sii.hIcon;
|
||||
} else {
|
||||
rv = NS_ERROR_FAILURE;
|
||||
}
|
||||
} else {
|
||||
rv = NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
UINT infoFlags = SHGSI_ICON;
|
||||
infoFlags |= GetSizeInfoFlag(desiredImageSize);
|
||||
|
||||
SHSTOCKICONINFO sii = {0};
|
||||
sii.cbSize = sizeof(sii);
|
||||
HRESULT hr = SHGetStockIconInfo(stockIconID, infoFlags, &sii);
|
||||
|
||||
if (SUCCEEDED(hr)) {
|
||||
*hIcon = sii.hIcon;
|
||||
} else {
|
||||
rv = NS_ERROR_FAILURE;
|
||||
if (hShellDLL) {
|
||||
::FreeLibrary(hShellDLL);
|
||||
}
|
||||
|
||||
return rv;
|
||||
|
|
|
@ -297,34 +297,43 @@ bool LaunchApp(const std::wstring& cmdline,
|
|||
startup_info.wShowWindow = start_hidden ? SW_HIDE : SW_SHOW;
|
||||
|
||||
LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList = NULL;
|
||||
// Don't even bother trying pre-Vista...
|
||||
if (mozilla::IsVistaOrLater()) {
|
||||
// setup our handle array first - if we end up with no handles that can
|
||||
// be inherited we can avoid trying to do the ThreadAttributeList dance...
|
||||
HANDLE handlesToInherit[2];
|
||||
int handleCount = 0;
|
||||
HANDLE stdOut = ::GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
HANDLE stdErr = ::GetStdHandle(STD_ERROR_HANDLE);
|
||||
|
||||
// setup our handle array first - if we end up with no handles that can
|
||||
// be inherited we can avoid trying to do the ThreadAttributeList dance...
|
||||
HANDLE handlesToInherit[2];
|
||||
int handleCount = 0;
|
||||
HANDLE stdOut = ::GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
HANDLE stdErr = ::GetStdHandle(STD_ERROR_HANDLE);
|
||||
if (IsInheritableHandle(stdOut))
|
||||
handlesToInherit[handleCount++] = stdOut;
|
||||
if (stdErr != stdOut && IsInheritableHandle(stdErr))
|
||||
handlesToInherit[handleCount++] = stdErr;
|
||||
|
||||
if (IsInheritableHandle(stdOut))
|
||||
handlesToInherit[handleCount++] = stdOut;
|
||||
if (stdErr != stdOut && IsInheritableHandle(stdErr))
|
||||
handlesToInherit[handleCount++] = stdErr;
|
||||
|
||||
if (handleCount) {
|
||||
lpAttributeList = CreateThreadAttributeList(handlesToInherit, handleCount);
|
||||
if (lpAttributeList) {
|
||||
// it's safe to inherit handles, so arrange for that...
|
||||
startup_info.cb = sizeof(startup_info_ex);
|
||||
startup_info.dwFlags |= STARTF_USESTDHANDLES;
|
||||
startup_info.hStdOutput = stdOut;
|
||||
startup_info.hStdError = stdErr;
|
||||
startup_info.hStdInput = INVALID_HANDLE_VALUE;
|
||||
startup_info_ex.lpAttributeList = lpAttributeList;
|
||||
dwCreationFlags |= EXTENDED_STARTUPINFO_PRESENT;
|
||||
bInheritHandles = TRUE;
|
||||
if (handleCount) {
|
||||
lpAttributeList = CreateThreadAttributeList(handlesToInherit, handleCount);
|
||||
if (lpAttributeList) {
|
||||
// it's safe to inherit handles, so arrange for that...
|
||||
startup_info.cb = sizeof(startup_info_ex);
|
||||
startup_info.dwFlags |= STARTF_USESTDHANDLES;
|
||||
startup_info.hStdOutput = stdOut;
|
||||
startup_info.hStdError = stdErr;
|
||||
startup_info.hStdInput = INVALID_HANDLE_VALUE;
|
||||
startup_info_ex.lpAttributeList = lpAttributeList;
|
||||
dwCreationFlags |= EXTENDED_STARTUPINFO_PRESENT;
|
||||
bInheritHandles = TRUE;
|
||||
}
|
||||
}
|
||||
} else if (PR_GetEnv("MOZ_WIN_INHERIT_STD_HANDLES_PRE_VISTA")) {
|
||||
// Even if we can't limit what gets inherited, we sometimes want to inherit
|
||||
// stdout/err for testing purposes.
|
||||
startup_info.dwFlags |= STARTF_USESTDHANDLES;
|
||||
startup_info.hStdOutput = ::GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
startup_info.hStdError = ::GetStdHandle(STD_ERROR_HANDLE);
|
||||
startup_info.hStdInput = INVALID_HANDLE_VALUE;
|
||||
bInheritHandles = TRUE;
|
||||
}
|
||||
|
||||
PROCESS_INFORMATION process_info;
|
||||
BOOL createdOK = CreateProcess(NULL,
|
||||
const_cast<wchar_t*>(cmdline.c_str()), NULL, NULL,
|
||||
|
|
|
@ -1034,7 +1034,7 @@ MessageChannel::WaitForSyncNotify(bool aHandleWindowsMessages)
|
|||
MOZ_ASSERT(gUIThreadId, "InitUIThread was not called!");
|
||||
|
||||
#if defined(ACCESSIBILITY)
|
||||
if (mFlags & REQUIRE_A11Y_REENTRY) {
|
||||
if (IsVistaOrLater() && (mFlags & REQUIRE_A11Y_REENTRY)) {
|
||||
MOZ_ASSERT(!(mFlags & REQUIRE_DEFERRED_MESSAGE_PROTECTION));
|
||||
return WaitForSyncNotifyWithA11yReentry();
|
||||
}
|
||||
|
|
|
@ -44,6 +44,13 @@ MainThreadRuntime::MainThreadRuntime()
|
|||
return;
|
||||
}
|
||||
|
||||
// Windows XP doesn't support setting of the COM exception policy, so we'll
|
||||
// just stop here in that case.
|
||||
if (!IsVistaOrLater()) {
|
||||
mInitResult = S_OK;
|
||||
return;
|
||||
}
|
||||
|
||||
// We are required to initialize security in order to configure global options.
|
||||
mInitResult = InitializeSecurity();
|
||||
MOZ_ASSERT(SUCCEEDED(mInitResult));
|
||||
|
@ -60,8 +67,11 @@ MainThreadRuntime::MainThreadRuntime()
|
|||
return;
|
||||
}
|
||||
|
||||
// Use the strictest policy available.
|
||||
ULONG_PTR exceptionSetting = COMGLB_EXCEPTION_DONOT_HANDLE_ANY;
|
||||
// Windows 7 has a policy that is even more strict. We should use that one
|
||||
// whenever possible.
|
||||
ULONG_PTR exceptionSetting = IsWin7OrLater() ?
|
||||
COMGLB_EXCEPTION_DONOT_HANDLE_ANY :
|
||||
COMGLB_EXCEPTION_DONOT_HANDLE;
|
||||
mInitResult = globalOpts->Set(COMGLB_EXCEPTION_HANDLING, exceptionSetting);
|
||||
MOZ_ASSERT(SUCCEEDED(mInitResult));
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ mozilla::Atomic<AutoEnterOOMUnsafeRegion*> AutoEnterOOMUnsafeRegion::owner_;
|
|||
namespace oom {
|
||||
|
||||
JS_PUBLIC_DATA(uint32_t) targetThread = 0;
|
||||
MOZ_THREAD_LOCAL(uint32_t) threadType;
|
||||
JS_PUBLIC_DATA(MOZ_THREAD_LOCAL(uint32_t)) threadType;
|
||||
JS_PUBLIC_DATA(uint64_t) maxAllocations = UINT64_MAX;
|
||||
JS_PUBLIC_DATA(uint64_t) counter = 0;
|
||||
JS_PUBLIC_DATA(bool) failAlways = true;
|
||||
|
|
|
@ -143,7 +143,7 @@ MOZ_TOOL_VARIABLES
|
|||
dnl Special win32 checks
|
||||
dnl ========================================================
|
||||
|
||||
WINVER=601
|
||||
WINVER=502
|
||||
|
||||
case "$target" in
|
||||
*-mingw*)
|
||||
|
@ -206,6 +206,10 @@ case "$target" in
|
|||
|
||||
# -Zc:sizedDealloc- disables C++14 global sized deallocation (see bug 1160146)
|
||||
CXXFLAGS="$CXXFLAGS -Zc:sizedDealloc-"
|
||||
|
||||
# Disable C++11 thread-safe statics due to crashes on XP (bug 1204752)
|
||||
# See https://connect.microsoft.com/VisualStudio/feedback/details/1789709/visual-c-2015-runtime-broken-on-windows-server-2003-c-11-magic-statics
|
||||
CXXFLAGS="$CXXFLAGS -Zc:threadSafeInit-"
|
||||
;;
|
||||
esac
|
||||
AC_SUBST(MSVS_VERSION)
|
||||
|
@ -717,7 +721,11 @@ case "$target" in
|
|||
IMPORT_LIB_SUFFIX=lib
|
||||
MKSHLIB='$(LD) -NOLOGO -DLL -OUT:$@ -PDB:$(LINK_PDBFILE) $(DSO_LDOPTS)'
|
||||
MKCSHLIB='$(LD) -NOLOGO -DLL -OUT:$@ -PDB:$(LINK_PDBFILE) $(DSO_LDOPTS)'
|
||||
WIN32_SUBSYSTEM_VERSION=6.01
|
||||
dnl Set subsystem version.
|
||||
WIN32_SUBSYSTEM_VERSION=5.01
|
||||
if test "$CPU_ARCH" = "x86_64"; then
|
||||
WIN32_SUBSYSTEM_VERSION=5.02
|
||||
fi
|
||||
WIN32_CONSOLE_EXE_LDFLAGS=-SUBSYSTEM:CONSOLE,$WIN32_SUBSYSTEM_VERSION
|
||||
WIN32_GUI_EXE_LDFLAGS=-SUBSYSTEM:WINDOWS,$WIN32_SUBSYSTEM_VERSION
|
||||
DSO_LDOPTS=-SUBSYSTEM:WINDOWS,$WIN32_SUBSYSTEM_VERSION
|
||||
|
|
|
@ -28,34 +28,342 @@
|
|||
_InterlockedIncrement((volatile long*)(addend))
|
||||
#endif
|
||||
|
||||
// Windows XP and Server 2003 don't support condition variables natively. The
|
||||
// NativeImports class is responsible for detecting native support and
|
||||
// retrieving the appropriate function pointers. It gets instantiated once,
|
||||
// using a static initializer.
|
||||
class ConditionVariableNativeImports
|
||||
{
|
||||
public:
|
||||
ConditionVariableNativeImports() {
|
||||
HMODULE kernel32_dll = GetModuleHandle("kernel32.dll");
|
||||
MOZ_RELEASE_ASSERT(kernel32_dll != NULL);
|
||||
|
||||
#define LOAD_SYMBOL(symbol) loadSymbol(kernel32_dll, #symbol, symbol)
|
||||
supported_ = LOAD_SYMBOL(InitializeConditionVariable) &&
|
||||
LOAD_SYMBOL(WakeConditionVariable) &&
|
||||
LOAD_SYMBOL(WakeAllConditionVariable) &&
|
||||
LOAD_SYMBOL(SleepConditionVariableCS);
|
||||
#undef LOAD_SYMBOL
|
||||
}
|
||||
|
||||
inline bool supported() const {
|
||||
return supported_;
|
||||
}
|
||||
|
||||
void(WINAPI* InitializeConditionVariable)(CONDITION_VARIABLE* ConditionVariable);
|
||||
void(WINAPI* WakeAllConditionVariable)(PCONDITION_VARIABLE ConditionVariable);
|
||||
void(WINAPI* WakeConditionVariable)(CONDITION_VARIABLE* ConditionVariable);
|
||||
BOOL(WINAPI* SleepConditionVariableCS)(CONDITION_VARIABLE* ConditionVariable,
|
||||
CRITICAL_SECTION* CriticalSection,
|
||||
DWORD dwMilliseconds);
|
||||
|
||||
private:
|
||||
template <typename T>
|
||||
inline bool loadSymbol(HMODULE module, const char* name, T& fn) {
|
||||
FARPROC ptr = GetProcAddress(module, name);
|
||||
if (!ptr)
|
||||
return false;
|
||||
|
||||
fn = reinterpret_cast<T>(ptr);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool supported_;
|
||||
};
|
||||
|
||||
static ConditionVariableNativeImports sNativeImports;
|
||||
|
||||
// Wrapper for native condition variable APIs.
|
||||
struct ConditionVariableNative
|
||||
{
|
||||
inline void initialize() {
|
||||
sNativeImports.InitializeConditionVariable(&cv_);
|
||||
}
|
||||
|
||||
inline void destroy() {
|
||||
// Native condition variables don't require cleanup.
|
||||
}
|
||||
|
||||
inline void notify_one() { sNativeImports.WakeConditionVariable(&cv_); }
|
||||
|
||||
inline void notify_all() { sNativeImports.WakeAllConditionVariable(&cv_); }
|
||||
|
||||
inline bool wait(CRITICAL_SECTION* cs, DWORD msec) {
|
||||
return sNativeImports.SleepConditionVariableCS(&cv_, cs, msec);
|
||||
}
|
||||
|
||||
private:
|
||||
CONDITION_VARIABLE cv_;
|
||||
};
|
||||
|
||||
// Fallback condition variable support for Windows XP and Server 2003. Given the
|
||||
// difficulty of testing on these antiquated platforms and their rapidly
|
||||
// diminishing market share, this implementation trades performance for
|
||||
// predictable behavior.
|
||||
struct ConditionVariableFallback
|
||||
{
|
||||
static const uint32_t WAKEUP_MODE_NONE = 0;
|
||||
static const uint32_t WAKEUP_MODE_ONE = 0x40000000;
|
||||
static const uint32_t WAKEUP_MODE_ALL = 0x80000000;
|
||||
|
||||
static const uint32_t WAKEUP_MODE_MASK = WAKEUP_MODE_ONE | WAKEUP_MODE_ALL;
|
||||
static const uint32_t SLEEPERS_COUNT_MASK = ~WAKEUP_MODE_MASK;
|
||||
|
||||
void initialize()
|
||||
{
|
||||
// Initialize the state variable to 0 sleepers, no wakeup.
|
||||
sleepersCountAndWakeupMode_ = 0 | WAKEUP_MODE_NONE;
|
||||
|
||||
// Create a semaphore that prevents threads from entering sleep,
|
||||
// or waking other threads while a wakeup is ongoing.
|
||||
sleepWakeupSemaphore_ = CreateSemaphoreW(NULL, 1, 1, NULL);
|
||||
MOZ_RELEASE_ASSERT(sleepWakeupSemaphore_);
|
||||
|
||||
// Use an auto-reset event for waking up a single sleeper.
|
||||
wakeOneEvent_ = CreateEventW(NULL, FALSE, FALSE, NULL);
|
||||
MOZ_RELEASE_ASSERT(wakeOneEvent_);
|
||||
|
||||
// Use a manual-reset event for waking up all sleepers.
|
||||
wakeAllEvent_ = CreateEventW(NULL, TRUE, FALSE, NULL);
|
||||
MOZ_RELEASE_ASSERT(wakeAllEvent_);
|
||||
}
|
||||
|
||||
void destroy()
|
||||
{
|
||||
BOOL r;
|
||||
|
||||
MOZ_RELEASE_ASSERT(sleepersCountAndWakeupMode_ == (0 | WAKEUP_MODE_NONE));
|
||||
|
||||
r = CloseHandle(sleepWakeupSemaphore_);
|
||||
MOZ_RELEASE_ASSERT(r);
|
||||
|
||||
r = CloseHandle(wakeOneEvent_);
|
||||
MOZ_RELEASE_ASSERT(r);
|
||||
|
||||
r = CloseHandle(wakeAllEvent_);
|
||||
MOZ_RELEASE_ASSERT(r);
|
||||
}
|
||||
|
||||
private:
|
||||
void wakeup(uint32_t wakeupMode, HANDLE wakeEvent)
|
||||
{
|
||||
// Ensure that only one thread at a time can wake up others.
|
||||
BOOL result = WaitForSingleObject(sleepWakeupSemaphore_, INFINITE);
|
||||
MOZ_RELEASE_ASSERT(result == WAIT_OBJECT_0);
|
||||
|
||||
// Atomically set the wakeup mode and retrieve the number of sleepers.
|
||||
uint32_t wcwm = InterlockedExchangeAdd(&sleepersCountAndWakeupMode_,
|
||||
wakeupMode);
|
||||
uint32_t sleepersCount = wcwm & SLEEPERS_COUNT_MASK;
|
||||
MOZ_RELEASE_ASSERT((wcwm & WAKEUP_MODE_MASK) == WAKEUP_MODE_NONE);
|
||||
|
||||
if (sleepersCount > 0) {
|
||||
// If there are any sleepers, set the wake event. The (last) woken
|
||||
// up thread is responsible for releasing the semaphore.
|
||||
BOOL success = SetEvent(wakeEvent);
|
||||
MOZ_RELEASE_ASSERT(success);
|
||||
|
||||
} else {
|
||||
// If there are no sleepers, set the wakeup mode back to 'none'
|
||||
// and release the semaphore ourselves.
|
||||
sleepersCountAndWakeupMode_ = 0 | WAKEUP_MODE_NONE;
|
||||
|
||||
BOOL success = ReleaseSemaphore(sleepWakeupSemaphore_, 1, NULL);
|
||||
MOZ_RELEASE_ASSERT(success);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
void notify_one() { wakeup(WAKEUP_MODE_ONE, wakeOneEvent_); }
|
||||
|
||||
void notify_all() { wakeup(WAKEUP_MODE_ALL, wakeAllEvent_); }
|
||||
|
||||
bool wait(CRITICAL_SECTION* userLock, DWORD msec)
|
||||
{
|
||||
// Make sure that we can't enter sleep when there are other threads
|
||||
// that still need to wake up on either of the wake events being set.
|
||||
DWORD result = WaitForSingleObject(sleepWakeupSemaphore_, INFINITE);
|
||||
MOZ_RELEASE_ASSERT(result == WAIT_OBJECT_0);
|
||||
|
||||
// Register ourselves as a sleeper. Use an atomic operation, because
|
||||
// if another thread times out at the same time, it will decrement the
|
||||
// sleepers count without acquiring the semaphore.
|
||||
uint32_t wcwm = InterlockedIncrement(&sleepersCountAndWakeupMode_);
|
||||
MOZ_RELEASE_ASSERT((wcwm & WAKEUP_MODE_MASK) == WAKEUP_MODE_NONE);
|
||||
|
||||
// Now that that this thread has been enlisted as a sleeper, it is safe
|
||||
// again for other threads to do a wakeup.
|
||||
BOOL success = ReleaseSemaphore(sleepWakeupSemaphore_, 1, NULL);
|
||||
MOZ_RELEASE_ASSERT(success);
|
||||
|
||||
// Release the caller's mutex.
|
||||
LeaveCriticalSection(userLock);
|
||||
|
||||
// Wait for either event to become signaled, which happens when
|
||||
// notify_one() or notify_all() is called, or for a timeout.
|
||||
HANDLE handles[2] = { wakeOneEvent_, wakeAllEvent_ };
|
||||
DWORD waitResult = WaitForMultipleObjects(2, handles, FALSE, msec);
|
||||
MOZ_RELEASE_ASSERT(waitResult == WAIT_OBJECT_0 ||
|
||||
waitResult == WAIT_OBJECT_0 + 1 ||
|
||||
(waitResult == WAIT_TIMEOUT && msec != INFINITE));
|
||||
|
||||
// Atomically decrease the sleepers count and retrieve the wakeup mode
|
||||
// and new sleepers count.
|
||||
// If the wait returned because wakeOneEvent_ was set, we are certain
|
||||
// that the wakeup mode will be WAKEUP_MODE_ONE. In that case,
|
||||
// atomically reset the wakeup mode to 'none', because if another
|
||||
// thread's sleep times out at same time and it finds that it was the
|
||||
// last sleeper, it decides whether or not to reset the wakeOneEvent_
|
||||
// based on the current wakeup mode.
|
||||
uint32_t sub;
|
||||
if (waitResult == WAIT_OBJECT_0)
|
||||
sub = 1 | WAKEUP_MODE_ONE;
|
||||
else
|
||||
sub = 1;
|
||||
// Note that InterlockedExchangeAdd returns the old value, but it's
|
||||
// easier to work with the new value.
|
||||
wcwm = InterlockedExchangeAdd(&sleepersCountAndWakeupMode_, -sub) - sub;
|
||||
|
||||
uint32_t wakeupMode = wcwm & WAKEUP_MODE_MASK;
|
||||
uint32_t sleepersCount = wcwm & SLEEPERS_COUNT_MASK;
|
||||
|
||||
bool releaseSleepWakeupSemaphore = false;
|
||||
|
||||
if (waitResult == WAIT_OBJECT_0) {
|
||||
// The wake-one event is an auto-reset event so if we're woken by
|
||||
// it, it should already have been reset. We also already removed
|
||||
// the WAKEUP_MODE_ONE bit so the wakeup mode should now be 'none'
|
||||
// again.
|
||||
MOZ_RELEASE_ASSERT(wakeupMode == WAKEUP_MODE_NONE);
|
||||
|
||||
// The signaling thread has acquired the enter-wakeup semaphore and
|
||||
// expects the woken (this) thread to release it again.
|
||||
releaseSleepWakeupSemaphore = true;
|
||||
|
||||
} else if (waitResult == WAIT_TIMEOUT && wakeupMode == WAKEUP_MODE_ONE &&
|
||||
sleepersCount == 0) {
|
||||
// In theory a race condition is possible where the last sleeper
|
||||
// times out right at the moment that another thread signals it.
|
||||
// If that just happened we now have a dangling signal event and
|
||||
// mode, but no threads to be woken up by it, and we need to clean
|
||||
// that up.
|
||||
BOOL success = ResetEvent(wakeOneEvent_);
|
||||
MOZ_RELEASE_ASSERT(success);
|
||||
|
||||
// This is safe - we are certain there are no other sleepers that
|
||||
// could wake up right now, and the semaphore ensures that no
|
||||
// non-sleeping threads are messing with
|
||||
// sleepersCountAndWakeupMode_.
|
||||
sleepersCountAndWakeupMode_ = 0 | WAKEUP_MODE_NONE;
|
||||
|
||||
// The signaling thread has acquired the sleep-wakeup semaphore and
|
||||
// expects the woken thread to release it. But since there are no
|
||||
// sleeping threads left this thread will do it instead.
|
||||
releaseSleepWakeupSemaphore = true;
|
||||
|
||||
} else if (wakeupMode == WAKEUP_MODE_ALL && sleepersCount == 0) {
|
||||
// If this was the last thread waking up in response to a
|
||||
// notify_all, clear the wakeup mode and reset the wake-all event.
|
||||
// A race condition similar to the case described above could
|
||||
// occur, so waitResult could be WAIT_TIMEOUT, but that doesn't
|
||||
// matter for the actions that need to be taken.
|
||||
MOZ_RELEASE_ASSERT(waitResult = WAIT_OBJECT_0 + 1 ||
|
||||
waitResult == WAIT_TIMEOUT);
|
||||
|
||||
BOOL success = ResetEvent(wakeAllEvent_);
|
||||
MOZ_RELEASE_ASSERT(success);
|
||||
|
||||
sleepersCountAndWakeupMode_ = 0 | WAKEUP_MODE_NONE;
|
||||
|
||||
// The broadcasting thread has acquired the enter-wakeup semaphore
|
||||
// and expects the last thread that wakes up to release it.
|
||||
releaseSleepWakeupSemaphore = true;
|
||||
|
||||
} else if ((waitResult == WAIT_TIMEOUT && msec != INFINITE) ||
|
||||
(waitResult == WAIT_OBJECT_0 + 1 &&
|
||||
wakeupMode == WAKEUP_MODE_ALL)) {
|
||||
// Either:
|
||||
// * The wait timed out but found no active notify_one or notify_all
|
||||
// the moment it decreased the wait count.
|
||||
// * A notify_all woke up this thread but there are more threads
|
||||
// that need to be woken up by the wake-all event.
|
||||
// These are ordinary conditions in which we don't have to do
|
||||
// anything.
|
||||
|
||||
} else {
|
||||
MOZ_CRASH("invalid wakeup condition");
|
||||
}
|
||||
|
||||
// Release the enter-wakeup semaphore if the wakeup condition requires
|
||||
// us to do it.
|
||||
if (releaseSleepWakeupSemaphore) {
|
||||
BOOL success = ReleaseSemaphore(sleepWakeupSemaphore_, 1, NULL);
|
||||
MOZ_RELEASE_ASSERT(success);
|
||||
}
|
||||
|
||||
// Reacquire the user mutex.
|
||||
EnterCriticalSection(userLock);
|
||||
|
||||
// Return true if woken up, false when timed out.
|
||||
if (waitResult == WAIT_TIMEOUT) {
|
||||
SetLastError(ERROR_TIMEOUT);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
uint32_t sleepersCountAndWakeupMode_;
|
||||
HANDLE sleepWakeupSemaphore_;
|
||||
HANDLE wakeOneEvent_;
|
||||
HANDLE wakeAllEvent_;
|
||||
};
|
||||
|
||||
struct js::ConditionVariable::PlatformData
|
||||
{
|
||||
CONDITION_VARIABLE cv_;
|
||||
union
|
||||
{
|
||||
ConditionVariableNative native;
|
||||
ConditionVariableFallback fallback;
|
||||
};
|
||||
};
|
||||
|
||||
js::ConditionVariable::ConditionVariable()
|
||||
{
|
||||
InitializeConditionVariable(&platformData()->cv_);
|
||||
if (sNativeImports.supported())
|
||||
platformData()->native.initialize();
|
||||
else
|
||||
platformData()->fallback.initialize();
|
||||
}
|
||||
|
||||
void
|
||||
js::ConditionVariable::notify_one()
|
||||
{
|
||||
WakeConditionVariable(&platformData()->cv_);
|
||||
if (sNativeImports.supported())
|
||||
platformData()->native.notify_one();
|
||||
else
|
||||
platformData()->fallback.notify_one();
|
||||
}
|
||||
|
||||
void
|
||||
js::ConditionVariable::notify_all()
|
||||
{
|
||||
WakeAllConditionVariable(&platformData()->cv_);
|
||||
if (sNativeImports.supported())
|
||||
platformData()->native.notify_all();
|
||||
else
|
||||
platformData()->fallback.notify_all();
|
||||
}
|
||||
|
||||
void
|
||||
js::ConditionVariable::wait(UniqueLock<Mutex>& lock)
|
||||
{
|
||||
SRWLOCK* srwlock = &lock.lock.platformData()->lock;
|
||||
bool r = SleepConditionVariableSRW(&platformData()->cv_, srwlock, INFINITE, 0);
|
||||
CRITICAL_SECTION* cs = &lock.lock.platformData()->criticalSection;
|
||||
bool r;
|
||||
if (sNativeImports.supported())
|
||||
r = platformData()->native.wait(cs, INFINITE);
|
||||
else
|
||||
r = platformData()->fallback.wait(cs, INFINITE);
|
||||
MOZ_RELEASE_ASSERT(r);
|
||||
}
|
||||
|
||||
|
@ -70,7 +378,7 @@ js::CVStatus
|
|||
js::ConditionVariable::wait_for(UniqueLock<Mutex>& lock,
|
||||
const mozilla::TimeDuration& rel_time)
|
||||
{
|
||||
SRWLOCK* srwlock = &lock.lock.platformData()->lock;
|
||||
CRITICAL_SECTION* cs = &lock.lock.platformData()->criticalSection;
|
||||
|
||||
// Note that DWORD is unsigned, so we have to be careful to clamp at 0.
|
||||
// If rel_time is Forever, then ToMilliseconds is +inf, which evaluates as
|
||||
|
@ -82,7 +390,11 @@ js::ConditionVariable::wait_for(UniqueLock<Mutex>& lock,
|
|||
? INFINITE
|
||||
: static_cast<DWORD>(msecd);
|
||||
|
||||
BOOL r = SleepConditionVariableSRW(&platformData()->cv_, srwlock, msec, 0);
|
||||
BOOL r;
|
||||
if (sNativeImports.supported())
|
||||
r = platformData()->native.wait(cs, msec);
|
||||
else
|
||||
r = platformData()->fallback.wait(cs, msec);
|
||||
if (r)
|
||||
return CVStatus::NoTimeout;
|
||||
MOZ_RELEASE_ASSERT(GetLastError() == ERROR_TIMEOUT);
|
||||
|
@ -91,7 +403,10 @@ js::ConditionVariable::wait_for(UniqueLock<Mutex>& lock,
|
|||
|
||||
js::ConditionVariable::~ConditionVariable()
|
||||
{
|
||||
// Native condition variables don't require cleanup.
|
||||
if (sNativeImports.supported())
|
||||
platformData()->native.destroy();
|
||||
else
|
||||
platformData()->fallback.destroy();
|
||||
}
|
||||
|
||||
inline js::ConditionVariable::PlatformData*
|
||||
|
|
|
@ -13,6 +13,35 @@
|
|||
#include "threading/Mutex.h"
|
||||
#include "threading/windows/MutexPlatformData.h"
|
||||
|
||||
namespace {
|
||||
|
||||
// We build with a toolkit that supports WinXP, so we have to probe
|
||||
// for modern features at runtime. This is necessary because Vista and
|
||||
// later automatically allocate and subsequently leak a debug info
|
||||
// object for each critical section that we allocate unless we tell it
|
||||
// not to. In order to tell it not to, we need the extra flags field
|
||||
// provided by the Ex version of InitializeCriticalSection.
|
||||
struct MutexNativeImports
|
||||
{
|
||||
using InitializeCriticalSectionExT = BOOL (WINAPI*)(CRITICAL_SECTION*, DWORD, DWORD);
|
||||
InitializeCriticalSectionExT InitializeCriticalSectionEx;
|
||||
|
||||
MutexNativeImports() {
|
||||
HMODULE kernel32_dll = GetModuleHandle("kernel32.dll");
|
||||
MOZ_RELEASE_ASSERT(kernel32_dll != NULL);
|
||||
InitializeCriticalSectionEx = reinterpret_cast<InitializeCriticalSectionExT>(
|
||||
GetProcAddress(kernel32_dll, "InitializeCriticalSectionEx"));
|
||||
}
|
||||
|
||||
bool hasInitializeCriticalSectionEx() const {
|
||||
return InitializeCriticalSectionEx;
|
||||
}
|
||||
};
|
||||
|
||||
static MutexNativeImports NativeImports;
|
||||
|
||||
} // (anonymous namespace)
|
||||
|
||||
js::detail::MutexImpl::MutexImpl()
|
||||
{
|
||||
AutoEnterOOMUnsafeRegion oom;
|
||||
|
@ -20,7 +49,18 @@ js::detail::MutexImpl::MutexImpl()
|
|||
if (!platformData_)
|
||||
oom.crash("js::Mutex::Mutex");
|
||||
|
||||
InitializeSRWLock(&platformData()->lock);
|
||||
// This number was adopted from NSPR.
|
||||
const static DWORD LockSpinCount = 1500;
|
||||
BOOL r;
|
||||
if (NativeImports.hasInitializeCriticalSectionEx()) {
|
||||
r = NativeImports.InitializeCriticalSectionEx(&platformData()->criticalSection,
|
||||
LockSpinCount,
|
||||
CRITICAL_SECTION_NO_DEBUG_INFO);
|
||||
} else {
|
||||
r = InitializeCriticalSectionAndSpinCount(&platformData()->criticalSection,
|
||||
LockSpinCount);
|
||||
}
|
||||
MOZ_RELEASE_ASSERT(r);
|
||||
}
|
||||
|
||||
js::detail::MutexImpl::~MutexImpl()
|
||||
|
@ -28,17 +68,18 @@ js::detail::MutexImpl::~MutexImpl()
|
|||
if (!platformData_)
|
||||
return;
|
||||
|
||||
DeleteCriticalSection(&platformData()->criticalSection);
|
||||
js_delete(platformData());
|
||||
}
|
||||
|
||||
void
|
||||
js::detail::MutexImpl::lock()
|
||||
{
|
||||
AcquireSRWLockExclusive(&platformData()->lock);
|
||||
EnterCriticalSection(&platformData()->criticalSection);
|
||||
}
|
||||
|
||||
void
|
||||
js::detail::MutexImpl::unlock()
|
||||
{
|
||||
ReleaseSRWLockExclusive(&platformData()->lock);
|
||||
LeaveCriticalSection(&platformData()->criticalSection);
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
struct js::detail::MutexImpl::PlatformData
|
||||
{
|
||||
SRWLOCK lock;
|
||||
CRITICAL_SECTION criticalSection;
|
||||
};
|
||||
|
||||
#endif // platform_win_MutexPlatformData_h
|
||||
|
|
|
@ -70,6 +70,8 @@ struct OperatingSystemVersionInfo {
|
|||
|
||||
// Os version identities used in the -moz-os-version media query.
|
||||
const OperatingSystemVersionInfo osVersionStrings[] = {
|
||||
{ LookAndFeel::eOperatingSystemVersion_WindowsXP, L"windows-xp" },
|
||||
{ LookAndFeel::eOperatingSystemVersion_WindowsVista, L"windows-vista" },
|
||||
{ LookAndFeel::eOperatingSystemVersion_Windows7, L"windows-win7" },
|
||||
{ LookAndFeel::eOperatingSystemVersion_Windows8, L"windows-win8" },
|
||||
{ LookAndFeel::eOperatingSystemVersion_Windows10, L"windows-win10" }
|
||||
|
|
|
@ -204,6 +204,9 @@
|
|||
|
||||
#ifdef MOZ_MEMORY_WINDOWS
|
||||
|
||||
/* Some defines from the CRT internal headers that we need here. */
|
||||
#define _CRT_SPINCOUNT 5000
|
||||
#define __crtInitCritSecAndSpinCount InitializeCriticalSectionAndSpinCount
|
||||
#include <io.h>
|
||||
#include <windows.h>
|
||||
#include <intrin.h>
|
||||
|
@ -592,8 +595,8 @@ void *_mmap(void *addr, size_t length, int prot, int flags,
|
|||
* issues in some cases.
|
||||
*/
|
||||
#if defined(MOZ_MEMORY_WINDOWS)
|
||||
#define malloc_mutex_t SRWLOCK
|
||||
#define malloc_spinlock_t SRWLOCK
|
||||
#define malloc_mutex_t CRITICAL_SECTION
|
||||
#define malloc_spinlock_t CRITICAL_SECTION
|
||||
#elif defined(MOZ_MEMORY_DARWIN)
|
||||
typedef struct {
|
||||
OSSpinLock lock;
|
||||
|
@ -1558,7 +1561,8 @@ static bool
|
|||
malloc_mutex_init(malloc_mutex_t *mutex)
|
||||
{
|
||||
#if defined(MOZ_MEMORY_WINDOWS)
|
||||
InitializeSRWLock(mutex);
|
||||
if (! __crtInitCritSecAndSpinCount(mutex, _CRT_SPINCOUNT))
|
||||
return (true);
|
||||
#elif defined(MOZ_MEMORY_DARWIN)
|
||||
mutex->lock = OS_SPINLOCK_INIT;
|
||||
#elif defined(MOZ_MEMORY_LINUX) && !defined(MOZ_MEMORY_ANDROID)
|
||||
|
@ -1587,7 +1591,7 @@ malloc_mutex_lock(malloc_mutex_t *mutex)
|
|||
{
|
||||
|
||||
#if defined(MOZ_MEMORY_WINDOWS)
|
||||
AcquireSRWLockExclusive(mutex);
|
||||
EnterCriticalSection(mutex);
|
||||
#elif defined(MOZ_MEMORY_DARWIN)
|
||||
OSSpinLockLock(&mutex->lock);
|
||||
#elif defined(MOZ_MEMORY)
|
||||
|
@ -1602,7 +1606,7 @@ malloc_mutex_unlock(malloc_mutex_t *mutex)
|
|||
{
|
||||
|
||||
#if defined(MOZ_MEMORY_WINDOWS)
|
||||
ReleaseSRWLockExclusive(mutex);
|
||||
LeaveCriticalSection(mutex);
|
||||
#elif defined(MOZ_MEMORY_DARWIN)
|
||||
OSSpinLockUnlock(&mutex->lock);
|
||||
#elif defined(MOZ_MEMORY)
|
||||
|
@ -1619,7 +1623,8 @@ static bool
|
|||
malloc_spin_init(malloc_spinlock_t *lock)
|
||||
{
|
||||
#if defined(MOZ_MEMORY_WINDOWS)
|
||||
InitializeSRWLock(lock);
|
||||
if (! __crtInitCritSecAndSpinCount(lock, _CRT_SPINCOUNT))
|
||||
return (true);
|
||||
#elif defined(MOZ_MEMORY_DARWIN)
|
||||
lock->lock = OS_SPINLOCK_INIT;
|
||||
#elif defined(MOZ_MEMORY_LINUX) && !defined(MOZ_MEMORY_ANDROID)
|
||||
|
@ -1646,7 +1651,7 @@ malloc_spin_lock(malloc_spinlock_t *lock)
|
|||
{
|
||||
|
||||
#if defined(MOZ_MEMORY_WINDOWS)
|
||||
AcquireSRWLockExclusive(lock);
|
||||
EnterCriticalSection(lock);
|
||||
#elif defined(MOZ_MEMORY_DARWIN)
|
||||
OSSpinLockLock(&lock->lock);
|
||||
#elif defined(MOZ_MEMORY)
|
||||
|
@ -1660,7 +1665,7 @@ static inline void
|
|||
malloc_spin_unlock(malloc_spinlock_t *lock)
|
||||
{
|
||||
#if defined(MOZ_MEMORY_WINDOWS)
|
||||
ReleaseSRWLockExclusive(lock);
|
||||
LeaveCriticalSection(lock);
|
||||
#elif defined(MOZ_MEMORY_DARWIN)
|
||||
OSSpinLockUnlock(&lock->lock);
|
||||
#elif defined(MOZ_MEMORY)
|
||||
|
|
|
@ -9,7 +9,20 @@
|
|||
#ifndef mozilla_ThreadLocal_h
|
||||
#define mozilla_ThreadLocal_h
|
||||
|
||||
#if !defined(XP_WIN)
|
||||
#if defined(XP_WIN)
|
||||
// This file will get included in any file that wants to add a profiler mark.
|
||||
// In order to not bring <windows.h> together we could include windef.h and
|
||||
// winbase.h which are sufficient to get the prototypes for the Tls* functions.
|
||||
// # include <windef.h>
|
||||
// # include <winbase.h>
|
||||
// Unfortunately, even including these headers causes us to add a bunch of ugly
|
||||
// stuff to our namespace e.g #define CreateEvent CreateEventW
|
||||
extern "C" {
|
||||
__declspec(dllimport) void* __stdcall TlsGetValue(unsigned long);
|
||||
__declspec(dllimport) int __stdcall TlsSetValue(unsigned long, void*);
|
||||
__declspec(dllimport) unsigned long __stdcall TlsAlloc();
|
||||
}
|
||||
#else
|
||||
# include <pthread.h>
|
||||
# include <signal.h>
|
||||
#endif
|
||||
|
@ -31,7 +44,7 @@ typedef sig_atomic_t sig_safe_t;
|
|||
|
||||
namespace detail {
|
||||
|
||||
#if defined(HAVE_THREAD_TLS_KEYWORD) || defined(XP_WIN) || defined(XP_MACOSX)
|
||||
#if defined(HAVE_THREAD_TLS_KEYWORD)
|
||||
#define MOZ_HAS_THREAD_LOCAL
|
||||
#endif
|
||||
|
||||
|
@ -78,7 +91,11 @@ template<typename T>
|
|||
class ThreadLocal
|
||||
{
|
||||
#ifndef MOZ_HAS_THREAD_LOCAL
|
||||
#if defined(XP_WIN)
|
||||
typedef unsigned long key_t;
|
||||
#else
|
||||
typedef pthread_key_t key_t;
|
||||
#endif
|
||||
|
||||
// Integral types narrower than void* must be extended to avoid
|
||||
// warnings from valgrind on some platforms. This helper type
|
||||
|
@ -144,7 +161,12 @@ ThreadLocal<T>::init()
|
|||
return true;
|
||||
#else
|
||||
if (!initialized()) {
|
||||
#ifdef XP_WIN
|
||||
mKey = TlsAlloc();
|
||||
mInited = mKey != 0xFFFFFFFFUL; // TLS_OUT_OF_INDEXES
|
||||
#else
|
||||
mInited = !pthread_key_create(&mKey, nullptr);
|
||||
#endif
|
||||
}
|
||||
return mInited;
|
||||
#endif
|
||||
|
@ -159,7 +181,11 @@ ThreadLocal<T>::get() const
|
|||
#else
|
||||
MOZ_ASSERT(initialized());
|
||||
void* h;
|
||||
#ifdef XP_WIN
|
||||
h = TlsGetValue(mKey);
|
||||
#else
|
||||
h = pthread_getspecific(mKey);
|
||||
#endif
|
||||
return static_cast<T>(reinterpret_cast<typename Helper<T>::Type>(h));
|
||||
#endif
|
||||
}
|
||||
|
@ -173,7 +199,11 @@ ThreadLocal<T>::set(const T aValue)
|
|||
#else
|
||||
MOZ_ASSERT(initialized());
|
||||
void* h = reinterpret_cast<void*>(static_cast<typename Helper<T>::Type>(aValue));
|
||||
#ifdef XP_WIN
|
||||
bool succeeded = TlsSetValue(mKey, h);
|
||||
#else
|
||||
bool succeeded = !pthread_setspecific(mKey, h);
|
||||
#endif
|
||||
if (!succeeded) {
|
||||
MOZ_CRASH();
|
||||
}
|
||||
|
@ -181,11 +211,7 @@ ThreadLocal<T>::set(const T aValue)
|
|||
}
|
||||
|
||||
#ifdef MOZ_HAS_THREAD_LOCAL
|
||||
#if defined(XP_WIN) || defined(XP_MACOSX)
|
||||
#define MOZ_THREAD_LOCAL(TYPE) thread_local mozilla::detail::ThreadLocal<TYPE>
|
||||
#else
|
||||
#define MOZ_THREAD_LOCAL(TYPE) __thread mozilla::detail::ThreadLocal<TYPE>
|
||||
#endif
|
||||
#else
|
||||
#define MOZ_THREAD_LOCAL(TYPE) mozilla::detail::ThreadLocal<TYPE>
|
||||
#endif
|
||||
|
|
|
@ -156,6 +156,41 @@ IsNotWin7PreRTM()
|
|||
IsWindowsBuildOrLater(7600);
|
||||
}
|
||||
|
||||
MOZ_ALWAYS_INLINE bool
|
||||
IsWin7AndPre2000Compatible() {
|
||||
/*
|
||||
* See Bug 1279171.
|
||||
* We'd like to avoid using WMF on specific OS version when compatibility
|
||||
* mode is in effect. The purpose of this function is to check if FF runs on
|
||||
* Win7 OS with application compatibility mode being set to 95/98/ME.
|
||||
* Those compatibility mode options (95/98/ME) can only display and
|
||||
* be selected for 32-bit application.
|
||||
* If the compatibility mode is in effect, the GetVersionEx function will
|
||||
* report the OS as it identifies itself, which may not be the OS that is
|
||||
* installed.
|
||||
* Note : 1) We only target for Win7 build number greater than 7600.
|
||||
* 2) GetVersionEx may be altered or unavailable for release after
|
||||
* Win8.1. Set pragma to avoid build warning as error.
|
||||
*/
|
||||
bool isWin7 = IsNotWin7PreRTM() && !IsWin8OrLater();
|
||||
if (!isWin7) {
|
||||
return false;
|
||||
}
|
||||
|
||||
OSVERSIONINFOEX info;
|
||||
ZeroMemory(&info, sizeof(OSVERSIONINFOEX));
|
||||
|
||||
info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4996)
|
||||
bool success = GetVersionEx((LPOSVERSIONINFO) &info);
|
||||
#pragma warning(pop)
|
||||
if (!success) {
|
||||
return false;
|
||||
}
|
||||
return info.dwMajorVersion < 5;
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif /* mozilla_WindowsVersion_h */
|
||||
|
|
|
@ -156,8 +156,41 @@ static CRITICAL_SECTION sTimeStampLock;
|
|||
// Kept in [mt]
|
||||
static ULONGLONG sFaultIntoleranceCheckpoint = 0;
|
||||
|
||||
// Used only when GetTickCount64 is not available on the platform.
|
||||
// Last result of GetTickCount call.
|
||||
//
|
||||
// Kept in [ms]
|
||||
static DWORD sLastGTCResult = 0;
|
||||
|
||||
// Higher part of the 64-bit value of MozGetTickCount64,
|
||||
// incremented atomically.
|
||||
static DWORD sLastGTCRollover = 0;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
typedef ULONGLONG (WINAPI* GetTickCount64_t)();
|
||||
static GetTickCount64_t sGetTickCount64 = nullptr;
|
||||
|
||||
// Function protecting GetTickCount result from rolling over,
|
||||
// result is in [ms]
|
||||
static ULONGLONG WINAPI
|
||||
MozGetTickCount64()
|
||||
{
|
||||
DWORD GTC = ::GetTickCount();
|
||||
|
||||
// Cheaper then CMPXCHG8B
|
||||
AutoCriticalSection lock(&sTimeStampLock);
|
||||
|
||||
// Pull the rollover counter forward only if new value of GTC goes way
|
||||
// down under the last saved result
|
||||
if ((sLastGTCResult > GTC) && ((sLastGTCResult - GTC) > (1UL << 30))) {
|
||||
++sLastGTCRollover;
|
||||
}
|
||||
|
||||
sLastGTCResult = GTC;
|
||||
return ULONGLONG(sLastGTCRollover) << 32 | sLastGTCResult;
|
||||
}
|
||||
|
||||
// Result is in [mt]
|
||||
static inline ULONGLONG
|
||||
PerformanceCounter()
|
||||
|
@ -322,7 +355,7 @@ TimeStampValue::CheckQPC(const TimeStampValue& aOther) const
|
|||
if (duration < sHardFailureLimit) {
|
||||
// Interval between the two time stamps is very short, consider
|
||||
// QPC as unstable and record a failure.
|
||||
uint64_t now = ms2mt(GetTickCount64());
|
||||
uint64_t now = ms2mt(sGetTickCount64());
|
||||
|
||||
AutoCriticalSection lock(&sTimeStampLock);
|
||||
|
||||
|
@ -452,6 +485,16 @@ TimeStamp::Startup()
|
|||
|
||||
gInitialized = true;
|
||||
|
||||
HMODULE kernelDLL = GetModuleHandleW(L"kernel32.dll");
|
||||
sGetTickCount64 = reinterpret_cast<GetTickCount64_t>(
|
||||
GetProcAddress(kernelDLL, "GetTickCount64"));
|
||||
if (!sGetTickCount64) {
|
||||
// If the platform does not support the GetTickCount64 (Windows XP doesn't),
|
||||
// then use our fallback implementation based on GetTickCount.
|
||||
sGetTickCount64 = MozGetTickCount64;
|
||||
}
|
||||
|
||||
|
||||
InitializeCriticalSectionAndSpinCount(&sTimeStampLock, kLockSpinCount);
|
||||
|
||||
sHasStableTSC = HasStableTSC();
|
||||
|
@ -490,7 +533,7 @@ TimeStamp::Now(bool aHighResolution)
|
|||
|
||||
// Both values are in [mt] units.
|
||||
ULONGLONG QPC = useQPC ? PerformanceCounter() : uint64_t(0);
|
||||
ULONGLONG GTC = ms2mt(GetTickCount64());
|
||||
ULONGLONG GTC = ms2mt(sGetTickCount64());
|
||||
return TimeStamp(TimeStampValue(GTC, QPC, useQPC));
|
||||
}
|
||||
|
||||
|
|
|
@ -161,7 +161,7 @@ dnl ========================================================
|
|||
dnl Special win32 checks
|
||||
dnl ========================================================
|
||||
|
||||
WINVER=601
|
||||
WINVER=502
|
||||
|
||||
case "$target" in
|
||||
*-mingw*)
|
||||
|
@ -215,6 +215,10 @@ case "$target" in
|
|||
|
||||
# -Zc:sizedDealloc- disables C++14 global sized deallocation (see bug 1160146)
|
||||
CXXFLAGS="$CXXFLAGS -Zc:sizedDealloc-"
|
||||
|
||||
# Disable C++11 thread-safe statics due to crashes on XP (bug 1204752)
|
||||
# See https://connect.microsoft.com/VisualStudio/feedback/details/1789709/visual-c-2015-runtime-broken-on-windows-server-2003-c-11-magic-statics
|
||||
CXXFLAGS="$CXXFLAGS -Zc:threadSafeInit-"
|
||||
|
||||
# C4752: We explicitly use AVX instructions in only some libs, not global
|
||||
# This is a pointless "helpful warning" to use /arch:AVX which we don't want.
|
||||
|
@ -947,7 +951,11 @@ case "$target" in
|
|||
IMPORT_LIB_SUFFIX=lib
|
||||
MKSHLIB='$(LD) -NOLOGO -DLL -OUT:$@ -PDB:$(LINK_PDBFILE) $(DSO_LDOPTS)'
|
||||
MKCSHLIB='$(LD) -NOLOGO -DLL -OUT:$@ -PDB:$(LINK_PDBFILE) $(DSO_LDOPTS)'
|
||||
WIN32_SUBSYSTEM_VERSION=6.01
|
||||
dnl Set subsystem version.
|
||||
WIN32_SUBSYSTEM_VERSION=5.01
|
||||
if test "$CPU_ARCH" = "x86_64"; then
|
||||
WIN32_SUBSYSTEM_VERSION=5.02
|
||||
fi
|
||||
WIN32_CONSOLE_EXE_LDFLAGS=-SUBSYSTEM:CONSOLE,$WIN32_SUBSYSTEM_VERSION
|
||||
WIN32_GUI_EXE_LDFLAGS=-SUBSYSTEM:WINDOWS,$WIN32_SUBSYSTEM_VERSION
|
||||
DSO_LDOPTS=-SUBSYSTEM:WINDOWS,$WIN32_SUBSYSTEM_VERSION
|
||||
|
@ -3192,6 +3200,9 @@ MOZ_D3D_CPU_SUFFIX=
|
|||
MOZ_HAS_WINSDK_WITH_D3D=
|
||||
MOZ_D3DCOMPILER_VISTA_DLL=
|
||||
MOZ_D3DCOMPILER_VISTA_DLL_PATH=
|
||||
MOZ_DIRECTX_SDK_PATH=
|
||||
MOZ_D3DCOMPILER_XP_DLL=
|
||||
MOZ_D3DCOMPILER_XP_CAB=
|
||||
|
||||
if test "$COMPILE_ENVIRONMENT" ; then
|
||||
case "$target_os" in
|
||||
|
@ -3210,6 +3221,11 @@ x86_64)
|
|||
;;
|
||||
esac
|
||||
|
||||
MOZ_ARG_ENABLE_BOOL(require-all-d3dc-versions,
|
||||
[ --enable-require-all-d3dc-versions Require all versions of the D3D compiler needed for supported Windows systems.],
|
||||
MOZ_REQUIRE_ALL_D3DCS=1,
|
||||
MOZ_REQUIRE_ALL_D3DCS=)
|
||||
|
||||
# This is potentially set in external mozconfig files; if it's set,
|
||||
# then the build exposes the "webgl" context name, which is reserved
|
||||
# for conformant implementations.
|
||||
|
@ -3267,19 +3283,85 @@ if test -n "$MOZ_ANGLE_RENDERER"; then
|
|||
MOZ_CHECK_HEADER(d3d10.h, MOZ_HAS_WINSDK_WITH_D3D=1)
|
||||
fi
|
||||
|
||||
######################################
|
||||
# Find _43 for use by XP.
|
||||
|
||||
# Get the SDK path from the registry.
|
||||
# First try to get the June 2010 SDK
|
||||
MOZ_DIRECTX_SDK_REG_KEY=`reg query 'HKLM\Software\Microsoft\DirectX' //s | grep 'Microsoft DirectX SDK (June 2010)' | head -n 1`
|
||||
if test -z "$MOZ_DIRECTX_SDK_REG_KEY" ; then
|
||||
# Otherwise just take whatever comes first
|
||||
MOZ_DIRECTX_SDK_REG_KEY=`reg query 'HKLM\Software\Microsoft\DirectX' //s | grep 'Microsoft DirectX SDK' | head -n 1`
|
||||
fi
|
||||
MOZ_DIRECTX_SDK_PATH=`reg query "$MOZ_DIRECTX_SDK_REG_KEY" //v InstallPath | grep REG_SZ | sed 's/.*\([[a-zA-Z]]\)\\:\\\\/\\1\\:\\\\/' | sed 's,\\\\,/,g'`
|
||||
|
||||
if test -n "$MOZ_DIRECTX_SDK_PATH" &&
|
||||
test -f "$MOZ_DIRECTX_SDK_PATH"/lib/$MOZ_D3D_CPU_SUFFIX/dxguid.lib ; then
|
||||
AC_MSG_RESULT([Found DirectX SDK via registry, using $MOZ_DIRECTX_SDK_PATH])
|
||||
else
|
||||
AC_MSG_RESULT([DirectX SDK not found.])
|
||||
MOZ_DIRECTX_SDK_PATH=
|
||||
fi
|
||||
|
||||
# Check that our DirectX SDK is acceptable.
|
||||
if test -n "$MOZ_DIRECTX_SDK_PATH"; then
|
||||
if test -n "`echo $MOZ_DIRECTX_SDK_REG_KEY | grep 'February 2010'`" ; then
|
||||
AC_MSG_RESULT([Found the February 2010 DirectX SDK, which is unacceptable to ANGLE.])
|
||||
MOZ_DIRECTX_SDK_PATH=
|
||||
fi
|
||||
fi
|
||||
|
||||
if test -n "$MOZ_DIRECTX_SDK_PATH"; then
|
||||
# Find a D3D compiler DLL in the DirectX SDK, if we didn't find one already.
|
||||
# Get the SDK numeric version (e.g. 43) by looking at the dependencies of d3dx9.lib
|
||||
MOZ_D3DX9_VERSION=`dumpbin //headers "$MOZ_DIRECTX_SDK_PATH"/lib/$MOZ_D3D_CPU_SUFFIX/d3dx9.lib | egrep d3dx9_[[0-9]][[0-9]]\.dll | head -n1 | sed 's/.*\([[0-9]][[0-9]]\).*/\\1/g'`
|
||||
|
||||
if test -n "$MOZ_D3DX9_VERSION" ; then
|
||||
MOZ_D3DCOMPILER_XP_CAB=`find "$MOZ_DIRECTX_SDK_PATH"/Redist -name *D3DCompiler_${MOZ_D3DX9_VERSION}_${MOZ_D3D_CPU_SUFFIX}.cab | head -n1`
|
||||
|
||||
if test -n "$MOZ_D3DCOMPILER_XP_CAB"; then
|
||||
MOZ_D3DCOMPILER_XP_DLL=D3DCompiler_$MOZ_D3DX9_VERSION.dll
|
||||
else
|
||||
AC_MSG_RESULT([Couldn't find a CAB containing the D3D compiler DLL.])
|
||||
AC_MSG_ERROR([DirectX SDK at "$MOZ_DIRECTX_SDK_PATH" appears broken.])
|
||||
MOZ_DIRECTX_SDK_PATH=
|
||||
fi
|
||||
else
|
||||
AC_MSG_RESULT([Couldn't determine the D3DX9 version for the DirectX SDK.])
|
||||
MOZ_DIRECTX_SDK_PATH=
|
||||
fi
|
||||
else
|
||||
AC_MSG_RESULT([Couldn't find an acceptable DirectX SDK for ANGLE, needed for d3dcompiler_43.])
|
||||
fi
|
||||
|
||||
######################################
|
||||
# Check that we found what we needed.
|
||||
MOZ_FOUND_A_D3D_COMPILER=
|
||||
MOZ_FOUND_BOTH_D3D_COMPILERS=1
|
||||
|
||||
if test -n "$MOZ_D3DCOMPILER_VISTA_DLL"; then
|
||||
MOZ_FOUND_A_D3D_COMPILER=1
|
||||
AC_MSG_RESULT([Found d3dcompiler DLL for Vista+: $MOZ_D3DCOMPILER_VISTA_DLL])
|
||||
else
|
||||
MOZ_FOUND_BOTH_D3D_COMPILERS=
|
||||
fi
|
||||
|
||||
if test -n "$MOZ_D3DCOMPILER_XP_DLL"; then
|
||||
MOZ_FOUND_A_D3D_COMPILER=1
|
||||
AC_MSG_RESULT([Found d3dcompiler DLL for XP: $MOZ_D3DCOMPILER_XP_DLL])
|
||||
else
|
||||
MOZ_FOUND_BOTH_D3D_COMPILERS=
|
||||
fi
|
||||
|
||||
if test -z "$CROSS_COMPILE"; then
|
||||
if test -z "MOZ_FOUND_A_D3D_COMPILER"; then
|
||||
AC_MSG_ERROR([Couldn't find an acceptable D3D compiler DLL.])
|
||||
fi
|
||||
|
||||
if test -n "$MOZ_REQUIRE_ALL_D3DCS" -a -z "$MOZ_FOUND_BOTH_D3D_COMPILERS"; then
|
||||
AC_MSG_ERROR([Both D3D compilers _43 and _46+ are required by --enable-require-d3d-compilers.])
|
||||
AC_MSG_ERROR([ Install Windows SDK 8.0+, as well as DirectX SDK (June 2010 version or newer), or reconfigure without this flag.])
|
||||
fi
|
||||
fi
|
||||
fi # MOZ_ANGLE_RENDERER
|
||||
|
||||
|
@ -5062,6 +5144,9 @@ AC_SUBST(MOZ_D3D_CPU_SUFFIX)
|
|||
AC_SUBST(MOZ_HAS_WINSDK_WITH_D3D)
|
||||
AC_SUBST(MOZ_D3DCOMPILER_VISTA_DLL)
|
||||
AC_SUBST(MOZ_D3DCOMPILER_VISTA_DLL_PATH)
|
||||
AC_SUBST(MOZ_DIRECTX_SDK_PATH)
|
||||
AC_SUBST(MOZ_D3DCOMPILER_XP_DLL)
|
||||
AC_SUBST(MOZ_D3DCOMPILER_XP_CAB)
|
||||
|
||||
AC_SUBST(MOZ_ANDROID_APPLICATION_CLASS)
|
||||
AC_SUBST(MOZ_ANDROID_BROWSER_INTENT_CLASS)
|
||||
|
|
|
@ -21,10 +21,6 @@
|
|||
#include "nsIFaviconService.h"
|
||||
#endif // MOZ_PLACES
|
||||
|
||||
#ifdef XP_WIN
|
||||
#include <shellapi.h>
|
||||
#endif
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
using mozilla::dom::ContentChild;
|
||||
|
@ -157,12 +153,23 @@ bool nsAlertsService::ShouldShowAlert()
|
|||
bool result = true;
|
||||
|
||||
#ifdef XP_WIN
|
||||
QUERY_USER_NOTIFICATION_STATE qstate;
|
||||
if (SUCCEEDED(SHQueryUserNotificationState(&qstate))) {
|
||||
if (qstate != QUNS_ACCEPTS_NOTIFICATIONS) {
|
||||
result = false;
|
||||
HMODULE shellDLL = ::LoadLibraryW(L"shell32.dll");
|
||||
if (!shellDLL)
|
||||
return result;
|
||||
|
||||
SHQueryUserNotificationStatePtr pSHQueryUserNotificationState =
|
||||
(SHQueryUserNotificationStatePtr) ::GetProcAddress(shellDLL, "SHQueryUserNotificationState");
|
||||
|
||||
if (pSHQueryUserNotificationState) {
|
||||
MOZ_QUERY_USER_NOTIFICATION_STATE qstate;
|
||||
if (SUCCEEDED(pSHQueryUserNotificationState(&qstate))) {
|
||||
if (qstate != QUNS_ACCEPTS_NOTIFICATIONS) {
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
::FreeLibrary(shellDLL);
|
||||
#endif
|
||||
|
||||
return result;
|
||||
|
|
|
@ -10,6 +10,23 @@
|
|||
#include "nsCOMPtr.h"
|
||||
#include "nsXULAlerts.h"
|
||||
|
||||
#ifdef XP_WIN
|
||||
typedef enum tagMOZ_QUERY_USER_NOTIFICATION_STATE {
|
||||
QUNS_NOT_PRESENT = 1,
|
||||
QUNS_BUSY = 2,
|
||||
QUNS_RUNNING_D3D_FULL_SCREEN = 3,
|
||||
QUNS_PRESENTATION_MODE = 4,
|
||||
QUNS_ACCEPTS_NOTIFICATIONS = 5,
|
||||
QUNS_QUIET_TIME = 6,
|
||||
QUNS_IMMERSIVE = 7
|
||||
} MOZ_QUERY_USER_NOTIFICATION_STATE;
|
||||
|
||||
extern "C" {
|
||||
// This function is Windows Vista or later
|
||||
typedef HRESULT (__stdcall *SHQueryUserNotificationStatePtr)(MOZ_QUERY_USER_NOTIFICATION_STATE *pquns);
|
||||
}
|
||||
#endif // defined(XP_WIN)
|
||||
|
||||
class nsAlertsService : public nsIAlertsService,
|
||||
public nsIAlertsDoNotDisturb
|
||||
{
|
||||
|
|
|
@ -16,6 +16,26 @@ EXTRA_DEPS += symverscript
|
|||
endif
|
||||
endif
|
||||
|
||||
ifdef MOZ_WEBRTC
|
||||
ifeq (WINNT,$(OS_TARGET))
|
||||
ifndef MOZ_HAS_WINSDK_WITH_D3D
|
||||
OS_LDFLAGS += \
|
||||
-LIBPATH:'$(MOZ_DIRECTX_SDK_PATH)/lib/$(MOZ_D3D_CPU_SUFFIX)' \
|
||||
$(NULL)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef MOZ_WEBRTC
|
||||
ifeq (WINNT,$(OS_TARGET))
|
||||
ifndef MOZ_HAS_WINSDK_WITH_D3D
|
||||
OS_LDFLAGS += \
|
||||
-LIBPATH:'$(MOZ_DIRECTX_SDK_PATH)/lib/$(MOZ_D3D_CPU_SUFFIX)' \
|
||||
$(NULL)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
# Generate GDB pretty printer-autoload files only on Linux. OSX's GDB is
|
||||
# too old to support Python pretty-printers; if this changes, we could make
|
||||
# this 'ifdef GNU_CC'.
|
||||
|
|
|
@ -5108,7 +5108,7 @@
|
|||
${EndIf}
|
||||
|
||||
; Windows NT 6.0 (Vista/Server 2008) and lower are not supported.
|
||||
${Unless} ${AtLeastWin7}
|
||||
${Unless} ${AtLeastWinXP}
|
||||
MessageBox MB_OK|MB_ICONSTOP "$R9"
|
||||
; Nothing initialized so no need to call OnEndCommon
|
||||
Quit
|
||||
|
|
|
@ -351,7 +351,9 @@ popupnotificationcontent {
|
|||
width: 20px;
|
||||
}
|
||||
|
||||
@media (-moz-os-version: windows-win7) {
|
||||
@media (-moz-os-version: windows-xp),
|
||||
(-moz-os-version: windows-vista),
|
||||
(-moz-os-version: windows-win7) {
|
||||
.close-icon {
|
||||
-moz-image-region: rect(0, 16px, 16px, 0);
|
||||
}
|
||||
|
@ -385,7 +387,9 @@ popupnotificationcontent {
|
|||
-moz-image-region: rect(0, 120px, 40px, 80px);
|
||||
}
|
||||
|
||||
@media (-moz-os-version: windows-win7) {
|
||||
@media (-moz-os-version: windows-xp),
|
||||
(-moz-os-version: windows-vista),
|
||||
(-moz-os-version: windows-win7) {
|
||||
.close-icon {
|
||||
-moz-image-region: rect(0, 32px, 32px, 0);
|
||||
}
|
||||
|
|
|
@ -99,6 +99,7 @@
|
|||
#include <intrin.h>
|
||||
#include <math.h>
|
||||
#include "cairo/cairo-features.h"
|
||||
#include "mozilla/WindowsVersion.h"
|
||||
#include "mozilla/mscom/MainThreadRuntime.h"
|
||||
#include "mozilla/widget/AudioSession.h"
|
||||
|
||||
|
@ -2823,7 +2824,10 @@ XREMain::XRE_mainInit(bool* aExitFlag)
|
|||
// manual font file I/O on _all_ system fonts. To avoid this, load the
|
||||
// dwrite library and create a factory as early as possible so that the
|
||||
// FntCache service is ready by the time it's needed.
|
||||
CreateThread(nullptr, 0, &InitDwriteBG, nullptr, 0, nullptr);
|
||||
|
||||
if (IsVistaOrLater()) {
|
||||
CreateThread(nullptr, 0, &InitDwriteBG, nullptr, 0, nullptr);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -4211,7 +4215,7 @@ enum {
|
|||
kE10sDisabledForAddons = 7,
|
||||
kE10sForceDisabled = 8,
|
||||
// kE10sDisabledForXPAcceleration = 9, removed in bug 1296353
|
||||
// kE10sDisabledForOperatingSystem = 10, removed due to xp-eol
|
||||
kE10sDisabledForOperatingSystem = 10,
|
||||
};
|
||||
|
||||
const char* kAccessibilityLastRunDatePref = "accessibility.lastLoadDate";
|
||||
|
@ -4247,6 +4251,18 @@ MultiprocessBlockPolicy() {
|
|||
}
|
||||
|
||||
#if defined(XP_WIN)
|
||||
|
||||
/**
|
||||
* Avoids enabling e10s for Windows XP users on the release channel.
|
||||
*/
|
||||
if (!IsVistaOrLater()) {
|
||||
nsAdoptingCString channelName = Preferences::GetDefaultCString("app.update.channel");
|
||||
if (channelName.EqualsLiteral("release") || channelName.EqualsLiteral("esr")) {
|
||||
gMultiprocessBlockPolicy = kE10sDisabledForOperatingSystem;
|
||||
return gMultiprocessBlockPolicy;
|
||||
}
|
||||
}
|
||||
|
||||
bool disabledForA11y = false;
|
||||
/**
|
||||
* Avoids enabling e10s if accessibility has recently loaded. Performs the
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
|
||||
#ifdef XP_WIN
|
||||
#include <process.h>
|
||||
#include <shobjidl.h>
|
||||
#include "mozilla/ipc/WindowsMessageLoop.h"
|
||||
#endif
|
||||
|
||||
|
@ -108,6 +107,10 @@ using mozilla::startup::sChildProcessType;
|
|||
|
||||
static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
|
||||
|
||||
#ifdef XP_WIN
|
||||
static const wchar_t kShellLibraryName[] = L"shell32.dll";
|
||||
#endif
|
||||
|
||||
nsresult
|
||||
XRE_LockProfileDirectory(nsIFile* aDirectory,
|
||||
nsISupports* *aLockObject)
|
||||
|
@ -231,9 +234,26 @@ XRE_SetProcessType(const char* aProcessTypeString)
|
|||
void
|
||||
SetTaskbarGroupId(const nsString& aId)
|
||||
{
|
||||
if (FAILED(SetCurrentProcessExplicitAppUserModelID(aId.get()))) {
|
||||
typedef HRESULT (WINAPI * SetCurrentProcessExplicitAppUserModelIDPtr)(PCWSTR AppID);
|
||||
|
||||
SetCurrentProcessExplicitAppUserModelIDPtr funcAppUserModelID = nullptr;
|
||||
|
||||
HMODULE hDLL = ::LoadLibraryW(kShellLibraryName);
|
||||
|
||||
funcAppUserModelID = (SetCurrentProcessExplicitAppUserModelIDPtr)
|
||||
GetProcAddress(hDLL, "SetCurrentProcessExplicitAppUserModelID");
|
||||
|
||||
if (!funcAppUserModelID) {
|
||||
::FreeLibrary(hDLL);
|
||||
return;
|
||||
}
|
||||
|
||||
if (FAILED(funcAppUserModelID(aId.get()))) {
|
||||
NS_WARNING("SetCurrentProcessExplicitAppUserModelID failed for child process.");
|
||||
}
|
||||
|
||||
if (hDLL)
|
||||
::FreeLibrary(hDLL);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -37,6 +37,10 @@
|
|||
#include "gfxConfig.h"
|
||||
#include "DriverCrashGuard.h"
|
||||
|
||||
#if defined(MOZ_CRASHREPORTER)
|
||||
#include "nsExceptionHandler.h"
|
||||
#endif
|
||||
|
||||
using namespace mozilla::widget;
|
||||
using namespace mozilla;
|
||||
using mozilla::MutexAutoLock;
|
||||
|
@ -248,7 +252,13 @@ RemovePrefForDriverVersion()
|
|||
static OperatingSystem
|
||||
BlacklistOSToOperatingSystem(const nsAString& os)
|
||||
{
|
||||
if (os.EqualsLiteral("WINNT 6.1"))
|
||||
if (os.EqualsLiteral("WINNT 5.1"))
|
||||
return OperatingSystem::WindowsXP;
|
||||
else if (os.EqualsLiteral("WINNT 5.2"))
|
||||
return OperatingSystem::WindowsServer2003;
|
||||
else if (os.EqualsLiteral("WINNT 6.0"))
|
||||
return OperatingSystem::WindowsVista;
|
||||
else if (os.EqualsLiteral("WINNT 6.1"))
|
||||
return OperatingSystem::Windows7;
|
||||
else if (os.EqualsLiteral("WINNT 6.2"))
|
||||
return OperatingSystem::Windows8;
|
||||
|
|
|
@ -450,7 +450,9 @@ public:
|
|||
* Operating system versions.
|
||||
*/
|
||||
enum OperatingSystemVersion {
|
||||
eOperatingSystemVersion_Windows7 = 2,
|
||||
eOperatingSystemVersion_WindowsXP = 0,
|
||||
eOperatingSystemVersion_WindowsVista,
|
||||
eOperatingSystemVersion_Windows7,
|
||||
eOperatingSystemVersion_Windows8,
|
||||
eOperatingSystemVersion_Windows10,
|
||||
eOperatingSystemVersion_Unknown
|
||||
|
|
|
@ -235,6 +235,9 @@ ParseIDFromDeviceID(const nsAString &key, const char *prefix, int length)
|
|||
// based on http://msdn.microsoft.com/en-us/library/ms724834(VS.85).aspx
|
||||
enum {
|
||||
kWindowsUnknown = 0,
|
||||
kWindowsXP = 0x50001,
|
||||
kWindowsServer2003 = 0x50002,
|
||||
kWindowsVista = 0x60000,
|
||||
kWindows7 = 0x60001,
|
||||
kWindows8 = 0x60002,
|
||||
kWindows8_1 = 0x60003,
|
||||
|
@ -725,6 +728,12 @@ static OperatingSystem
|
|||
WindowsVersionToOperatingSystem(int32_t aWindowsVersion)
|
||||
{
|
||||
switch(aWindowsVersion) {
|
||||
case kWindowsXP:
|
||||
return OperatingSystem::WindowsXP;
|
||||
case kWindowsServer2003:
|
||||
return OperatingSystem::WindowsServer2003;
|
||||
case kWindowsVista:
|
||||
return OperatingSystem::WindowsVista;
|
||||
case kWindows7:
|
||||
return OperatingSystem::Windows7;
|
||||
case kWindows8:
|
||||
|
@ -753,6 +762,11 @@ GfxInfo::GetGfxDriverInfo()
|
|||
/*
|
||||
* NVIDIA entries
|
||||
*/
|
||||
APPEND_TO_DRIVER_BLOCKLIST(OperatingSystem::WindowsXP,
|
||||
(nsAString&) GfxDriverInfo::GetDeviceVendor(VendorNVIDIA), GfxDriverInfo::allDevices,
|
||||
GfxDriverInfo::allFeatures, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION,
|
||||
DRIVER_LESS_THAN_OR_EQUAL, V(6,14,11,8745), "FEATURE_FAILURE_NV_XP", "nVidia driver > 187.45" );
|
||||
|
||||
/*
|
||||
* The last 5 digit of the NVIDIA driver version maps to the version that
|
||||
* NVIDIA uses. The minor version (15, 16, 17) corresponds roughtly to the
|
||||
|
@ -763,17 +777,33 @@ GfxInfo::GetGfxDriverInfo()
|
|||
* 187.45 (late October 2009) and earlier contain a bug which can cause us
|
||||
* to crash on shutdown.
|
||||
*/
|
||||
APPEND_TO_DRIVER_BLOCKLIST(OperatingSystem::WindowsVista,
|
||||
(nsAString&) GfxDriverInfo::GetDeviceVendor(VendorNVIDIA), GfxDriverInfo::allDevices,
|
||||
GfxDriverInfo::allFeatures, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION,
|
||||
DRIVER_LESS_THAN_OR_EQUAL, V(8,15,11,8745),
|
||||
"FEATURE_FAILURE_NV_VISTA_15", "nVidia driver > 187.45" );
|
||||
APPEND_TO_DRIVER_BLOCKLIST(OperatingSystem::Windows7,
|
||||
(nsAString&) GfxDriverInfo::GetDeviceVendor(VendorNVIDIA), GfxDriverInfo::allDevices,
|
||||
GfxDriverInfo::allFeatures, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION,
|
||||
DRIVER_LESS_THAN_OR_EQUAL, V(8,15,11,8745),
|
||||
"FEATURE_FAILURE_NV_W7_15", "nVidia driver > 187.45" );
|
||||
APPEND_TO_DRIVER_BLOCKLIST_RANGE(OperatingSystem::WindowsVista,
|
||||
(nsAString&) GfxDriverInfo::GetDeviceVendor(VendorNVIDIA), GfxDriverInfo::allDevices,
|
||||
GfxDriverInfo::allFeatures, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION,
|
||||
DRIVER_BETWEEN_INCLUSIVE_START, V(8,16,10,0000), V(8,16,11,8745),
|
||||
"FEATURE_FAILURE_NV_VISTA_16", "nVidia driver > 187.45" );
|
||||
APPEND_TO_DRIVER_BLOCKLIST_RANGE(OperatingSystem::Windows7,
|
||||
(nsAString&) GfxDriverInfo::GetDeviceVendor(VendorNVIDIA), GfxDriverInfo::allDevices,
|
||||
GfxDriverInfo::allFeatures, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION,
|
||||
DRIVER_BETWEEN_INCLUSIVE_START, V(8,16,10,0000), V(8,16,11,8745),
|
||||
"FEATURE_FAILURE_NV_W7_16", "nVidia driver > 187.45" );
|
||||
// Telemetry doesn't show any driver in this range so it might not even be required.
|
||||
APPEND_TO_DRIVER_BLOCKLIST_RANGE(OperatingSystem::WindowsVista,
|
||||
(nsAString&) GfxDriverInfo::GetDeviceVendor(VendorNVIDIA), GfxDriverInfo::allDevices,
|
||||
GfxDriverInfo::allFeatures, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION,
|
||||
DRIVER_BETWEEN_INCLUSIVE_START, V(8,17,10,0000), V(8,17,11,8745),
|
||||
"FEATURE_FAILURE_NV_VISTA_17", "nVidia driver > 187.45" );
|
||||
// Telemetry doesn't show any driver in this range so it might not even be required.
|
||||
APPEND_TO_DRIVER_BLOCKLIST_RANGE(OperatingSystem::Windows7,
|
||||
(nsAString&) GfxDriverInfo::GetDeviceVendor(VendorNVIDIA), GfxDriverInfo::allDevices,
|
||||
GfxDriverInfo::allFeatures, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION,
|
||||
|
@ -871,6 +901,13 @@ GfxInfo::GetGfxDriverInfo()
|
|||
nsIGfxInfo::FEATURE_DIRECT2D, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION, \
|
||||
DRIVER_BUILD_ID_LESS_THAN, driverVer, ruleId )
|
||||
|
||||
IMPLEMENT_INTEL_DRIVER_BLOCKLIST_D2D(OperatingSystem::WindowsVista, IntelGMA500, 1006, "FEATURE_FAILURE_594877_1");
|
||||
IMPLEMENT_INTEL_DRIVER_BLOCKLIST_D2D(OperatingSystem::WindowsVista, IntelGMA900, GfxDriverInfo::allDriverVersions, "FEATURE_FAILURE_594877_2");
|
||||
IMPLEMENT_INTEL_DRIVER_BLOCKLIST_D2D(OperatingSystem::WindowsVista, IntelGMA950, 1504, "FEATURE_FAILURE_594877_3");
|
||||
IMPLEMENT_INTEL_DRIVER_BLOCKLIST_D2D(OperatingSystem::WindowsVista, IntelGMA3150, 2124, "FEATURE_FAILURE_594877_4");
|
||||
IMPLEMENT_INTEL_DRIVER_BLOCKLIST_D2D(OperatingSystem::WindowsVista, IntelGMAX3000, 1666, "FEATURE_FAILURE_594877_5");
|
||||
IMPLEMENT_INTEL_DRIVER_BLOCKLIST_D2D(OperatingSystem::WindowsVista, IntelHDGraphicsToSandyBridge, 2202, "FEATURE_FAILURE_594877_6");
|
||||
|
||||
IMPLEMENT_INTEL_DRIVER_BLOCKLIST_D2D(OperatingSystem::Windows7, IntelGMA500, 2026, "FEATURE_FAILURE_594877_7");
|
||||
IMPLEMENT_INTEL_DRIVER_BLOCKLIST_D2D(OperatingSystem::Windows7, IntelGMA900, GfxDriverInfo::allDriverVersions, "FEATURE_FAILURE_594877_8");
|
||||
IMPLEMENT_INTEL_DRIVER_BLOCKLIST_D2D(OperatingSystem::Windows7, IntelGMA950, 1930, "FEATURE_FAILURE_594877_9");
|
||||
|
@ -887,6 +924,31 @@ GfxInfo::GetGfxDriverInfo()
|
|||
nsIGfxInfo::FEATURE_DIRECT2D, nsIGfxInfo::FEATURE_BLOCKED_DEVICE,
|
||||
DRIVER_LESS_THAN, GfxDriverInfo::allDriverVersions, "FEATURE_FAILURE_1180379");
|
||||
|
||||
IMPLEMENT_INTEL_DRIVER_BLOCKLIST(OperatingSystem::WindowsXP, IntelGMA500, V(3,0,20,3200), "FEATURE_FAILURE_INTEL_1");
|
||||
IMPLEMENT_INTEL_DRIVER_BLOCKLIST(OperatingSystem::WindowsXP, IntelGMA900, V(6,14,10,4764), "FEATURE_FAILURE_INTEL_2");
|
||||
IMPLEMENT_INTEL_DRIVER_BLOCKLIST(OperatingSystem::WindowsXP, IntelGMA950, V(6,14,10,4926), "FEATURE_FAILURE_INTEL_3");
|
||||
IMPLEMENT_INTEL_DRIVER_BLOCKLIST(OperatingSystem::WindowsXP, IntelGMA3150, V(6,14,10,5134), "FEATURE_FAILURE_INTEL_4");
|
||||
IMPLEMENT_INTEL_DRIVER_BLOCKLIST(OperatingSystem::WindowsXP, IntelGMAX3000, V(6,14,10,5218), "FEATURE_FAILURE_INTEL_5");
|
||||
IMPLEMENT_INTEL_DRIVER_BLOCKLIST(OperatingSystem::WindowsXP, IntelGMAX4500HD, V(6,14,10,4969), "FEATURE_FAILURE_INTEL_6");
|
||||
IMPLEMENT_INTEL_DRIVER_BLOCKLIST(OperatingSystem::WindowsXP, IntelHDGraphicsToSandyBridge, V(6,14,10,4969), "FEATURE_FAILURE_INTEL_7");
|
||||
|
||||
// StrechRect seems to suffer from precision issues which leads to artifacting
|
||||
// during content drawing starting with at least version 6.14.10.5082
|
||||
// and going until 6.14.10.5218. See bug 919454 and bug 949275 for more info.
|
||||
APPEND_TO_DRIVER_BLOCKLIST_RANGE(OperatingSystem::WindowsXP,
|
||||
const_cast<nsAString&>(GfxDriverInfo::GetDeviceVendor(VendorIntel)),
|
||||
const_cast<GfxDeviceFamily*>(GfxDriverInfo::GetDeviceFamily(IntelGMAX4500HD)),
|
||||
GfxDriverInfo::allFeatures, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION,
|
||||
DRIVER_BETWEEN_EXCLUSIVE, V(6,14,10,5076), V(6,14,10,5218), "FEATURE_FAILURE_INTEL_8", "6.14.10.5218");
|
||||
|
||||
IMPLEMENT_INTEL_DRIVER_BLOCKLIST(OperatingSystem::WindowsVista, IntelGMA500, V(3,0,20,3200), "FEATURE_FAILURE_INTEL_9");
|
||||
IMPLEMENT_INTEL_DRIVER_BLOCKLIST(OperatingSystem::WindowsVista, IntelGMA900, GfxDriverInfo::allDriverVersions, "FEATURE_FAILURE_INTEL_10");
|
||||
IMPLEMENT_INTEL_DRIVER_BLOCKLIST(OperatingSystem::WindowsVista, IntelGMA950, V(7,14,10,1504), "FEATURE_FAILURE_INTEL_11");
|
||||
IMPLEMENT_INTEL_DRIVER_BLOCKLIST(OperatingSystem::WindowsVista, IntelGMA3150, V(7,14,10,1910), "FEATURE_FAILURE_INTEL_12");
|
||||
IMPLEMENT_INTEL_DRIVER_BLOCKLIST(OperatingSystem::WindowsVista, IntelGMAX3000, V(7,15,10,1666), "FEATURE_FAILURE_INTEL_13");
|
||||
IMPLEMENT_INTEL_DRIVER_BLOCKLIST(OperatingSystem::WindowsVista, IntelGMAX4500HD, V(7,15,10,1666), "FEATURE_FAILURE_INTEL_14");
|
||||
IMPLEMENT_INTEL_DRIVER_BLOCKLIST(OperatingSystem::WindowsVista, IntelHDGraphicsToSandyBridge, V(7,15,10,1666), "FEATURE_FAILURE_INTEL_15");
|
||||
|
||||
IMPLEMENT_INTEL_DRIVER_BLOCKLIST(OperatingSystem::Windows7, IntelGMA500, V(5,0,0,2026), "FEATURE_FAILURE_INTEL_16");
|
||||
IMPLEMENT_INTEL_DRIVER_BLOCKLIST(OperatingSystem::Windows7, IntelGMA900, GfxDriverInfo::allDriverVersions, "FEATURE_FAILURE_INTEL_17");
|
||||
IMPLEMENT_INTEL_DRIVER_BLOCKLIST(OperatingSystem::Windows7, IntelGMA950, V(8,15,10,1930), "FEATURE_FAILURE_INTEL_18");
|
||||
|
@ -1144,6 +1206,23 @@ GfxInfo::GetFeatureStatusImpl(int32_t aFeature,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// special-case the WinXP test slaves: they have out-of-date drivers, but we still want to
|
||||
// whitelist them, actually we do know that this combination of device and driver version
|
||||
// works well.
|
||||
if (mWindowsVersion == kWindowsXP &&
|
||||
adapterVendorID.Equals(GfxDriverInfo::GetDeviceVendor(VendorNVIDIA), nsCaseInsensitiveStringComparator()) &&
|
||||
adapterDeviceID.LowerCaseEqualsLiteral("0x0861") && // GeForce 9400
|
||||
driverVersion == V(6,14,11,7756))
|
||||
{
|
||||
*aStatus = FEATURE_STATUS_OK;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Windows Server 2003 should be just like Windows XP for present purpose, but still has a different version number.
|
||||
// OTOH Windows Server 2008 R1 and R2 already have the same version numbers as Vista and Seven respectively
|
||||
if (os == OperatingSystem::WindowsServer2003)
|
||||
os = OperatingSystem::WindowsXP;
|
||||
|
||||
if (mHasDriverVersionMismatch) {
|
||||
*aStatus = nsIGfxInfo::FEATURE_BLOCKED_MISMATCHED_VERSION;
|
||||
return NS_OK;
|
||||
|
|
|
@ -1360,6 +1360,34 @@ NativeKey::InitWithKeyChar()
|
|||
break;
|
||||
}
|
||||
|
||||
if (!CanComputeVirtualKeyCodeFromScanCode()) {
|
||||
// The right control key and the right alt key are extended keys.
|
||||
// Therefore, we never get VK_RCONTRL and VK_RMENU for the result of
|
||||
// MapVirtualKeyEx() on WinXP or WinServer2003.
|
||||
//
|
||||
// If VK_SHIFT, VK_CONTROL or VK_MENU key message is caused by well
|
||||
// known scan code, we should decide it as Right key. Otherwise,
|
||||
// decide it as Left key.
|
||||
switch (mOriginalVirtualKeyCode) {
|
||||
case VK_CONTROL:
|
||||
mVirtualKeyCode =
|
||||
mIsExtended && mScanCode == 0x1D ? VK_RCONTROL : VK_LCONTROL;
|
||||
break;
|
||||
case VK_MENU:
|
||||
mVirtualKeyCode =
|
||||
mIsExtended && mScanCode == 0x38 ? VK_RMENU : VK_LMENU;
|
||||
break;
|
||||
case VK_SHIFT:
|
||||
// Neither left shift nor right shift is an extended key,
|
||||
// let's use VK_LSHIFT for unknown mapping.
|
||||
mVirtualKeyCode = VK_LSHIFT;
|
||||
break;
|
||||
default:
|
||||
MOZ_CRASH("Unsupported mOriginalVirtualKeyCode");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
NS_ASSERTION(!mVirtualKeyCode,
|
||||
"mVirtualKeyCode has been computed already");
|
||||
|
||||
|
@ -1416,6 +1444,11 @@ NativeKey::InitWithKeyChar()
|
|||
// scancode, we cannot compute virtual keycode. I.e., with such
|
||||
// applications, we cannot generate proper KeyboardEvent.code value.
|
||||
|
||||
// We cannot compute the virtual key code from WM_CHAR message on WinXP
|
||||
// if it's caused by an extended key.
|
||||
if (!CanComputeVirtualKeyCodeFromScanCode()) {
|
||||
break;
|
||||
}
|
||||
mVirtualKeyCode = mOriginalVirtualKeyCode =
|
||||
ComputeVirtualKeyCodeFromScanCodeEx();
|
||||
NS_ASSERTION(mVirtualKeyCode, "Failed to compute virtual keycode");
|
||||
|
@ -1833,6 +1866,18 @@ NativeKey::GetKeyLocation() const
|
|||
}
|
||||
}
|
||||
|
||||
bool
|
||||
NativeKey::CanComputeVirtualKeyCodeFromScanCode() const
|
||||
{
|
||||
// Vista or later supports ScanCodeEx.
|
||||
if (IsVistaOrLater()) {
|
||||
return true;
|
||||
}
|
||||
// Otherwise, MapVirtualKeyEx() can compute virtual keycode only with
|
||||
// non-extended key.
|
||||
return !mIsExtended;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
NativeKey::ComputeVirtualKeyCodeFromScanCode() const
|
||||
{
|
||||
|
@ -1846,6 +1891,12 @@ NativeKey::ComputeVirtualKeyCodeFromScanCodeEx() const
|
|||
// MapVirtualKeyEx() has been improved for supporting extended keys since
|
||||
// Vista. When we call it for mapping a scancode of an extended key and
|
||||
// a virtual keycode, we need to add 0xE000 to the scancode.
|
||||
// On the other hand, neither WinXP nor WinServer2003 doesn't support 0xE000.
|
||||
// Therefore, we have no way to get virtual keycode from scan code of
|
||||
// extended keys.
|
||||
if (NS_WARN_IF(!CanComputeVirtualKeyCodeFromScanCode())) {
|
||||
return 0;
|
||||
}
|
||||
return static_cast<uint8_t>(
|
||||
::MapVirtualKeyEx(GetScanCodeWithExtendedFlag(), MAPVK_VSC_TO_VK_EX,
|
||||
mKeyboardLayout));
|
||||
|
@ -1856,7 +1907,8 @@ NativeKey::ComputeScanCodeExFromVirtualKeyCode(UINT aVirtualKeyCode) const
|
|||
{
|
||||
return static_cast<uint16_t>(
|
||||
::MapVirtualKeyEx(aVirtualKeyCode,
|
||||
MAPVK_VK_TO_VSC_EX,
|
||||
IsVistaOrLater() ? MAPVK_VK_TO_VSC_EX :
|
||||
MAPVK_VK_TO_VSC,
|
||||
mKeyboardLayout));
|
||||
}
|
||||
|
||||
|
@ -4176,7 +4228,8 @@ KeyboardLayout::LoadLayout(HKL aLayout)
|
|||
|
||||
if (MOZ_LOG_TEST(sKeyboardLayoutLogger, LogLevel::Verbose)) {
|
||||
static const UINT kExtendedScanCode[] = { 0x0000, 0xE000 };
|
||||
static const UINT kMapType = MAPVK_VSC_TO_VK_EX;
|
||||
static const UINT kMapType =
|
||||
IsVistaOrLater() ? MAPVK_VSC_TO_VK_EX : MAPVK_VSC_TO_VK;
|
||||
MOZ_LOG(sKeyboardLayoutLogger, LogLevel::Verbose,
|
||||
("Logging virtual keycode values for scancode (0x%p)...",
|
||||
mKeyboardLayout));
|
||||
|
@ -4188,6 +4241,11 @@ KeyboardLayout::LoadLayout(HKL aLayout)
|
|||
MOZ_LOG(sKeyboardLayoutLogger, LogLevel::Verbose,
|
||||
("0x%04X, %s", scanCode, kVirtualKeyName[virtualKeyCode]));
|
||||
}
|
||||
// XP and Server 2003 don't support 0xE0 prefix of the scancode.
|
||||
// Therefore, we don't need to continue on them.
|
||||
if (!IsVistaOrLater()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -559,6 +559,11 @@ private:
|
|||
*/
|
||||
bool GetFollowingCharMessage(MSG& aCharMsg);
|
||||
|
||||
/**
|
||||
* Whether the key event can compute virtual keycode from the scancode value.
|
||||
*/
|
||||
bool CanComputeVirtualKeyCodeFromScanCode() const;
|
||||
|
||||
/**
|
||||
* Wraps MapVirtualKeyEx() with MAPVK_VSC_TO_VK.
|
||||
*/
|
||||
|
|
|
@ -5764,7 +5764,8 @@ TSFTextStore::Initialize()
|
|||
return;
|
||||
}
|
||||
|
||||
bool enableTsf = Preferences::GetBool(kPrefNameEnableTSF, false);
|
||||
bool enableTsf =
|
||||
IsVistaOrLater() && Preferences::GetBool(kPrefNameEnableTSF, false);
|
||||
MOZ_LOG(sTextStoreLog, LogLevel::Info,
|
||||
(" TSFTextStore::Initialize(), TSF is %s",
|
||||
enableTsf ? "enabled" : "disabled"));
|
||||
|
|
|
@ -28,9 +28,7 @@
|
|||
#include "mozilla/Telemetry.h"
|
||||
|
||||
// Defined in dwmapi in a header that needs a higher numbered _WINNT #define
|
||||
#ifndef DWM_SIT_DISPLAYFRAME
|
||||
#define DWM_SIT_DISPLAYFRAME 0x1
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
namespace widget {
|
||||
|
|
|
@ -992,7 +992,10 @@ MouseScrollHandler::SystemSettings::InitScrollChars()
|
|||
&mScrollChars, 0)) {
|
||||
MOZ_LOG(gMouseScrollLog, LogLevel::Info,
|
||||
("MouseScroll::SystemSettings::InitScrollChars(): ::SystemParametersInfo("
|
||||
"SPI_GETWHEELSCROLLCHARS) failed, this is unexpected on Vista or later"));
|
||||
"SPI_GETWHEELSCROLLCHARS) failed, %s",
|
||||
IsVistaOrLater() ?
|
||||
"this is unexpected on Vista or later" :
|
||||
"but on XP or earlier, this is not a problem"));
|
||||
// XXX Should we use DefaultScrollChars()?
|
||||
mScrollChars = 1;
|
||||
}
|
||||
|
@ -1078,7 +1081,7 @@ bool
|
|||
MouseScrollHandler::SystemSettings::IsOverridingSystemScrollSpeedAllowed()
|
||||
{
|
||||
return mScrollLines == DefaultScrollLines() &&
|
||||
mScrollChars == DefaultScrollChars();
|
||||
(!IsVistaOrLater() || mScrollChars == DefaultScrollChars());
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
|
|
@ -34,6 +34,8 @@
|
|||
#include <propkey.h>
|
||||
#include <shellapi.h>
|
||||
|
||||
const wchar_t kShellLibraryName[] = L"shell32.dll";
|
||||
|
||||
static NS_DEFINE_CID(kJumpListBuilderCID, NS_WIN_JUMPLISTBUILDER_CID);
|
||||
|
||||
namespace {
|
||||
|
@ -75,14 +77,30 @@ SetWindowAppUserModelProp(mozIDOMWindow *aParent,
|
|||
if (!toplevelHWND)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
RefPtr<IPropertyStore> pPropStore;
|
||||
if (FAILED(SHGetPropertyStoreForWindow(toplevelHWND, IID_IPropertyStore,
|
||||
getter_AddRefs(pPropStore)))) {
|
||||
typedef HRESULT (WINAPI * SHGetPropertyStoreForWindowPtr)
|
||||
(HWND hwnd, REFIID riid, void** ppv);
|
||||
SHGetPropertyStoreForWindowPtr funcGetProStore = nullptr;
|
||||
|
||||
HMODULE hDLL = ::LoadLibraryW(kShellLibraryName);
|
||||
funcGetProStore = (SHGetPropertyStoreForWindowPtr)
|
||||
GetProcAddress(hDLL, "SHGetPropertyStoreForWindow");
|
||||
|
||||
if (!funcGetProStore) {
|
||||
FreeLibrary(hDLL);
|
||||
return NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
|
||||
IPropertyStore* pPropStore;
|
||||
if (FAILED(funcGetProStore(toplevelHWND,
|
||||
IID_PPV_ARGS(&pPropStore)))) {
|
||||
FreeLibrary(hDLL);
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
PROPVARIANT pv;
|
||||
if (FAILED(InitPropVariantFromString(aIdentifier.get(), &pv))) {
|
||||
pPropStore->Release();
|
||||
FreeLibrary(hDLL);
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
|
@ -93,6 +111,8 @@ SetWindowAppUserModelProp(mozIDOMWindow *aParent,
|
|||
}
|
||||
|
||||
PropVariantClear(&pv);
|
||||
pPropStore->Release();
|
||||
FreeLibrary(hDLL);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
@ -319,18 +339,40 @@ WinTaskbar::GetDefaultGroupId(nsAString & aDefaultGroupId) {
|
|||
// (static) Called from AppShell
|
||||
bool
|
||||
WinTaskbar::RegisterAppUserModelID() {
|
||||
if (!IsWin7OrLater())
|
||||
return false;
|
||||
|
||||
SetCurrentProcessExplicitAppUserModelIDPtr funcAppUserModelID = nullptr;
|
||||
bool retVal = false;
|
||||
|
||||
nsAutoString uid;
|
||||
if (!GetAppUserModelID(uid))
|
||||
return false;
|
||||
|
||||
return SUCCEEDED(SetCurrentProcessExplicitAppUserModelID(uid.get()));
|
||||
HMODULE hDLL = ::LoadLibraryW(kShellLibraryName);
|
||||
|
||||
funcAppUserModelID = (SetCurrentProcessExplicitAppUserModelIDPtr)
|
||||
GetProcAddress(hDLL, "SetCurrentProcessExplicitAppUserModelID");
|
||||
|
||||
if (!funcAppUserModelID) {
|
||||
::FreeLibrary(hDLL);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (SUCCEEDED(funcAppUserModelID(uid.get())))
|
||||
retVal = true;
|
||||
|
||||
if (hDLL)
|
||||
::FreeLibrary(hDLL);
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
WinTaskbar::GetAvailable(bool *aAvailable) {
|
||||
// ITaskbarList4::HrInit() may fail with shell extensions like blackbox
|
||||
// installed. Initialize early to return available=false in those cases.
|
||||
*aAvailable = Initialize();
|
||||
*aAvailable = IsWin7OrLater() && Initialize();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -462,7 +462,7 @@ static NtTestAlertPtr sNtTestAlert = nullptr;
|
|||
void
|
||||
WinUtils::Initialize()
|
||||
{
|
||||
if (!sDwmDll) {
|
||||
if (!sDwmDll && IsVistaOrLater()) {
|
||||
sDwmDll = ::LoadLibraryW(kDwmLibraryName);
|
||||
|
||||
if (sDwmDll) {
|
||||
|
@ -601,7 +601,7 @@ WinUtils::SystemScaleFactor()
|
|||
return systemScale;
|
||||
}
|
||||
|
||||
#if WINVER < 0x603
|
||||
#ifndef WM_DPICHANGED
|
||||
typedef enum {
|
||||
MDT_EFFECTIVE_DPI = 0,
|
||||
MDT_ANGULAR_DPI = 1,
|
||||
|
@ -628,14 +628,16 @@ GETPROCESSDPIAWARENESSPROC sGetProcessDpiAwareness;
|
|||
static bool
|
||||
SlowIsPerMonitorDPIAware()
|
||||
{
|
||||
// Intentionally leak the handle.
|
||||
HMODULE shcore =
|
||||
LoadLibraryEx(L"shcore", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
|
||||
if (shcore) {
|
||||
sGetDpiForMonitor =
|
||||
(GETDPIFORMONITORPROC) GetProcAddress(shcore, "GetDpiForMonitor");
|
||||
sGetProcessDpiAwareness =
|
||||
(GETPROCESSDPIAWARENESSPROC) GetProcAddress(shcore, "GetProcessDpiAwareness");
|
||||
if (IsVistaOrLater()) {
|
||||
// Intentionally leak the handle.
|
||||
HMODULE shcore =
|
||||
LoadLibraryEx(L"shcore", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
|
||||
if (shcore) {
|
||||
sGetDpiForMonitor =
|
||||
(GETDPIFORMONITORPROC) GetProcAddress(shcore, "GetDpiForMonitor");
|
||||
sGetProcessDpiAwareness =
|
||||
(GETPROCESSDPIAWARENESSPROC) GetProcAddress(shcore, "GetProcessDpiAwareness");
|
||||
}
|
||||
}
|
||||
PROCESS_DPI_AWARENESS dpiAwareness;
|
||||
return sGetDpiForMonitor && sGetProcessDpiAwareness &&
|
||||
|
@ -758,7 +760,7 @@ static DWORD
|
|||
GetWaitFlags()
|
||||
{
|
||||
DWORD result = MWMO_INPUTAVAILABLE;
|
||||
if (XRE_IsContentProcess()) {
|
||||
if (IsVistaOrLater() && XRE_IsContentProcess()) {
|
||||
result |= MWMO_ALERTABLE;
|
||||
}
|
||||
return result;
|
||||
|
@ -1138,8 +1140,7 @@ WinUtils::GetIsMouseFromTouch(EventMessage aEventMessage)
|
|||
const uint32_t MOZ_T_I_SIGNATURE = TABLET_INK_TOUCH | TABLET_INK_SIGNATURE;
|
||||
const uint32_t MOZ_T_I_CHECK_TCH = TABLET_INK_TOUCH | TABLET_INK_CHECK;
|
||||
return ((aEventMessage == eMouseMove || aEventMessage == eMouseDown ||
|
||||
aEventMessage == eMouseUp || aEventMessage == eMouseAuxClick ||
|
||||
aEventMessage == eMouseDoubleClick) &&
|
||||
aEventMessage == eMouseUp || aEventMessage == eMouseDoubleClick) &&
|
||||
(GetMessageExtraInfo() & MOZ_T_I_SIGNATURE) == MOZ_T_I_CHECK_TCH);
|
||||
}
|
||||
|
||||
|
@ -1877,7 +1878,7 @@ WinUtils::IsTouchDeviceSupportPresent()
|
|||
uint32_t
|
||||
WinUtils::GetMaxTouchPoints()
|
||||
{
|
||||
if (IsTouchDeviceSupportPresent()) {
|
||||
if (IsWin7OrLater() && IsTouchDeviceSupportPresent()) {
|
||||
return GetSystemMetrics(SM_MAXIMUMTOUCHES);
|
||||
}
|
||||
return 0;
|
||||
|
@ -1892,6 +1893,11 @@ typedef DWORD (WINAPI * GetFinalPathNameByHandlePtr)(HANDLE hFile,
|
|||
bool
|
||||
WinUtils::ResolveJunctionPointsAndSymLinks(std::wstring& aPath)
|
||||
{
|
||||
// Users folder was introduced with Vista.
|
||||
if (!IsVistaOrLater()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
wchar_t path[MAX_PATH] = { 0 };
|
||||
|
||||
nsAutoHandle handle(
|
||||
|
@ -2019,19 +2025,21 @@ WinUtils::GetAppInitDLLs(nsAString& aOutput)
|
|||
}
|
||||
nsAutoRegKey key(hkey);
|
||||
LONG status;
|
||||
const wchar_t kLoadAppInitDLLs[] = L"LoadAppInit_DLLs";
|
||||
DWORD loadAppInitDLLs = 0;
|
||||
DWORD loadAppInitDLLsLen = sizeof(loadAppInitDLLs);
|
||||
status = RegQueryValueExW(hkey, kLoadAppInitDLLs, nullptr,
|
||||
nullptr, (LPBYTE)&loadAppInitDLLs,
|
||||
&loadAppInitDLLsLen);
|
||||
if (status != ERROR_SUCCESS) {
|
||||
return false;
|
||||
}
|
||||
if (!loadAppInitDLLs) {
|
||||
// If loadAppInitDLLs is zero then AppInit_DLLs is disabled.
|
||||
// In this case we'll return true along with an empty output string.
|
||||
return true;
|
||||
if (IsVistaOrLater()) {
|
||||
const wchar_t kLoadAppInitDLLs[] = L"LoadAppInit_DLLs";
|
||||
DWORD loadAppInitDLLs = 0;
|
||||
DWORD loadAppInitDLLsLen = sizeof(loadAppInitDLLs);
|
||||
status = RegQueryValueExW(hkey, kLoadAppInitDLLs, nullptr,
|
||||
nullptr, (LPBYTE)&loadAppInitDLLs,
|
||||
&loadAppInitDLLsLen);
|
||||
if (status != ERROR_SUCCESS) {
|
||||
return false;
|
||||
}
|
||||
if (!loadAppInitDLLs) {
|
||||
// If loadAppInitDLLs is zero then AppInit_DLLs is disabled.
|
||||
// In this case we'll return true along with an empty output string.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
DWORD numBytes = 0;
|
||||
const wchar_t kAppInitDLLs[] = L"AppInit_DLLs";
|
||||
|
|
|
@ -5,8 +5,7 @@
|
|||
|
||||
#include <windows.h>
|
||||
#include <winsdkver.h>
|
||||
#include <wrl.h>
|
||||
|
||||
#include "mozwrlbase.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
|
||||
#include "WindowsUIUtils.h"
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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/. */
|
||||
|
||||
#pragma once
|
||||
|
||||
/*
|
||||
* Includes <wrl.h> and it's children. Defines imports needed by
|
||||
* corewrappers.h in the case where windows.h has already been
|
||||
* included w/WINVER < 0x600. Also ups WINVER/_WIN32_WINNT prior
|
||||
* to including wrl.h. Mozilla's build currently has WINVER set to
|
||||
* 0x502 for XP support.
|
||||
*/
|
||||
|
||||
#if _WIN32_WINNT < 0x600
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
VOID
|
||||
WINAPI
|
||||
ReleaseSRWLockExclusive(
|
||||
_Inout_ PSRWLOCK SRWLock
|
||||
);
|
||||
|
||||
VOID
|
||||
WINAPI
|
||||
ReleaseSRWLockShared(
|
||||
_Inout_ PSRWLOCK SRWLock
|
||||
);
|
||||
|
||||
BOOL
|
||||
WINAPI
|
||||
InitializeCriticalSectionEx(
|
||||
_Out_ LPCRITICAL_SECTION lpCriticalSection,
|
||||
_In_ DWORD dwSpinCount,
|
||||
_In_ DWORD Flags
|
||||
);
|
||||
|
||||
VOID
|
||||
WINAPI
|
||||
InitializeSRWLock(
|
||||
_Out_ PSRWLOCK SRWLock
|
||||
);
|
||||
|
||||
VOID
|
||||
WINAPI
|
||||
AcquireSRWLockExclusive(
|
||||
_Inout_ PSRWLOCK SRWLock
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
WINAPI
|
||||
TryAcquireSRWLockExclusive(
|
||||
_Inout_ PSRWLOCK SRWLock
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
WINAPI
|
||||
TryAcquireSRWLockShared(
|
||||
_Inout_ PSRWLOCK SRWLock
|
||||
);
|
||||
|
||||
VOID
|
||||
WINAPI
|
||||
AcquireSRWLockShared(
|
||||
_Inout_ PSRWLOCK SRWLock
|
||||
);
|
||||
|
||||
#undef WINVER
|
||||
#undef _WIN32_WINNT
|
||||
#define WINVER 0x600
|
||||
#define _WIN32_WINNT 0x600
|
||||
|
||||
#endif // _WIN32_WINNT < 0x600
|
||||
|
||||
#include <wrl.h>
|
|
@ -1261,7 +1261,8 @@ nsDataObj :: GetFileContentsInternetShortcut ( FORMATETC& aFE, STGMEDIUM& aSTG )
|
|||
const char *shortcutFormatStr;
|
||||
int totalLen;
|
||||
nsCString path;
|
||||
if (!Preferences::GetBool(kShellIconPref, true)) {
|
||||
if (!Preferences::GetBool(kShellIconPref, true) ||
|
||||
!IsVistaOrLater()) {
|
||||
shortcutFormatStr = "[InternetShortcut]\r\nURL=%s\r\n";
|
||||
const int formatLen = strlen(shortcutFormatStr) - 2; // don't include %s
|
||||
totalLen = formatLen + asciiUrl.Length(); // don't include null character
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "nsPIDOMWindow.h"
|
||||
#include "GeckoProfiler.h"
|
||||
|
||||
using mozilla::IsVistaOrLater;
|
||||
using mozilla::IsWin8OrLater;
|
||||
using mozilla::MakeUnique;
|
||||
using mozilla::mscom::EnsureMTA;
|
||||
|
@ -218,6 +219,191 @@ STDMETHODIMP nsFilePicker::QueryInterface(REFIID refiid, void** ppvResult)
|
|||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
/*
|
||||
* XP picker callbacks
|
||||
*/
|
||||
|
||||
// Show - Display the file dialog
|
||||
int CALLBACK
|
||||
BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
|
||||
{
|
||||
if (uMsg == BFFM_INITIALIZED)
|
||||
{
|
||||
char16_t * filePath = (char16_t *) lpData;
|
||||
if (filePath)
|
||||
::SendMessageW(hwnd, BFFM_SETSELECTIONW,
|
||||
TRUE /* true because lpData is a path string */,
|
||||
lpData);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
EnsureWindowVisible(HWND hwnd)
|
||||
{
|
||||
// Obtain the monitor which has the largest area of intersection
|
||||
// with the window, or nullptr if there is no intersection.
|
||||
HMONITOR monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONULL);
|
||||
if (!monitor) {
|
||||
// The window is not visible, we should reposition it to the same place as its parent
|
||||
HWND parentHwnd = GetParent(hwnd);
|
||||
RECT parentRect;
|
||||
GetWindowRect(parentHwnd, &parentRect);
|
||||
SetWindowPos(hwnd, nullptr, parentRect.left, parentRect.top, 0, 0,
|
||||
SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER);
|
||||
}
|
||||
}
|
||||
|
||||
// Callback hook which will ensure that the window is visible. Currently
|
||||
// only in use on os <= XP.
|
||||
UINT_PTR CALLBACK
|
||||
nsFilePicker::FilePickerHook(HWND hwnd,
|
||||
UINT msg,
|
||||
WPARAM wParam,
|
||||
LPARAM lParam)
|
||||
{
|
||||
switch(msg) {
|
||||
case WM_NOTIFY:
|
||||
{
|
||||
LPOFNOTIFYW lpofn = (LPOFNOTIFYW) lParam;
|
||||
if (!lpofn || !lpofn->lpOFN) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (CDN_INITDONE == lpofn->hdr.code) {
|
||||
// The Window will be automatically moved to the last position after
|
||||
// CDN_INITDONE. We post a message to ensure the window will be visible
|
||||
// so it will be done after the automatic last position window move.
|
||||
PostMessage(hwnd, MOZ_WM_ENSUREVISIBLE, 0, 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MOZ_WM_ENSUREVISIBLE:
|
||||
EnsureWindowVisible(GetParent(hwnd));
|
||||
break;
|
||||
case WM_INITDIALOG:
|
||||
{
|
||||
OPENFILENAMEW* pofn = reinterpret_cast<OPENFILENAMEW*>(lParam);
|
||||
SetProp(hwnd, kDialogPtrProp, (HANDLE)pofn->lCustData);
|
||||
nsFilePicker* picker = reinterpret_cast<nsFilePicker*>(pofn->lCustData);
|
||||
if (picker) {
|
||||
picker->SetDialogHandle(hwnd);
|
||||
SetTimer(hwnd, kDialogTimerID, kDialogTimerTimeout, nullptr);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WM_TIMER:
|
||||
{
|
||||
// Check to see if our parent has been torn down, if so, we close too.
|
||||
if (wParam == kDialogTimerID) {
|
||||
nsFilePicker* picker =
|
||||
reinterpret_cast<nsFilePicker*>(GetProp(hwnd, kDialogPtrProp));
|
||||
if (picker && picker->ClosePickerIfNeeded(true)) {
|
||||
KillTimer(hwnd, kDialogTimerID);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// Callback hook which will dynamically allocate a buffer large enough
|
||||
// for the file picker dialog. Currently only in use on os <= XP.
|
||||
UINT_PTR CALLBACK
|
||||
nsFilePicker::MultiFilePickerHook(HWND hwnd,
|
||||
UINT msg,
|
||||
WPARAM wParam,
|
||||
LPARAM lParam)
|
||||
{
|
||||
switch (msg) {
|
||||
case WM_INITDIALOG:
|
||||
{
|
||||
// Finds the child drop down of a File Picker dialog and sets the
|
||||
// maximum amount of text it can hold when typed in manually.
|
||||
// A wParam of 0 mean 0x7FFFFFFE characters.
|
||||
HWND comboBox = FindWindowEx(GetParent(hwnd), nullptr,
|
||||
L"ComboBoxEx32", nullptr );
|
||||
if(comboBox)
|
||||
SendMessage(comboBox, CB_LIMITTEXT, 0, 0);
|
||||
// Store our nsFilePicker ptr for future use
|
||||
OPENFILENAMEW* pofn = reinterpret_cast<OPENFILENAMEW*>(lParam);
|
||||
SetProp(hwnd, kDialogPtrProp, (HANDLE)pofn->lCustData);
|
||||
nsFilePicker* picker =
|
||||
reinterpret_cast<nsFilePicker*>(pofn->lCustData);
|
||||
if (picker) {
|
||||
picker->SetDialogHandle(hwnd);
|
||||
SetTimer(hwnd, kDialogTimerID, kDialogTimerTimeout, nullptr);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WM_NOTIFY:
|
||||
{
|
||||
LPOFNOTIFYW lpofn = (LPOFNOTIFYW) lParam;
|
||||
if (!lpofn || !lpofn->lpOFN) {
|
||||
return 0;
|
||||
}
|
||||
// CDN_SELCHANGE is sent when the selection in the list box of the file
|
||||
// selection dialog changes
|
||||
if (lpofn->hdr.code == CDN_SELCHANGE) {
|
||||
HWND parentHWND = GetParent(hwnd);
|
||||
|
||||
// Get the required size for the selected files buffer
|
||||
UINT newBufLength = 0;
|
||||
int requiredBufLength = CommDlg_OpenSave_GetSpecW(parentHWND,
|
||||
nullptr, 0);
|
||||
if(requiredBufLength >= 0)
|
||||
newBufLength += requiredBufLength;
|
||||
else
|
||||
newBufLength += MAX_PATH;
|
||||
|
||||
// If the user selects multiple files, the buffer contains the
|
||||
// current directory followed by the file names of the selected
|
||||
// files. So make room for the directory path. If the user
|
||||
// selects a single file, it is no harm to add extra space.
|
||||
requiredBufLength = CommDlg_OpenSave_GetFolderPathW(parentHWND,
|
||||
nullptr, 0);
|
||||
if(requiredBufLength >= 0)
|
||||
newBufLength += requiredBufLength;
|
||||
else
|
||||
newBufLength += MAX_PATH;
|
||||
|
||||
// Check if lpstrFile and nMaxFile are large enough
|
||||
if (newBufLength > lpofn->lpOFN->nMaxFile) {
|
||||
if (lpofn->lpOFN->lpstrFile)
|
||||
delete[] lpofn->lpOFN->lpstrFile;
|
||||
|
||||
// We allocate FILE_BUFFER_SIZE more bytes than is needed so that
|
||||
// if the user selects a file and holds down shift and down to
|
||||
// select additional items, we will not continuously reallocate
|
||||
newBufLength += FILE_BUFFER_SIZE;
|
||||
|
||||
wchar_t* filesBuffer = new wchar_t[newBufLength];
|
||||
ZeroMemory(filesBuffer, newBufLength * sizeof(wchar_t));
|
||||
|
||||
lpofn->lpOFN->lpstrFile = filesBuffer;
|
||||
lpofn->lpOFN->nMaxFile = newBufLength;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WM_TIMER:
|
||||
{
|
||||
// Check to see if our parent has been torn down, if so, we close too.
|
||||
if (wParam == kDialogTimerID) {
|
||||
nsFilePicker* picker =
|
||||
reinterpret_cast<nsFilePicker*>(GetProp(hwnd, kDialogPtrProp));
|
||||
if (picker && picker->ClosePickerIfNeeded(true)) {
|
||||
KillTimer(hwnd, kDialogTimerID);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return FilePickerHook(hwnd, msg, wParam, lParam);
|
||||
}
|
||||
|
||||
/*
|
||||
* Vista+ callbacks
|
||||
|
@ -290,18 +476,25 @@ nsFilePicker::OnOverwrite(IFileDialog *pfd,
|
|||
*/
|
||||
|
||||
bool
|
||||
nsFilePicker::ClosePickerIfNeeded()
|
||||
nsFilePicker::ClosePickerIfNeeded(bool aIsXPDialog)
|
||||
{
|
||||
if (!mParentWidget || !mDlgWnd)
|
||||
return false;
|
||||
|
||||
nsWindow *win = static_cast<nsWindow *>(mParentWidget.get());
|
||||
if (IsWindow(mDlgWnd) && IsWindowVisible(mDlgWnd) && win->DestroyCalled()) {
|
||||
// Note, the xp callbacks hand us an inner window, so we have to step up
|
||||
// one to get the actual dialog.
|
||||
HWND dlgWnd;
|
||||
if (aIsXPDialog)
|
||||
dlgWnd = GetParent(mDlgWnd);
|
||||
else
|
||||
dlgWnd = mDlgWnd;
|
||||
if (IsWindow(dlgWnd) && IsWindowVisible(dlgWnd) && win->DestroyCalled()) {
|
||||
wchar_t className[64];
|
||||
// Make sure we have the right window
|
||||
if (GetClassNameW(mDlgWnd, className, mozilla::ArrayLength(className)) &&
|
||||
if (GetClassNameW(dlgWnd, className, mozilla::ArrayLength(className)) &&
|
||||
!wcscmp(className, L"#32770") &&
|
||||
DestroyWindow(mDlgWnd)) {
|
||||
DestroyWindow(dlgWnd)) {
|
||||
mDlgWnd = nullptr;
|
||||
return true;
|
||||
}
|
||||
|
@ -313,7 +506,7 @@ void
|
|||
nsFilePicker::PickerCallbackTimerFunc(nsITimer *aTimer, void *aCtx)
|
||||
{
|
||||
nsFilePicker* picker = (nsFilePicker*)aCtx;
|
||||
if (picker->ClosePickerIfNeeded()) {
|
||||
if (picker->ClosePickerIfNeeded(false)) {
|
||||
aTimer->Cancel();
|
||||
}
|
||||
}
|
||||
|
@ -330,15 +523,62 @@ nsFilePicker::SetDialogHandle(HWND aWnd)
|
|||
* Folder picker invocation
|
||||
*/
|
||||
|
||||
// Open the older XP style folder picker dialog. We end up in this call
|
||||
// on XP systems or when platform is built without the longhorn SDK.
|
||||
bool
|
||||
nsFilePicker::ShowXPFolderPicker(const nsString& aInitialDir)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
auto dirBuffer = MakeUnique<wchar_t[]>(FILE_BUFFER_SIZE);
|
||||
wcsncpy(dirBuffer.get(), aInitialDir.get(), FILE_BUFFER_SIZE);
|
||||
dirBuffer[FILE_BUFFER_SIZE-1] = '\0';
|
||||
|
||||
AutoDestroyTmpWindow adtw((HWND)(mParentWidget.get() ?
|
||||
mParentWidget->GetNativeData(NS_NATIVE_TMP_WINDOW) : nullptr));
|
||||
|
||||
BROWSEINFOW browserInfo = {0};
|
||||
browserInfo.pidlRoot = nullptr;
|
||||
browserInfo.pszDisplayName = dirBuffer.get();
|
||||
browserInfo.lpszTitle = mTitle.get();
|
||||
browserInfo.ulFlags = BIF_USENEWUI | BIF_RETURNONLYFSDIRS;
|
||||
browserInfo.hwndOwner = adtw.get();
|
||||
browserInfo.iImage = 0;
|
||||
browserInfo.lParam = reinterpret_cast<LPARAM>(this);
|
||||
|
||||
if (!aInitialDir.IsEmpty()) {
|
||||
// the dialog is modal so that |initialDir.get()| will be valid in
|
||||
// BrowserCallbackProc. Thus, we don't need to clone it.
|
||||
browserInfo.lParam = (LPARAM) aInitialDir.get();
|
||||
browserInfo.lpfn = &BrowseCallbackProc;
|
||||
} else {
|
||||
browserInfo.lParam = 0;
|
||||
browserInfo.lpfn = nullptr;
|
||||
}
|
||||
|
||||
LPITEMIDLIST list = ::SHBrowseForFolderW(&browserInfo);
|
||||
if (list) {
|
||||
result = ::SHGetPathFromIDListW(list, dirBuffer.get());
|
||||
if (result)
|
||||
mUnicodeFile.Assign(static_cast<const wchar_t*>(dirBuffer.get()));
|
||||
// free PIDL
|
||||
CoTaskMemFree(list);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Show a folder picker.
|
||||
*
|
||||
* Show a folder picker post Windows XP
|
||||
*
|
||||
* @param aInitialDir The initial directory, the last used directory will be
|
||||
* used if left blank.
|
||||
* @param aWasInitError Out parameter will hold true if there was an error
|
||||
* before the folder picker is shown.
|
||||
* @return true if a file was selected successfully.
|
||||
*/
|
||||
bool
|
||||
nsFilePicker::ShowFolderPicker(const nsString& aInitialDir)
|
||||
nsFilePicker::ShowFolderPicker(const nsString& aInitialDir, bool &aWasInitError)
|
||||
{
|
||||
if (!IsWin8OrLater()) {
|
||||
// Some Windows 7 users are experiencing a race condition when some dlls
|
||||
|
@ -353,8 +593,10 @@ nsFilePicker::ShowFolderPicker(const nsString& aInitialDir)
|
|||
if (FAILED(CoCreateInstance(CLSID_FileOpenDialog, nullptr, CLSCTX_INPROC,
|
||||
IID_IFileOpenDialog,
|
||||
getter_AddRefs(dialog)))) {
|
||||
aWasInitError = true;
|
||||
return false;
|
||||
}
|
||||
aWasInitError = false;
|
||||
|
||||
// hook up event callbacks
|
||||
dialog->Advise(this, &mFDECookie);
|
||||
|
@ -416,15 +658,233 @@ nsFilePicker::ShowFolderPicker(const nsString& aInitialDir)
|
|||
* File open and save picker invocation
|
||||
*/
|
||||
|
||||
/* static */ bool
|
||||
nsFilePicker::GetFileNameWrapper(OPENFILENAMEW* ofn, PickerType aType)
|
||||
{
|
||||
MOZ_SEH_TRY {
|
||||
if (aType == PICKER_TYPE_OPEN)
|
||||
return ::GetOpenFileNameW(ofn);
|
||||
else if (aType == PICKER_TYPE_SAVE)
|
||||
return ::GetSaveFileNameW(ofn);
|
||||
} MOZ_SEH_EXCEPT(true) {
|
||||
NS_ERROR("nsFilePicker GetFileName win32 call generated an exception! This is bad!");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
nsFilePicker::FilePickerWrapper(OPENFILENAMEW* ofn, PickerType aType)
|
||||
{
|
||||
if (!ofn)
|
||||
return false;
|
||||
AutoWidgetPickerState awps(mParentWidget);
|
||||
return GetFileNameWrapper(ofn, aType);
|
||||
}
|
||||
|
||||
bool
|
||||
nsFilePicker::ShowXPFilePicker(const nsString& aInitialDir)
|
||||
{
|
||||
OPENFILENAMEW ofn = {0};
|
||||
ofn.lStructSize = sizeof(ofn);
|
||||
nsString filterBuffer = mFilterList;
|
||||
|
||||
auto fileBuffer = MakeUnique<wchar_t[]>(FILE_BUFFER_SIZE);
|
||||
wcsncpy(fileBuffer.get(), mDefaultFilePath.get(), FILE_BUFFER_SIZE);
|
||||
fileBuffer[FILE_BUFFER_SIZE-1] = '\0'; // null terminate in case copy truncated
|
||||
|
||||
if (!aInitialDir.IsEmpty()) {
|
||||
ofn.lpstrInitialDir = aInitialDir.get();
|
||||
}
|
||||
|
||||
AutoDestroyTmpWindow adtw((HWND) (mParentWidget.get() ?
|
||||
mParentWidget->GetNativeData(NS_NATIVE_TMP_WINDOW) : nullptr));
|
||||
|
||||
ofn.lpstrTitle = (LPCWSTR)mTitle.get();
|
||||
ofn.lpstrFilter = (LPCWSTR)filterBuffer.get();
|
||||
ofn.nFilterIndex = mSelectedType;
|
||||
ofn.lpstrFile = fileBuffer.get();
|
||||
ofn.nMaxFile = FILE_BUFFER_SIZE;
|
||||
ofn.hwndOwner = adtw.get();
|
||||
ofn.lCustData = reinterpret_cast<LPARAM>(this);
|
||||
ofn.Flags = OFN_SHAREAWARE | OFN_LONGNAMES | OFN_OVERWRITEPROMPT |
|
||||
OFN_HIDEREADONLY | OFN_PATHMUSTEXIST | OFN_ENABLESIZING |
|
||||
OFN_EXPLORER;
|
||||
|
||||
// Windows Vista and up won't allow you to use the new looking dialogs with
|
||||
// a hook procedure. The hook procedure fixes a problem on XP dialogs for
|
||||
// file picker visibility. Vista and up automatically ensures the file
|
||||
// picker is always visible.
|
||||
if (!IsVistaOrLater()) {
|
||||
ofn.lpfnHook = FilePickerHook;
|
||||
ofn.Flags |= OFN_ENABLEHOOK;
|
||||
}
|
||||
|
||||
// Handle add to recent docs settings
|
||||
if (IsPrivacyModeEnabled() || !mAddToRecentDocs) {
|
||||
ofn.Flags |= OFN_DONTADDTORECENT;
|
||||
}
|
||||
|
||||
NS_NAMED_LITERAL_STRING(htmExt, "html");
|
||||
|
||||
if (!mDefaultExtension.IsEmpty()) {
|
||||
ofn.lpstrDefExt = mDefaultExtension.get();
|
||||
} else if (IsDefaultPathHtml()) {
|
||||
// Get file extension from suggested filename to detect if we are
|
||||
// saving an html file.
|
||||
// This is supposed to append ".htm" if user doesn't supply an
|
||||
// extension but the behavior is sort of weird:
|
||||
// - Often appends ".html" even if you have an extension
|
||||
// - It obeys your extension if you put quotes around name
|
||||
ofn.lpstrDefExt = htmExt.get();
|
||||
}
|
||||
|
||||
// When possible, instead of using OFN_NOCHANGEDIR to ensure the current
|
||||
// working directory will not change from this call, we will retrieve the
|
||||
// current working directory before the call and restore it after the
|
||||
// call. This flag causes problems on Windows XP for paths that are
|
||||
// selected like C:test.txt where the user is currently at C:\somepath
|
||||
// In which case expected result should be C:\somepath\test.txt
|
||||
AutoRestoreWorkingPath restoreWorkingPath;
|
||||
// If we can't get the current working directory, the best case is to
|
||||
// use the OFN_NOCHANGEDIR flag
|
||||
if (!restoreWorkingPath.HasWorkingPath()) {
|
||||
ofn.Flags |= OFN_NOCHANGEDIR;
|
||||
}
|
||||
|
||||
bool result = false;
|
||||
|
||||
switch(mMode) {
|
||||
case modeOpen:
|
||||
// FILE MUST EXIST!
|
||||
ofn.Flags |= OFN_FILEMUSTEXIST;
|
||||
result = FilePickerWrapper(&ofn, PICKER_TYPE_OPEN);
|
||||
break;
|
||||
|
||||
case modeOpenMultiple:
|
||||
ofn.Flags |= OFN_FILEMUSTEXIST | OFN_ALLOWMULTISELECT;
|
||||
|
||||
// The hook set here ensures that the buffer returned will always be
|
||||
// large enough to hold all selected files. The hook may modify the
|
||||
// value of ofn.lpstrFile and deallocate the old buffer that it pointed
|
||||
// to (fileBuffer). The hook assumes that the passed in value is heap
|
||||
// allocated and that the returned value should be freed by the caller.
|
||||
// If the hook changes the buffer, it will deallocate the old buffer.
|
||||
// This fix would be nice to have in Vista and up, but it would force
|
||||
// the file picker to use the old style dialogs because hooks are not
|
||||
// allowed in the new file picker UI. We need to eventually move to
|
||||
// the new Common File Dialogs for Vista and up.
|
||||
if (!IsVistaOrLater()) {
|
||||
ofn.lpfnHook = MultiFilePickerHook;
|
||||
fileBuffer.release();
|
||||
result = FilePickerWrapper(&ofn, PICKER_TYPE_OPEN);
|
||||
fileBuffer.reset(ofn.lpstrFile);
|
||||
} else {
|
||||
result = FilePickerWrapper(&ofn, PICKER_TYPE_OPEN);
|
||||
}
|
||||
break;
|
||||
|
||||
case modeSave:
|
||||
{
|
||||
ofn.Flags |= OFN_NOREADONLYRETURN;
|
||||
|
||||
// Don't follow shortcuts when saving a shortcut, this can be used
|
||||
// to trick users (bug 271732)
|
||||
if (IsDefaultPathLink())
|
||||
ofn.Flags |= OFN_NODEREFERENCELINKS;
|
||||
|
||||
result = FilePickerWrapper(&ofn, PICKER_TYPE_SAVE);
|
||||
if (!result) {
|
||||
// Error, find out what kind.
|
||||
if (GetLastError() == ERROR_INVALID_PARAMETER ||
|
||||
CommDlgExtendedError() == FNERR_INVALIDFILENAME) {
|
||||
// Probably the default file name is too long or contains illegal
|
||||
// characters. Try again, without a starting file name.
|
||||
ofn.lpstrFile[0] = L'\0';
|
||||
result = FilePickerWrapper(&ofn, PICKER_TYPE_SAVE);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
NS_NOTREACHED("unsupported file picker mode");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!result)
|
||||
return false;
|
||||
|
||||
// Remember what filter type the user selected
|
||||
mSelectedType = (int16_t)ofn.nFilterIndex;
|
||||
|
||||
// Single file selection, we're done
|
||||
if (mMode != modeOpenMultiple) {
|
||||
GetQualifiedPath(fileBuffer.get(), mUnicodeFile);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Set user-selected location of file or directory. From msdn's "Open and
|
||||
// Save As Dialog Boxes" section:
|
||||
// If you specify OFN_EXPLORER, the directory and file name strings are '\0'
|
||||
// separated, with an extra '\0' character after the last file name. This
|
||||
// format enables the Explorer-style dialog boxes to return long file names
|
||||
// that include spaces.
|
||||
wchar_t *current = fileBuffer.get();
|
||||
|
||||
nsAutoString dirName(current);
|
||||
// Sometimes dirName contains a trailing slash and sometimes it doesn't:
|
||||
if (current[dirName.Length() - 1] != '\\')
|
||||
dirName.Append((char16_t)'\\');
|
||||
|
||||
while (current && *current && *(current + wcslen(current) + 1)) {
|
||||
current = current + wcslen(current) + 1;
|
||||
|
||||
nsCOMPtr<nsIFile> file = do_CreateInstance("@mozilla.org/file/local;1");
|
||||
NS_ENSURE_TRUE(file, false);
|
||||
|
||||
// Only prepend the directory if the path specified is a relative path
|
||||
nsAutoString path;
|
||||
if (PathIsRelativeW(current)) {
|
||||
path = dirName + nsDependentString(current);
|
||||
} else {
|
||||
path = current;
|
||||
}
|
||||
|
||||
nsAutoString canonicalizedPath;
|
||||
GetQualifiedPath(path.get(), canonicalizedPath);
|
||||
if (NS_FAILED(file->InitWithPath(canonicalizedPath)) ||
|
||||
!mFiles.AppendObject(file))
|
||||
return false;
|
||||
}
|
||||
|
||||
// Handle the case where the user selected just one file. From msdn: If you
|
||||
// specify OFN_ALLOWMULTISELECT and the user selects only one file the
|
||||
// lpstrFile string does not have a separator between the path and file name.
|
||||
if (current && *current && (current == fileBuffer.get())) {
|
||||
nsCOMPtr<nsIFile> file = do_CreateInstance("@mozilla.org/file/local;1");
|
||||
NS_ENSURE_TRUE(file, false);
|
||||
|
||||
nsAutoString canonicalizedPath;
|
||||
GetQualifiedPath(current, canonicalizedPath);
|
||||
if (NS_FAILED(file->InitWithPath(canonicalizedPath)) ||
|
||||
!mFiles.AppendObject(file))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Show a file picker.
|
||||
*
|
||||
* Show a file picker post Windows XP
|
||||
*
|
||||
* @param aInitialDir The initial directory, the last used directory will be
|
||||
* used if left blank.
|
||||
* @param aWasInitError Out parameter will hold true if there was an error
|
||||
* before the file picker is shown.
|
||||
* @return true if a file was selected successfully.
|
||||
*/
|
||||
bool
|
||||
nsFilePicker::ShowFilePicker(const nsString& aInitialDir)
|
||||
nsFilePicker::ShowFilePicker(const nsString& aInitialDir, bool &aWasInitError)
|
||||
{
|
||||
PROFILER_LABEL_FUNC(js::ProfileEntry::Category::OTHER);
|
||||
|
||||
|
@ -442,15 +902,18 @@ nsFilePicker::ShowFilePicker(const nsString& aInitialDir)
|
|||
if (FAILED(CoCreateInstance(CLSID_FileOpenDialog, nullptr, CLSCTX_INPROC,
|
||||
IID_IFileOpenDialog,
|
||||
getter_AddRefs(dialog)))) {
|
||||
aWasInitError = true;
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (FAILED(CoCreateInstance(CLSID_FileSaveDialog, nullptr, CLSCTX_INPROC,
|
||||
IID_IFileSaveDialog,
|
||||
getter_AddRefs(dialog)))) {
|
||||
aWasInitError = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
aWasInitError = false;
|
||||
|
||||
// hook up event callbacks
|
||||
dialog->Advise(this, &mFDECookie);
|
||||
|
@ -617,11 +1080,22 @@ nsFilePicker::ShowW(int16_t *aReturnVal)
|
|||
// with our context set temporarily to system-dpi-aware
|
||||
WinUtils::AutoSystemDpiAware dpiAwareness;
|
||||
|
||||
bool result = false;
|
||||
// Launch the XP file/folder picker on XP and as a fallback on Vista+.
|
||||
// The CoCreateInstance call to CLSID_FileOpenDialog fails with "(0x80040111)
|
||||
// ClassFactory cannot supply requested class" when the checkbox for
|
||||
// Disable Visual Themes is on in the compatability tab within the shortcut
|
||||
// properties.
|
||||
bool result = false, wasInitError = true;
|
||||
if (mMode == modeGetFolder) {
|
||||
result = ShowFolderPicker(initialDir);
|
||||
if (IsVistaOrLater())
|
||||
result = ShowFolderPicker(initialDir, wasInitError);
|
||||
if (!result && wasInitError)
|
||||
result = ShowXPFolderPicker(initialDir);
|
||||
} else {
|
||||
result = ShowFilePicker(initialDir);
|
||||
if (IsVistaOrLater())
|
||||
result = ShowFilePicker(initialDir, wasInitError);
|
||||
if (!result && wasInitError)
|
||||
result = ShowXPFilePicker(initialDir);
|
||||
}
|
||||
|
||||
// exit, and return returnCancel in aReturnVal
|
||||
|
@ -773,10 +1247,48 @@ nsFilePicker::InitNative(nsIWidget *aParent,
|
|||
mTitle.Assign(aTitle);
|
||||
}
|
||||
|
||||
void
|
||||
nsFilePicker::GetQualifiedPath(const wchar_t *aInPath, nsString &aOutPath)
|
||||
{
|
||||
// Prefer a qualified path over a non qualified path.
|
||||
// Things like c:file.txt would be accepted in Win XP but would later
|
||||
// fail to open from the download manager.
|
||||
wchar_t qualifiedFileBuffer[MAX_PATH];
|
||||
if (PathSearchAndQualifyW(aInPath, qualifiedFileBuffer, MAX_PATH)) {
|
||||
aOutPath.Assign(qualifiedFileBuffer);
|
||||
} else {
|
||||
aOutPath.Assign(aInPath);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsFilePicker::AppendXPFilter(const nsAString& aTitle, const nsAString& aFilter)
|
||||
{
|
||||
mFilterList.Append(aTitle);
|
||||
mFilterList.Append(char16_t('\0'));
|
||||
|
||||
if (aFilter.EqualsLiteral("..apps"))
|
||||
mFilterList.AppendLiteral("*.exe;*.com");
|
||||
else
|
||||
{
|
||||
nsAutoString filter(aFilter);
|
||||
filter.StripWhitespace();
|
||||
if (filter.EqualsLiteral("*"))
|
||||
filter.AppendLiteral(".*");
|
||||
mFilterList.Append(filter);
|
||||
}
|
||||
|
||||
mFilterList.Append(char16_t('\0'));
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFilePicker::AppendFilter(const nsAString& aTitle, const nsAString& aFilter)
|
||||
{
|
||||
mComFilterList.Append(aTitle, aFilter);
|
||||
if (IsVistaOrLater()) {
|
||||
mComFilterList.Append(aTitle, aFilter);
|
||||
} else {
|
||||
AppendXPFilter(aTitle, aFilter);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,17 @@
|
|||
|
||||
#include <windows.h>
|
||||
|
||||
// For Vista IFileDialog interfaces which aren't exposed
|
||||
// unless _WIN32_WINNT >= _WIN32_WINNT_LONGHORN.
|
||||
#if _WIN32_WINNT < _WIN32_WINNT_LONGHORN
|
||||
#define _WIN32_WINNT_bak _WIN32_WINNT
|
||||
#undef _WIN32_WINNT
|
||||
#define _WIN32_WINNT _WIN32_WINNT_LONGHORN
|
||||
#define _WIN32_IE_bak _WIN32_IE
|
||||
#undef _WIN32_IE
|
||||
#define _WIN32_IE _WIN32_IE_IE70
|
||||
#endif
|
||||
|
||||
#include "nsIFile.h"
|
||||
#include "nsITimer.h"
|
||||
#include "nsISimpleEnumerator.h"
|
||||
|
@ -76,19 +87,32 @@ public:
|
|||
HRESULT STDMETHODCALLTYPE OnOverwrite(IFileDialog *pfd, IShellItem *psi, FDE_OVERWRITE_RESPONSE *pResponse);
|
||||
|
||||
protected:
|
||||
enum PickerType {
|
||||
PICKER_TYPE_OPEN,
|
||||
PICKER_TYPE_SAVE,
|
||||
};
|
||||
|
||||
/* method from nsBaseFilePicker */
|
||||
virtual void InitNative(nsIWidget *aParent,
|
||||
const nsAString& aTitle);
|
||||
static void GetQualifiedPath(const wchar_t *aInPath, nsString &aOutPath);
|
||||
void GetFilterListArray(nsString& aFilterList);
|
||||
bool ShowFolderPicker(const nsString& aInitialDir);
|
||||
bool ShowFilePicker(const nsString& aInitialDir);
|
||||
static bool GetFileNameWrapper(OPENFILENAMEW* ofn, PickerType aType);
|
||||
bool FilePickerWrapper(OPENFILENAMEW* ofn, PickerType aType);
|
||||
bool ShowXPFolderPicker(const nsString& aInitialDir);
|
||||
bool ShowXPFilePicker(const nsString& aInitialDir);
|
||||
bool ShowFolderPicker(const nsString& aInitialDir, bool &aWasInitError);
|
||||
bool ShowFilePicker(const nsString& aInitialDir, bool &aWasInitError);
|
||||
void AppendXPFilter(const nsAString& aTitle, const nsAString& aFilter);
|
||||
void RememberLastUsedDirectory();
|
||||
bool IsPrivacyModeEnabled();
|
||||
bool IsDefaultPathLink();
|
||||
bool IsDefaultPathHtml();
|
||||
void SetDialogHandle(HWND aWnd);
|
||||
bool ClosePickerIfNeeded();
|
||||
bool ClosePickerIfNeeded(bool aIsXPDialog);
|
||||
static void PickerCallbackTimerFunc(nsITimer *aTimer, void *aPicker);
|
||||
static UINT_PTR CALLBACK MultiFilePickerHook(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
static UINT_PTR CALLBACK FilePickerHook(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
nsCOMPtr<nsILoadContext> mLoadContext;
|
||||
nsCOMPtr<nsIWidget> mParentWidget;
|
||||
|
@ -130,4 +154,11 @@ protected:
|
|||
DWORD mFDECookie;
|
||||
};
|
||||
|
||||
#if defined(_WIN32_WINNT_bak)
|
||||
#undef _WIN32_WINNT
|
||||
#define _WIN32_WINNT _WIN32_WINNT_bak
|
||||
#undef _WIN32_IE
|
||||
#define _WIN32_IE _WIN32_IE_bak
|
||||
#endif
|
||||
|
||||
#endif // nsFilePicker_h__
|
||||
|
|
|
@ -31,8 +31,12 @@ nsLookAndFeel::GetOperatingSystemVersion()
|
|||
version = eOperatingSystemVersion_Windows10;
|
||||
} else if (IsWin8OrLater()) {
|
||||
version = eOperatingSystemVersion_Windows8;
|
||||
} else {
|
||||
} else if (IsWin7OrLater()) {
|
||||
version = eOperatingSystemVersion_Windows7;
|
||||
} else if (IsVistaOrLater()) {
|
||||
version = eOperatingSystemVersion_WindowsVista;
|
||||
} else {
|
||||
version = eOperatingSystemVersion_WindowsXP;
|
||||
}
|
||||
|
||||
return version;
|
||||
|
@ -176,7 +180,8 @@ nsLookAndFeel::NativeGetColor(ColorID aID, nscolor &aColor)
|
|||
idx = COLOR_HIGHLIGHT;
|
||||
break;
|
||||
case eColorID__moz_menubarhovertext:
|
||||
if (!IsAppThemed()) {
|
||||
if (!IsVistaOrLater() || !IsAppThemed())
|
||||
{
|
||||
idx = nsUXThemeData::sFlatMenus ?
|
||||
COLOR_HIGHLIGHTTEXT :
|
||||
COLOR_MENUTEXT;
|
||||
|
@ -184,7 +189,8 @@ nsLookAndFeel::NativeGetColor(ColorID aID, nscolor &aColor)
|
|||
}
|
||||
// Fall through
|
||||
case eColorID__moz_menuhovertext:
|
||||
if (IsAppThemed()) {
|
||||
if (IsVistaOrLater() && IsAppThemed())
|
||||
{
|
||||
res = ::GetColorFromTheme(eUXMenu,
|
||||
MENU_POPUPITEM, MPI_HOT, TMT_TEXTCOLOR, aColor);
|
||||
if (NS_SUCCEEDED(res))
|
||||
|
@ -276,7 +282,7 @@ nsLookAndFeel::NativeGetColor(ColorID aID, nscolor &aColor)
|
|||
aColor = NS_RGB(0, 0, 0);
|
||||
return NS_OK;
|
||||
case eColorID__moz_win_mediatext:
|
||||
if (IsAppThemed()) {
|
||||
if (IsVistaOrLater() && IsAppThemed()) {
|
||||
res = ::GetColorFromTheme(eUXMediaToolbar,
|
||||
TP_BUTTON, TS_NORMAL, TMT_TEXTCOLOR, aColor);
|
||||
if (NS_SUCCEEDED(res))
|
||||
|
@ -286,7 +292,8 @@ nsLookAndFeel::NativeGetColor(ColorID aID, nscolor &aColor)
|
|||
idx = COLOR_WINDOWTEXT;
|
||||
break;
|
||||
case eColorID__moz_win_communicationstext:
|
||||
if (IsAppThemed()) {
|
||||
if (IsVistaOrLater() && IsAppThemed())
|
||||
{
|
||||
res = ::GetColorFromTheme(eUXCommunicationsToolbar,
|
||||
TP_BUTTON, TS_NORMAL, TMT_TEXTCOLOR, aColor);
|
||||
if (NS_SUCCEEDED(res))
|
||||
|
|
|
@ -29,6 +29,18 @@
|
|||
#ifndef SM_SYSTEMDOCKED
|
||||
#define SM_CONVERTIBLESLATEMODE 0x00002003
|
||||
#define SM_SYSTEMDOCKED 0x00002004
|
||||
typedef enum _AR_STATE
|
||||
{
|
||||
AR_ENABLED = 0x0,
|
||||
AR_DISABLED = 0x1,
|
||||
AR_SUPPRESSED = 0x2,
|
||||
AR_REMOTESESSION = 0x4,
|
||||
AR_MULTIMON = 0x8,
|
||||
AR_NOSENSOR = 0x10,
|
||||
AR_NOT_SUPPORTED = 0x20,
|
||||
AR_DOCKED = 0x40,
|
||||
AR_LAPTOP = 0x80
|
||||
} AR_STATE, *PAR_STATE;
|
||||
#endif
|
||||
|
||||
class nsLookAndFeel: public nsXPLookAndFeel {
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include "nsUXThemeConstants.h"
|
||||
#include <algorithm>
|
||||
|
||||
using mozilla::IsVistaOrLater;
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::gfx;
|
||||
using namespace mozilla::widget;
|
||||
|
@ -302,6 +303,10 @@ DrawThemeBGRTLAware(HANDLE aTheme, HDC aHdc, int aPart, int aState,
|
|||
* aero basic max 0 2 1 2
|
||||
* aero basic close 1 2 1 2
|
||||
*
|
||||
* xp theme min 0 2 0 2
|
||||
* xp theme max 0 2 1 2
|
||||
* xp theme close 1 2 2 2
|
||||
*
|
||||
* 'cold' button padding - generic button padding, should
|
||||
* be handled in css.
|
||||
* left top right bottom
|
||||
|
@ -312,11 +317,16 @@ DrawThemeBGRTLAware(HANDLE aTheme, HDC aHdc, int aPart, int aState,
|
|||
* aero basic min 0 0 1 0
|
||||
* aero basic max 1 0 0 0
|
||||
* aero basic close 0 0 0 0
|
||||
*
|
||||
* xp theme min 0 0 1 0
|
||||
* xp theme max 1 0 0 0
|
||||
* xp theme close 0 0 0 0
|
||||
*/
|
||||
|
||||
enum CaptionDesktopTheme {
|
||||
CAPTION_CLASSIC = 0,
|
||||
CAPTION_BASIC,
|
||||
CAPTION_XPTHEME,
|
||||
};
|
||||
|
||||
enum CaptionButton {
|
||||
|
@ -350,6 +360,8 @@ AddPaddingRect(LayoutDeviceIntSize* aSize, CaptionButton button) {
|
|||
RECT offset;
|
||||
if (!IsAppThemed())
|
||||
offset = buttonData[CAPTION_CLASSIC].hotPadding[button];
|
||||
else if (!IsVistaOrLater())
|
||||
offset = buttonData[CAPTION_XPTHEME].hotPadding[button];
|
||||
else
|
||||
offset = buttonData[CAPTION_BASIC].hotPadding[button];
|
||||
aSize->width += offset.left + offset.right;
|
||||
|
@ -363,6 +375,8 @@ OffsetBackgroundRect(RECT& rect, CaptionButton button) {
|
|||
RECT offset;
|
||||
if (!IsAppThemed())
|
||||
offset = buttonData[CAPTION_CLASSIC].hotPadding[button];
|
||||
else if (!IsVistaOrLater())
|
||||
offset = buttonData[CAPTION_XPTHEME].hotPadding[button];
|
||||
else
|
||||
offset = buttonData[CAPTION_BASIC].hotPadding[button];
|
||||
rect.left += offset.left;
|
||||
|
@ -407,7 +421,9 @@ OffsetBackgroundRect(RECT& rect, CaptionButton button) {
|
|||
static const double kProgressDeterminateTimeSpan = 3.0;
|
||||
static const double kProgressIndeterminateTimeSpan = 5.0;
|
||||
// The width of the overlay used to animate the horizontal progress bar (Vista and later).
|
||||
static const int32_t kProgressHorizontalOverlaySize = 120;
|
||||
static const int32_t kProgressHorizontalVistaOverlaySize = 120;
|
||||
// The width of the overlay used for the horizontal indeterminate progress bars on XP.
|
||||
static const int32_t kProgressHorizontalXPOverlaySize = 55;
|
||||
// The height of the overlay used to animate the vertical progress bar (Vista and later).
|
||||
static const int32_t kProgressVerticalOverlaySize = 45;
|
||||
// The height of the overlay used for the vertical indeterminate progress bar (Vista and later).
|
||||
|
@ -421,8 +437,18 @@ static const int32_t kProgressClassicOverlaySize = 40;
|
|||
*/
|
||||
static int32_t
|
||||
GetProgressOverlayStyle(bool aIsVertical)
|
||||
{
|
||||
return aIsVertical ? PP_MOVEOVERLAYVERT : PP_MOVEOVERLAY;
|
||||
{
|
||||
if (aIsVertical) {
|
||||
if (IsVistaOrLater()) {
|
||||
return PP_MOVEOVERLAYVERT;
|
||||
}
|
||||
return PP_CHUNKVERT;
|
||||
} else {
|
||||
if (IsVistaOrLater()) {
|
||||
return PP_MOVEOVERLAY;
|
||||
}
|
||||
return PP_CHUNK;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -433,11 +459,14 @@ GetProgressOverlayStyle(bool aIsVertical)
|
|||
static int32_t
|
||||
GetProgressOverlaySize(bool aIsVertical, bool aIsIndeterminate)
|
||||
{
|
||||
if (aIsVertical) {
|
||||
return aIsIndeterminate ? kProgressVerticalIndeterminateOverlaySize
|
||||
: kProgressVerticalOverlaySize;
|
||||
if (IsVistaOrLater()) {
|
||||
if (aIsVertical) {
|
||||
return aIsIndeterminate ? kProgressVerticalIndeterminateOverlaySize
|
||||
: kProgressVerticalOverlaySize;
|
||||
}
|
||||
return kProgressHorizontalVistaOverlaySize;
|
||||
}
|
||||
return kProgressHorizontalOverlaySize;
|
||||
return kProgressHorizontalXPOverlaySize;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -526,6 +555,87 @@ nsNativeThemeWin::CalculateProgressOverlayRect(nsIFrame* aFrame,
|
|||
return overlayRect;
|
||||
}
|
||||
|
||||
/*
|
||||
* DrawChunkProgressMeter - renders an xp style chunked progress meter. Called
|
||||
* by DrawProgressMeter.
|
||||
*
|
||||
* @param aTheme progress theme handle
|
||||
* @param aHdc hdc returned by gfxWindowsNativeDrawing
|
||||
* @param aPart the PP_X progress part
|
||||
* @param aState the theme state
|
||||
* @param aFrame the elements frame
|
||||
* @param aWidgetRect bounding rect for the widget
|
||||
* @param aClipRect dirty rect that needs drawing.
|
||||
* @param aAppUnits app units per device pixel
|
||||
* @param aIsIndeterm is an indeterminate progress?
|
||||
* @param aIsVertical render a vertical progress?
|
||||
* @param aIsRtl direction is rtl
|
||||
*/
|
||||
static void
|
||||
DrawChunkProgressMeter(HTHEME aTheme, HDC aHdc, int aPart,
|
||||
int aState, nsIFrame* aFrame, RECT* aWidgetRect,
|
||||
RECT* aClipRect, gfxFloat aAppUnits, bool aIsIndeterm,
|
||||
bool aIsVertical, bool aIsRtl)
|
||||
{
|
||||
NS_ASSERTION(aTheme, "Bad theme.");
|
||||
NS_ASSERTION(aHdc, "Bad hdc.");
|
||||
NS_ASSERTION(aWidgetRect, "Bad rect.");
|
||||
NS_ASSERTION(aClipRect, "Bad clip rect.");
|
||||
NS_ASSERTION(aFrame, "Bad frame.");
|
||||
|
||||
// For horizontal meters, the theme lib paints the right graphic but doesn't
|
||||
// paint the chunks, so we do that manually. For vertical meters, the theme
|
||||
// library draws everything correctly.
|
||||
if (aIsVertical) {
|
||||
DrawThemeBackground(aTheme, aHdc, aPart, aState, aWidgetRect, aClipRect);
|
||||
return;
|
||||
}
|
||||
|
||||
// query for the proper chunk metrics
|
||||
int chunkSize, spaceSize;
|
||||
if (FAILED(GetThemeMetric(aTheme, aHdc, aPart, aState,
|
||||
TMT_PROGRESSCHUNKSIZE, &chunkSize)) ||
|
||||
FAILED(GetThemeMetric(aTheme, aHdc, aPart, aState,
|
||||
TMT_PROGRESSSPACESIZE, &spaceSize))) {
|
||||
DrawThemeBackground(aTheme, aHdc, aPart, aState, aWidgetRect, aClipRect);
|
||||
return;
|
||||
}
|
||||
|
||||
// render chunks
|
||||
if (!aIsRtl || aIsIndeterm) {
|
||||
for (int chunk = aWidgetRect->left; chunk <= aWidgetRect->right;
|
||||
chunk += (chunkSize+spaceSize)) {
|
||||
if (!aIsIndeterm && ((chunk + chunkSize) > aWidgetRect->right)) {
|
||||
// aWidgetRect->right represents the end of the meter. Partial blocks
|
||||
// don't get rendered with one exception, so exit here if we don't have
|
||||
// a full chunk to draw.
|
||||
// The above is true *except* when the meter is at 100% fill, in which
|
||||
// case Windows renders any remaining partial block. Query the parent
|
||||
// frame to find out if we're at 100%.
|
||||
if (!IsProgressMeterFilled(aFrame)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
RECT bounds =
|
||||
{ chunk, aWidgetRect->top, chunk + chunkSize, aWidgetRect->bottom };
|
||||
DrawThemeBackground(aTheme, aHdc, aPart, aState, &bounds, aClipRect);
|
||||
}
|
||||
} else {
|
||||
// rtl needs to grow in the opposite direction to look right.
|
||||
for (int chunk = aWidgetRect->right; chunk >= aWidgetRect->left;
|
||||
chunk -= (chunkSize+spaceSize)) {
|
||||
if ((chunk - chunkSize) < aWidgetRect->left) {
|
||||
if (!IsProgressMeterFilled(aFrame)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
RECT bounds =
|
||||
{ chunk - chunkSize, aWidgetRect->top, chunk, aWidgetRect->bottom };
|
||||
DrawThemeBackground(aTheme, aHdc, aPart, aState, &bounds, aClipRect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* DrawProgressMeter - render an appropriate progress meter based on progress
|
||||
* meter style, orientation, and os. Note, this does not render the underlying
|
||||
|
@ -545,7 +655,8 @@ void
|
|||
nsNativeThemeWin::DrawThemedProgressMeter(nsIFrame* aFrame, int aWidgetType,
|
||||
HANDLE aTheme, HDC aHdc,
|
||||
int aPart, int aState,
|
||||
RECT* aWidgetRect, RECT* aClipRect)
|
||||
RECT* aWidgetRect, RECT* aClipRect,
|
||||
gfxFloat aAppUnits)
|
||||
{
|
||||
if (!aFrame || !aTheme || !aHdc)
|
||||
return;
|
||||
|
@ -556,6 +667,12 @@ nsNativeThemeWin::DrawThemedProgressMeter(nsIFrame* aFrame, int aWidgetType,
|
|||
RECT adjWidgetRect, adjClipRect;
|
||||
adjWidgetRect = *aWidgetRect;
|
||||
adjClipRect = *aClipRect;
|
||||
if (!IsVistaOrLater()) {
|
||||
// Adjust clipping out by one pixel. XP progress meters are inset,
|
||||
// Vista+ are not.
|
||||
InflateRect(&adjWidgetRect, 1, 1);
|
||||
InflateRect(&adjClipRect, 1, 1);
|
||||
}
|
||||
|
||||
nsIFrame* parentFrame = aFrame->GetParent();
|
||||
if (!parentFrame) {
|
||||
|
@ -570,13 +687,20 @@ nsNativeThemeWin::DrawThemedProgressMeter(nsIFrame* aFrame, int aWidgetType,
|
|||
bool indeterminate = IsIndeterminateProgress(parentFrame, eventStates);
|
||||
bool animate = indeterminate;
|
||||
|
||||
// Vista and up progress meter is fill style, rendered here. We render
|
||||
// the pulse overlay in the follow up section below.
|
||||
DrawThemeBackground(aTheme, aHdc, aPart, aState,
|
||||
&adjWidgetRect, &adjClipRect);
|
||||
if (!IsProgressMeterFilled(aFrame)) {
|
||||
animate = true;
|
||||
}
|
||||
if (IsVistaOrLater()) {
|
||||
// Vista and up progress meter is fill style, rendered here. We render
|
||||
// the pulse overlay in the follow up section below.
|
||||
DrawThemeBackground(aTheme, aHdc, aPart, aState,
|
||||
&adjWidgetRect, &adjClipRect);
|
||||
if (!IsProgressMeterFilled(aFrame)) {
|
||||
animate = true;
|
||||
}
|
||||
} else if (!indeterminate) {
|
||||
// XP progress meters are 'chunk' style.
|
||||
DrawChunkProgressMeter(aTheme, aHdc, aPart, aState, aFrame,
|
||||
&adjWidgetRect, &adjClipRect, aAppUnits,
|
||||
indeterminate, vertical, IsFrameRTL(aFrame));
|
||||
}
|
||||
|
||||
if (animate) {
|
||||
// Indeterminate rendering
|
||||
|
@ -584,8 +708,14 @@ nsNativeThemeWin::DrawThemedProgressMeter(nsIFrame* aFrame, int aWidgetType,
|
|||
RECT overlayRect =
|
||||
CalculateProgressOverlayRect(aFrame, &adjWidgetRect, vertical,
|
||||
indeterminate, false);
|
||||
DrawThemeBackground(aTheme, aHdc, overlayPart, aState, &overlayRect,
|
||||
&adjClipRect);
|
||||
if (IsVistaOrLater()) {
|
||||
DrawThemeBackground(aTheme, aHdc, overlayPart, aState, &overlayRect,
|
||||
&adjClipRect);
|
||||
} else {
|
||||
DrawChunkProgressMeter(aTheme, aHdc, overlayPart, aState, aFrame,
|
||||
&overlayRect, &adjClipRect, aAppUnits,
|
||||
indeterminate, vertical, IsFrameRTL(aFrame));
|
||||
}
|
||||
|
||||
if (!QueueAnimatedContentForRefresh(aFrame->GetContent(), 60)) {
|
||||
NS_WARNING("unable to animate progress widget!");
|
||||
|
@ -596,6 +726,15 @@ nsNativeThemeWin::DrawThemedProgressMeter(nsIFrame* aFrame, int aWidgetType,
|
|||
HANDLE
|
||||
nsNativeThemeWin::GetTheme(uint8_t aWidgetType)
|
||||
{
|
||||
if (!IsVistaOrLater()) {
|
||||
// On XP or earlier, render dropdowns as textfields;
|
||||
// doing it the right way works fine with the MS themes,
|
||||
// but breaks on a lot of custom themes (presumably because MS
|
||||
// apps do the textfield border business as well).
|
||||
if (aWidgetType == NS_THEME_MENULIST)
|
||||
aWidgetType = NS_THEME_TEXTFIELD;
|
||||
}
|
||||
|
||||
switch (aWidgetType) {
|
||||
case NS_THEME_BUTTON:
|
||||
case NS_THEME_RADIO:
|
||||
|
@ -608,7 +747,9 @@ nsNativeThemeWin::GetTheme(uint8_t aWidgetType)
|
|||
case NS_THEME_FOCUS_OUTLINE:
|
||||
return nsUXThemeData::GetTheme(eUXEdit);
|
||||
case NS_THEME_TOOLTIP:
|
||||
return nsUXThemeData::GetTheme(eUXTooltip);
|
||||
// XP/2K3 should force a classic treatment of tooltips
|
||||
return !IsVistaOrLater() ?
|
||||
nullptr : nsUXThemeData::GetTheme(eUXTooltip);
|
||||
case NS_THEME_TOOLBOX:
|
||||
return nsUXThemeData::GetTheme(eUXRebar);
|
||||
case NS_THEME_WIN_MEDIA_TOOLBOX:
|
||||
|
@ -735,6 +876,12 @@ nsresult
|
|||
nsNativeThemeWin::GetThemePartAndState(nsIFrame* aFrame, uint8_t aWidgetType,
|
||||
int32_t& aPart, int32_t& aState)
|
||||
{
|
||||
if (!IsVistaOrLater()) {
|
||||
// See GetTheme
|
||||
if (aWidgetType == NS_THEME_MENULIST)
|
||||
aWidgetType = NS_THEME_TEXTFIELD;
|
||||
}
|
||||
|
||||
switch (aWidgetType) {
|
||||
case NS_THEME_BUTTON: {
|
||||
aPart = BP_BUTTON;
|
||||
|
@ -807,43 +954,63 @@ nsNativeThemeWin::GetThemePartAndState(nsIFrame* aFrame, uint8_t aWidgetType,
|
|||
case NS_THEME_TEXTFIELD_MULTILINE: {
|
||||
EventStates eventState = GetContentState(aFrame, aWidgetType);
|
||||
|
||||
/* Note: the NOSCROLL type has a rounded corner in each corner. The more
|
||||
* specific HSCROLL, VSCROLL, HVSCROLL types have side and/or top/bottom
|
||||
* edges rendered as straight horizontal lines with sharp corners to
|
||||
* accommodate a scrollbar. However, the scrollbar gets rendered on top
|
||||
* of this for us, so we don't care, and can just use NOSCROLL here.
|
||||
*/
|
||||
aPart = TFP_EDITBORDER_NOSCROLL;
|
||||
|
||||
if (!aFrame) {
|
||||
aState = TFS_EDITBORDER_NORMAL;
|
||||
} else if (IsDisabled(aFrame, eventState)) {
|
||||
aState = TFS_EDITBORDER_DISABLED;
|
||||
} else if (IsReadOnly(aFrame)) {
|
||||
/* no special read-only state */
|
||||
aState = TFS_EDITBORDER_NORMAL;
|
||||
} else {
|
||||
nsIContent* content = aFrame->GetContent();
|
||||
|
||||
/* XUL textboxes don't get focused themselves, because they have child
|
||||
* html:input.. but we can check the XUL focused attributes on them
|
||||
if (IsVistaOrLater()) {
|
||||
/* Note: the NOSCROLL type has a rounded corner in each
|
||||
* corner. The more specific HSCROLL, VSCROLL, HVSCROLL types
|
||||
* have side and/or top/bottom edges rendered as straight
|
||||
* horizontal lines with sharp corners to accommodate a
|
||||
* scrollbar. However, the scrollbar gets rendered on top of
|
||||
* this for us, so we don't care, and can just use NOSCROLL
|
||||
* here.
|
||||
*/
|
||||
if (content && content->IsXULElement() && IsFocused(aFrame))
|
||||
aState = TFS_EDITBORDER_FOCUSED;
|
||||
else if (eventState.HasAtLeastOneOfStates(NS_EVENT_STATE_ACTIVE | NS_EVENT_STATE_FOCUS))
|
||||
aState = TFS_EDITBORDER_FOCUSED;
|
||||
else if (eventState.HasState(NS_EVENT_STATE_HOVER))
|
||||
aState = TFS_EDITBORDER_HOVER;
|
||||
else
|
||||
aPart = TFP_EDITBORDER_NOSCROLL;
|
||||
|
||||
if (!aFrame) {
|
||||
aState = TFS_EDITBORDER_NORMAL;
|
||||
} else if (IsDisabled(aFrame, eventState)) {
|
||||
aState = TFS_EDITBORDER_DISABLED;
|
||||
} else if (IsReadOnly(aFrame)) {
|
||||
/* no special read-only state */
|
||||
aState = TFS_EDITBORDER_NORMAL;
|
||||
} else {
|
||||
nsIContent* content = aFrame->GetContent();
|
||||
|
||||
/* XUL textboxes don't get focused themselves, because they have child
|
||||
* html:input.. but we can check the XUL focused attributes on them
|
||||
*/
|
||||
if (content && content->IsXULElement() && IsFocused(aFrame))
|
||||
aState = TFS_EDITBORDER_FOCUSED;
|
||||
else if (eventState.HasAtLeastOneOfStates(NS_EVENT_STATE_ACTIVE | NS_EVENT_STATE_FOCUS))
|
||||
aState = TFS_EDITBORDER_FOCUSED;
|
||||
else if (eventState.HasState(NS_EVENT_STATE_HOVER))
|
||||
aState = TFS_EDITBORDER_HOVER;
|
||||
else
|
||||
aState = TFS_EDITBORDER_NORMAL;
|
||||
}
|
||||
} else {
|
||||
aPart = TFP_TEXTFIELD;
|
||||
|
||||
if (!aFrame)
|
||||
aState = TS_NORMAL;
|
||||
else if (IsDisabled(aFrame, eventState))
|
||||
aState = TS_DISABLED;
|
||||
else if (IsReadOnly(aFrame))
|
||||
aState = TFS_READONLY;
|
||||
else
|
||||
aState = StandardGetState(aFrame, aWidgetType, true);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
case NS_THEME_FOCUS_OUTLINE: {
|
||||
// XXX the EDITBORDER values don't respect DTBG_OMITCONTENT
|
||||
aPart = TFP_TEXTFIELD; //TFP_EDITBORDER_NOSCROLL;
|
||||
aState = TS_FOCUSED; //TFS_EDITBORDER_FOCUSED;
|
||||
if (IsVistaOrLater()) {
|
||||
// XXX the EDITBORDER values don't respect DTBG_OMITCONTENT
|
||||
aPart = TFP_TEXTFIELD; //TFP_EDITBORDER_NOSCROLL;
|
||||
aState = TS_FOCUSED; //TFS_EDITBORDER_FOCUSED;
|
||||
} else {
|
||||
aPart = TFP_TEXTFIELD;
|
||||
aState = TS_FOCUSED;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
case NS_THEME_TOOLTIP: {
|
||||
|
@ -867,9 +1034,11 @@ nsNativeThemeWin::GetThemePartAndState(nsIFrame* aFrame, uint8_t aWidgetType,
|
|||
nsIFrame* parentFrame = aFrame->GetParent();
|
||||
if (aWidgetType == NS_THEME_PROGRESSCHUNK_VERTICAL ||
|
||||
IsVerticalProgress(parentFrame)) {
|
||||
aPart = PP_FILLVERT;
|
||||
aPart = IsVistaOrLater() ?
|
||||
PP_FILLVERT : PP_CHUNKVERT;
|
||||
} else {
|
||||
aPart = PP_FILL;
|
||||
aPart = IsVistaOrLater() ?
|
||||
PP_FILL : PP_CHUNK;
|
||||
}
|
||||
|
||||
aState = PBBVS_NORMAL;
|
||||
|
@ -933,7 +1102,8 @@ nsNativeThemeWin::GetThemePartAndState(nsIFrame* aFrame, uint8_t aWidgetType,
|
|||
aState += TS_ACTIVE;
|
||||
else if (eventState.HasState(NS_EVENT_STATE_HOVER))
|
||||
aState += TS_HOVER;
|
||||
else if (parentState.HasState(NS_EVENT_STATE_HOVER))
|
||||
else if (IsVistaOrLater() &&
|
||||
parentState.HasState(NS_EVENT_STATE_HOVER))
|
||||
aState = (aWidgetType - NS_THEME_SCROLLBARBUTTON_UP) + SP_BUTTON_IMPLICIT_HOVER_BASE;
|
||||
else
|
||||
aState += TS_NORMAL;
|
||||
|
@ -1036,7 +1206,14 @@ nsNativeThemeWin::GetThemePartAndState(nsIFrame* aFrame, uint8_t aWidgetType,
|
|||
case NS_THEME_SCROLLBAR:
|
||||
case NS_THEME_SCROLLBAR_SMALL: {
|
||||
aState = 0;
|
||||
aPart = RP_BACKGROUND;
|
||||
if (IsVistaOrLater()) {
|
||||
// On vista, they have a part
|
||||
aPart = RP_BACKGROUND;
|
||||
} else {
|
||||
// Otherwise, they don't. (But I bet
|
||||
// RP_BACKGROUND would work here, too);
|
||||
aPart = 0;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
case NS_THEME_TOOLBAR: {
|
||||
|
@ -1161,7 +1338,8 @@ nsNativeThemeWin::GetThemePartAndState(nsIFrame* aFrame, uint8_t aWidgetType,
|
|||
aFrame = parentFrame;
|
||||
|
||||
EventStates eventState = GetContentState(aFrame, aWidgetType);
|
||||
aPart = CBP_DROPMARKER_VISTA;
|
||||
aPart = IsVistaOrLater() ?
|
||||
CBP_DROPMARKER_VISTA : CBP_DROPMARKER;
|
||||
|
||||
// For HTML controls with author styling, we should fall
|
||||
// back to the old dropmarker style to avoid clashes with
|
||||
|
@ -1181,25 +1359,28 @@ nsNativeThemeWin::GetThemePartAndState(nsIFrame* aFrame, uint8_t aWidgetType,
|
|||
else
|
||||
isOpen = IsOpenButton(aFrame);
|
||||
|
||||
if (isHTML || IsMenuListEditable(aFrame)) {
|
||||
if (isOpen) {
|
||||
/* Hover is propagated, but we need to know whether we're hovering
|
||||
* just the combobox frame, not the dropdown frame. But, we can't get
|
||||
* that information, since hover is on the content node, and they
|
||||
* share the same content node. So, instead, we cheat -- if the
|
||||
* dropdown is open, we always show the hover state. This looks fine
|
||||
* in practice.
|
||||
if (IsVistaOrLater()) {
|
||||
if (isHTML || IsMenuListEditable(aFrame)) {
|
||||
if (isOpen) {
|
||||
/* Hover is propagated, but we need to know whether we're
|
||||
* hovering just the combobox frame, not the dropdown frame.
|
||||
* But, we can't get that information, since hover is on the
|
||||
* content node, and they share the same content node. So,
|
||||
* instead, we cheat -- if the dropdown is open, we always
|
||||
* show the hover state. This looks fine in practice.
|
||||
*/
|
||||
aState = TS_HOVER;
|
||||
return NS_OK;
|
||||
}
|
||||
} else {
|
||||
/* On Vista, the dropdown indicator on a menulist button in
|
||||
* chrome is not given a hover effect. When the frame isn't
|
||||
* isn't HTML content, we cheat and force the dropdown state
|
||||
* to be normal. (Bug 430434)
|
||||
*/
|
||||
aState = TS_HOVER;
|
||||
aState = TS_NORMAL;
|
||||
return NS_OK;
|
||||
}
|
||||
} else {
|
||||
/* The dropdown indicator on a menulist button in chrome is not given a
|
||||
* hover effect. When the frame isn't isn't HTML content, we cheat and
|
||||
* force the dropdown state to be normal. (Bug 430434)
|
||||
*/
|
||||
aState = TS_NORMAL;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
aState = TS_NORMAL;
|
||||
|
@ -1703,7 +1884,7 @@ RENDER_AGAIN:
|
|||
else if (aWidgetType == NS_THEME_PROGRESSCHUNK ||
|
||||
aWidgetType == NS_THEME_PROGRESSCHUNK_VERTICAL) {
|
||||
DrawThemedProgressMeter(aFrame, aWidgetType, theme, hdc, part, state,
|
||||
&widgetRect, &clipRect);
|
||||
&widgetRect, &clipRect, p2a);
|
||||
}
|
||||
else if (aWidgetType == NS_THEME_FOCUS_OUTLINE) {
|
||||
// Inflate 'widgetRect' with the focus outline size.
|
||||
|
@ -1969,39 +2150,41 @@ nsNativeThemeWin::GetWidgetPadding(nsDeviceContext* aContext,
|
|||
return ok;
|
||||
}
|
||||
|
||||
if (aWidgetType == NS_THEME_NUMBER_INPUT ||
|
||||
aWidgetType == NS_THEME_TEXTFIELD ||
|
||||
aWidgetType == NS_THEME_TEXTFIELD_MULTILINE ||
|
||||
aWidgetType == NS_THEME_MENULIST)
|
||||
{
|
||||
// If we have author-specified padding for these elements, don't do the
|
||||
// fixups below.
|
||||
if (aFrame->PresContext()->HasAuthorSpecifiedRules(aFrame, NS_AUTHOR_SPECIFIED_PADDING))
|
||||
return false;
|
||||
}
|
||||
if (IsVistaOrLater()) {
|
||||
if (aWidgetType == NS_THEME_NUMBER_INPUT ||
|
||||
aWidgetType == NS_THEME_TEXTFIELD ||
|
||||
aWidgetType == NS_THEME_TEXTFIELD_MULTILINE ||
|
||||
aWidgetType == NS_THEME_MENULIST)
|
||||
{
|
||||
/* If we have author-specified padding for these elements, don't do the fixups below */
|
||||
if (aFrame->PresContext()->HasAuthorSpecifiedRules(aFrame, NS_AUTHOR_SPECIFIED_PADDING))
|
||||
return false;
|
||||
}
|
||||
|
||||
/* textfields need extra pixels on all sides, otherwise they wrap their
|
||||
* content too tightly. The actual border is drawn 1px inside the specified
|
||||
* rectangle, so Gecko will end up making the contents look too small.
|
||||
* Instead, we add 2px padding for the contents and fix this. (Used to be 1px
|
||||
* added, see bug 430212)
|
||||
*/
|
||||
if (aWidgetType == NS_THEME_NUMBER_INPUT ||
|
||||
aWidgetType == NS_THEME_TEXTFIELD ||
|
||||
aWidgetType == NS_THEME_TEXTFIELD_MULTILINE) {
|
||||
aResult->top = aResult->bottom = 2;
|
||||
aResult->left = aResult->right = 2;
|
||||
ScaleForFrameDPI(aResult, aFrame);
|
||||
return ok;
|
||||
} else if (IsHTMLContent(aFrame) && aWidgetType == NS_THEME_MENULIST) {
|
||||
/* For content menulist controls, we need an extra pixel so that we have
|
||||
* room to draw our focus rectangle stuff. Otherwise, the focus rect might
|
||||
* overlap the control's border.
|
||||
/* textfields need extra pixels on all sides, otherwise they
|
||||
* wrap their content too tightly. The actual border is drawn 1px
|
||||
* inside the specified rectangle, so Gecko will end up making the
|
||||
* contents look too small. Instead, we add 2px padding for the
|
||||
* contents and fix this. (Used to be 1px added, see bug 430212)
|
||||
*/
|
||||
aResult->top = aResult->bottom = 1;
|
||||
aResult->left = aResult->right = 1;
|
||||
ScaleForFrameDPI(aResult, aFrame);
|
||||
return ok;
|
||||
if (aWidgetType == NS_THEME_NUMBER_INPUT ||
|
||||
aWidgetType == NS_THEME_TEXTFIELD ||
|
||||
aWidgetType == NS_THEME_TEXTFIELD_MULTILINE) {
|
||||
aResult->top = aResult->bottom = 2;
|
||||
aResult->left = aResult->right = 2;
|
||||
ScaleForFrameDPI(aResult, aFrame);
|
||||
return ok;
|
||||
} else if (IsHTMLContent(aFrame) && aWidgetType == NS_THEME_MENULIST) {
|
||||
/* For content menulist controls, we need an extra pixel so
|
||||
* that we have room to draw our focus rectangle stuff.
|
||||
* Otherwise, the focus rect might overlap the control's
|
||||
* border.
|
||||
*/
|
||||
aResult->top = aResult->bottom = 1;
|
||||
aResult->left = aResult->right = 1;
|
||||
ScaleForFrameDPI(aResult, aFrame);
|
||||
return ok;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t right, left, top, bottom;
|
||||
|
@ -2066,21 +2249,23 @@ nsNativeThemeWin::GetWidgetOverflow(nsDeviceContext* aContext,
|
|||
* a border only shows up if the widget is being hovered.
|
||||
*/
|
||||
#if 0
|
||||
/* We explicitly draw dropdown buttons in HTML content 1px bigger up, right,
|
||||
* and bottom so that they overlap the dropdown's border like they're
|
||||
* supposed to.
|
||||
*/
|
||||
if (aWidgetType == NS_THEME_MENULIST_BUTTON &&
|
||||
IsHTMLContent(aFrame) &&
|
||||
!IsWidgetStyled(aFrame->GetParent()->PresContext(),
|
||||
aFrame->GetParent(),
|
||||
NS_THEME_MENULIST))
|
||||
{
|
||||
int32_t p2a = aContext->AppUnitsPerDevPixel();
|
||||
/* Note: no overflow on the left */
|
||||
nsMargin m(p2a, p2a, p2a, 0);
|
||||
aOverflowRect->Inflate (m);
|
||||
return true;
|
||||
if (IsVistaOrLater()) {
|
||||
/* We explicitly draw dropdown buttons in HTML content 1px bigger
|
||||
* up, right, and bottom so that they overlap the dropdown's border
|
||||
* like they're supposed to.
|
||||
*/
|
||||
if (aWidgetType == NS_THEME_MENULIST_BUTTON &&
|
||||
IsHTMLContent(aFrame) &&
|
||||
!IsWidgetStyled(aFrame->GetParent()->PresContext(),
|
||||
aFrame->GetParent(),
|
||||
NS_THEME_MENULIST))
|
||||
{
|
||||
int32_t p2a = aContext->AppUnitsPerDevPixel();
|
||||
/* Note: no overflow on the left */
|
||||
nsMargin m(p2a, p2a, p2a, 0);
|
||||
aOverflowRect->Inflate (m);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -2204,18 +2389,22 @@ nsNativeThemeWin::GetMinimumWidgetSize(nsPresContext* aPresContext, nsIFrame* aF
|
|||
case NS_THEME_SCALETHUMB_VERTICAL:
|
||||
{
|
||||
*aIsOverridable = false;
|
||||
// On Vista, GetThemePartAndState returns odd values for
|
||||
// on Vista, GetThemePartAndState returns odd values for
|
||||
// scale thumbs, so use a hardcoded size instead.
|
||||
if (aWidgetType == NS_THEME_SCALETHUMB_HORIZONTAL ||
|
||||
(aWidgetType == NS_THEME_RANGE_THUMB && IsRangeHorizontal(aFrame))) {
|
||||
aResult->width = 12;
|
||||
aResult->height = 20;
|
||||
} else {
|
||||
aResult->width = 20;
|
||||
aResult->height = 12;
|
||||
if (IsVistaOrLater()) {
|
||||
if (aWidgetType == NS_THEME_SCALETHUMB_HORIZONTAL ||
|
||||
(aWidgetType == NS_THEME_RANGE_THUMB && IsRangeHorizontal(aFrame))) {
|
||||
aResult->width = 12;
|
||||
aResult->height = 20;
|
||||
}
|
||||
else {
|
||||
aResult->width = 20;
|
||||
aResult->height = 12;
|
||||
}
|
||||
ScaleForFrameDPI(aResult, aFrame);
|
||||
return rv;
|
||||
}
|
||||
ScaleForFrameDPI(aResult, aFrame);
|
||||
return rv;
|
||||
break;
|
||||
}
|
||||
|
||||
case NS_THEME_SCROLLBAR:
|
||||
|
@ -2254,6 +2443,11 @@ nsNativeThemeWin::GetMinimumWidgetSize(nsPresContext* aPresContext, nsIFrame* aF
|
|||
// stores that info in nsUXThemeData.
|
||||
aResult->width = nsUXThemeData::sCommandButtons[CMDBUTTONIDX_RESTORE].cx;
|
||||
aResult->height = nsUXThemeData::sCommandButtons[CMDBUTTONIDX_RESTORE].cy;
|
||||
// For XP, subtract 4 from system metrics dimensions.
|
||||
if (!IsVistaOrLater()) {
|
||||
aResult->width -= 4;
|
||||
aResult->height -= 4;
|
||||
}
|
||||
AddPaddingRect(aResult, CAPTIONBUTTON_RESTORE);
|
||||
*aIsOverridable = false;
|
||||
return rv;
|
||||
|
@ -2261,6 +2455,10 @@ nsNativeThemeWin::GetMinimumWidgetSize(nsPresContext* aPresContext, nsIFrame* aF
|
|||
case NS_THEME_WINDOW_BUTTON_MINIMIZE:
|
||||
aResult->width = nsUXThemeData::sCommandButtons[CMDBUTTONIDX_MINIMIZE].cx;
|
||||
aResult->height = nsUXThemeData::sCommandButtons[CMDBUTTONIDX_MINIMIZE].cy;
|
||||
if (!IsVistaOrLater()) {
|
||||
aResult->width -= 4;
|
||||
aResult->height -= 4;
|
||||
}
|
||||
AddPaddingRect(aResult, CAPTIONBUTTON_MINIMIZE);
|
||||
*aIsOverridable = false;
|
||||
return rv;
|
||||
|
@ -2268,6 +2466,10 @@ nsNativeThemeWin::GetMinimumWidgetSize(nsPresContext* aPresContext, nsIFrame* aF
|
|||
case NS_THEME_WINDOW_BUTTON_CLOSE:
|
||||
aResult->width = nsUXThemeData::sCommandButtons[CMDBUTTONIDX_CLOSE].cx;
|
||||
aResult->height = nsUXThemeData::sCommandButtons[CMDBUTTONIDX_CLOSE].cy;
|
||||
if (!IsVistaOrLater()) {
|
||||
aResult->width -= 4;
|
||||
aResult->height -= 4;
|
||||
}
|
||||
AddPaddingRect(aResult, CAPTIONBUTTON_CLOSE);
|
||||
*aIsOverridable = false;
|
||||
return rv;
|
||||
|
@ -2397,9 +2599,18 @@ nsNativeThemeWin::WidgetStateChanged(nsIFrame* aFrame, uint8_t aWidgetType,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// On Vista, the scrollbar buttons need to change state when the track has/doesn't have hover
|
||||
if (!IsVistaOrLater() &&
|
||||
(aWidgetType == NS_THEME_SCROLLBAR_VERTICAL ||
|
||||
aWidgetType == NS_THEME_SCROLLBAR_HORIZONTAL)) {
|
||||
*aShouldRepaint = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// We need to repaint the dropdown arrow in vista HTML combobox controls when
|
||||
// the control is closed to get rid of the hover effect.
|
||||
if ((aWidgetType == NS_THEME_MENULIST || aWidgetType == NS_THEME_MENULIST_BUTTON) &&
|
||||
if (IsVistaOrLater() &&
|
||||
(aWidgetType == NS_THEME_MENULIST || aWidgetType == NS_THEME_MENULIST_BUTTON) &&
|
||||
IsHTMLContent(aFrame))
|
||||
{
|
||||
*aShouldRepaint = true;
|
||||
|
|
|
@ -117,7 +117,8 @@ protected:
|
|||
void DrawThemedProgressMeter(nsIFrame* aFrame, int aWidgetType,
|
||||
HANDLE aTheme, HDC aHdc,
|
||||
int aPart, int aState,
|
||||
RECT* aWidgetRect, RECT* aClipRect);
|
||||
RECT* aWidgetRect, RECT* aClipRect,
|
||||
gfxFloat aAppUnits);
|
||||
|
||||
private:
|
||||
TimeStamp mProgressDeterminateTimeStamp;
|
||||
|
|
|
@ -67,7 +67,7 @@
|
|||
#define SP_GRIPPERHOR 8
|
||||
#define SP_GRIPPERVERT 9
|
||||
|
||||
// Implicit hover state.
|
||||
// Vista only; implict hover state.
|
||||
// BASE + 0 = UP, + 1 = DOWN, etc.
|
||||
#define SP_BUTTON_IMPLICIT_HOVER_BASE 17
|
||||
|
||||
|
|
|
@ -143,8 +143,10 @@ nsUXThemeData::InitTitlebarInfo()
|
|||
sCommandButtons[3].cx = sCommandButtons[0].cx * 3;
|
||||
sCommandButtons[3].cy = sCommandButtons[0].cy;
|
||||
|
||||
// Trigger a refresh on the next layout.
|
||||
sTitlebarInfoPopulatedAero = sTitlebarInfoPopulatedThemed = false;
|
||||
// Use system metrics for pre-vista, otherwise trigger a
|
||||
// refresh on the next layout.
|
||||
sTitlebarInfoPopulatedAero = sTitlebarInfoPopulatedThemed =
|
||||
!IsVistaOrLater();
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -304,7 +306,7 @@ void
|
|||
nsUXThemeData::UpdateNativeThemeInfo()
|
||||
{
|
||||
// Trigger a refresh of themed button metrics if needed
|
||||
sTitlebarInfoPopulatedThemed = false;
|
||||
sTitlebarInfoPopulatedThemed = !IsVistaOrLater();
|
||||
|
||||
sIsDefaultWindowsTheme = false;
|
||||
sThemeId = LookAndFeel::eWindowsTheme_Generic;
|
||||
|
|
|
@ -17,6 +17,155 @@
|
|||
#include "mozilla/EventForwards.h"
|
||||
#include "mozilla/TouchEvents.h"
|
||||
|
||||
// Desktop builds target apis for 502. Win8 Metro builds target 602.
|
||||
#if WINVER < 0x0602
|
||||
|
||||
DECLARE_HANDLE(HGESTUREINFO);
|
||||
|
||||
/*
|
||||
* Gesture flags - GESTUREINFO.dwFlags
|
||||
*/
|
||||
#define GF_BEGIN 0x00000001
|
||||
#define GF_INERTIA 0x00000002
|
||||
#define GF_END 0x00000004
|
||||
|
||||
/*
|
||||
* Gesture configuration structure
|
||||
* - Used in SetGestureConfig and GetGestureConfig
|
||||
* - Note that any setting not included in either GESTURECONFIG.dwWant or
|
||||
* GESTURECONFIG.dwBlock will use the parent window's preferences or
|
||||
* system defaults.
|
||||
*/
|
||||
typedef struct tagGESTURECONFIG {
|
||||
DWORD dwID; // gesture ID
|
||||
DWORD dwWant; // settings related to gesture ID that are to be turned on
|
||||
DWORD dwBlock; // settings related to gesture ID that are to be turned off
|
||||
} GESTURECONFIG, *PGESTURECONFIG;
|
||||
|
||||
/*
|
||||
* Gesture information structure
|
||||
* - Pass the HGESTUREINFO received in the WM_GESTURE message lParam into the
|
||||
* GetGestureInfo function to retrieve this information.
|
||||
* - If cbExtraArgs is non-zero, pass the HGESTUREINFO received in the WM_GESTURE
|
||||
* message lParam into the GetGestureExtraArgs function to retrieve extended
|
||||
* argument information.
|
||||
*/
|
||||
typedef struct tagGESTUREINFO {
|
||||
UINT cbSize; // size, in bytes, of this structure (including variable length Args field)
|
||||
DWORD dwFlags; // see GF_* flags
|
||||
DWORD dwID; // gesture ID, see GID_* defines
|
||||
HWND hwndTarget; // handle to window targeted by this gesture
|
||||
POINTS ptsLocation; // current location of this gesture
|
||||
DWORD dwInstanceID; // internally used
|
||||
DWORD dwSequenceID; // internally used
|
||||
ULONGLONG ullArguments; // arguments for gestures whose arguments fit in 8 BYTES
|
||||
UINT cbExtraArgs; // size, in bytes, of extra arguments, if any, that accompany this gesture
|
||||
} GESTUREINFO, *PGESTUREINFO;
|
||||
typedef GESTUREINFO const * PCGESTUREINFO;
|
||||
|
||||
/*
|
||||
* Gesture notification structure
|
||||
* - The WM_GESTURENOTIFY message lParam contains a pointer to this structure.
|
||||
* - The WM_GESTURENOTIFY message notifies a window that gesture recognition is
|
||||
* in progress and a gesture will be generated if one is recognized under the
|
||||
* current gesture settings.
|
||||
*/
|
||||
typedef struct tagGESTURENOTIFYSTRUCT {
|
||||
UINT cbSize; // size, in bytes, of this structure
|
||||
DWORD dwFlags; // unused
|
||||
HWND hwndTarget; // handle to window targeted by the gesture
|
||||
POINTS ptsLocation; // starting location
|
||||
DWORD dwInstanceID; // internally used
|
||||
} GESTURENOTIFYSTRUCT, *PGESTURENOTIFYSTRUCT;
|
||||
|
||||
|
||||
/*
|
||||
* Gesture argument helpers
|
||||
* - Angle should be a double in the range of -2pi to +2pi
|
||||
* - Argument should be an unsigned 16-bit value
|
||||
*/
|
||||
#define GID_ROTATE_ANGLE_TO_ARGUMENT(_arg_) ((USHORT)((((_arg_) + 2.0 * 3.14159265) / (4.0 * 3.14159265)) * 65535.0))
|
||||
#define GID_ROTATE_ANGLE_FROM_ARGUMENT(_arg_) ((((double)(_arg_) / 65535.0) * 4.0 * 3.14159265) - 2.0 * 3.14159265)
|
||||
|
||||
/*
|
||||
* Gesture configuration flags
|
||||
*/
|
||||
#define GC_ALLGESTURES 0x00000001
|
||||
|
||||
#define GC_ZOOM 0x00000001
|
||||
|
||||
#define GC_PAN 0x00000001
|
||||
#define GC_PAN_WITH_SINGLE_FINGER_VERTICALLY 0x00000002
|
||||
#define GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY 0x00000004
|
||||
#define GC_PAN_WITH_GUTTER 0x00000008
|
||||
#define GC_PAN_WITH_INERTIA 0x00000010
|
||||
|
||||
#define GC_ROTATE 0x00000001
|
||||
|
||||
#define GC_TWOFINGERTAP 0x00000001
|
||||
|
||||
#define GC_PRESSANDTAP 0x00000001
|
||||
|
||||
/*
|
||||
* Gesture IDs
|
||||
*/
|
||||
#define GID_BEGIN 1
|
||||
#define GID_END 2
|
||||
#define GID_ZOOM 3
|
||||
#define GID_PAN 4
|
||||
#define GID_ROTATE 5
|
||||
#define GID_TWOFINGERTAP 6
|
||||
#define GID_PRESSANDTAP 7
|
||||
|
||||
// Maximum number of gestures that can be included
|
||||
// in a single call to SetGestureConfig / GetGestureConfig
|
||||
#define GESTURECONFIGMAXCOUNT 256
|
||||
|
||||
// If specified, GetGestureConfig returns consolidated configuration
|
||||
// for the specified window and it's parent window chain
|
||||
#define GCF_INCLUDE_ANCESTORS 0x00000001
|
||||
|
||||
// Window events we need to respond to or receive
|
||||
#define WM_GESTURE 0x0119
|
||||
#define WM_GESTURENOTIFY 0x011A
|
||||
|
||||
typedef struct _TOUCHINPUT {
|
||||
LONG x;
|
||||
LONG y;
|
||||
HANDLE hSource;
|
||||
DWORD dwID;
|
||||
DWORD dwFlags;
|
||||
DWORD dwMask;
|
||||
DWORD dwTime;
|
||||
ULONG_PTR dwExtraInfo;
|
||||
DWORD cxContact;
|
||||
DWORD cyContact;
|
||||
} TOUCHINPUT, *PTOUCHINPUT;
|
||||
|
||||
typedef HANDLE HTOUCHINPUT;
|
||||
|
||||
#define WM_TOUCH 0x0240
|
||||
|
||||
#define TOUCHEVENTF_MOVE 0x0001
|
||||
#define TOUCHEVENTF_DOWN 0x0002
|
||||
#define TOUCHEVENTF_UP 0x0004
|
||||
#define TOUCHEVENTF_INRANGE 0x0008
|
||||
#define TOUCHEVENTF_PRIMARY 0x0010
|
||||
#define TOUCHEVENTF_NOCOALESCE 0x0020
|
||||
#define TOUCHEVENTF_PEN 0x0040
|
||||
#define TOUCHEVENTF_PALM 0x0080
|
||||
|
||||
#define TOUCHINPUTMASKF_TIMEFROMSYSTEM 0x0001
|
||||
#define TOUCHINPUTMASKF_EXTRAINFO 0x0002
|
||||
#define TOUCHINPUTMASKF_CONTACTAREA 0x0004
|
||||
|
||||
#define TOUCH_COORD_TO_PIXEL(C) (C/100)
|
||||
|
||||
#define TWF_FINETOUCH 0x0001
|
||||
#define TWF_WANTPALM 0x0002
|
||||
|
||||
#endif // WINVER < 0x0602
|
||||
|
||||
// WM_TABLET_QUERYSYSTEMGESTURESTATUS return values
|
||||
#define TABLET_ROTATE_GESTURE_ENABLE 0x02000000
|
||||
|
||||
|
|
|
@ -266,7 +266,8 @@ LONG nsWindow::sLastMouseDownTime = 0L;
|
|||
LONG nsWindow::sLastClickCount = 0L;
|
||||
BYTE nsWindow::sLastMouseButton = 0;
|
||||
|
||||
bool nsWindow::sHaveInitializedPrefs = false;
|
||||
// Trim heap on minimize. (initialized, but still true.)
|
||||
int nsWindow::sTrimOnMinimize = 2;
|
||||
|
||||
TriStateBool nsWindow::sHasBogusPopupsDropShadowOnMultiMonitor = TRI_UNKNOWN;
|
||||
|
||||
|
@ -789,7 +790,7 @@ nsWindow::Create(nsIWidget* aParent,
|
|||
parent = nullptr;
|
||||
}
|
||||
|
||||
if (!IsWin8OrLater() &&
|
||||
if (IsVistaOrLater() && !IsWin8OrLater() &&
|
||||
HasBogusPopupsDropShadowOnMultiMonitor()) {
|
||||
extendedStyle |= WS_EX_COMPOSITED;
|
||||
}
|
||||
|
@ -914,13 +915,20 @@ nsWindow::Create(nsIWidget* aParent,
|
|||
mDefaultIMC.Init(this);
|
||||
IMEHandler::InitInputContext(this, mInputContext);
|
||||
|
||||
// Do some initialization work, but only if (a) it hasn't already been done,
|
||||
// and (b) this is the hidden window (which is conveniently created before
|
||||
// any visible windows but after the profile has been initialized).
|
||||
if (!sHaveInitializedPrefs && mWindowType == eWindowType_invisible) {
|
||||
// If the internal variable set by the config.trim_on_minimize pref has not
|
||||
// been initialized, and if this is the hidden window (conveniently created
|
||||
// before any visible windows, and after the profile has been initialized),
|
||||
// do some initialization work.
|
||||
if (sTrimOnMinimize == 2 && mWindowType == eWindowType_invisible) {
|
||||
// Our internal trim prevention logic is effective on 2K/XP at maintaining
|
||||
// the working set when windows are minimized, but on Vista and up it has
|
||||
// little to no effect. Since this feature has been the source of numerous
|
||||
// bugs over the years, disable it (sTrimOnMinimize=1) on Vista and up.
|
||||
sTrimOnMinimize =
|
||||
Preferences::GetBool("config.trim_on_minimize",
|
||||
IsVistaOrLater() ? 1 : 0);
|
||||
sSwitchKeyboardLayout =
|
||||
Preferences::GetBool("intl.keyboard.per_window_layout", false);
|
||||
sHaveInitializedPrefs = true;
|
||||
}
|
||||
|
||||
// Query for command button metric data for rendering the titlebar. We
|
||||
|
@ -1646,10 +1654,9 @@ bool nsWindow::IsVisible() const
|
|||
|
||||
// XP and Vista visual styles sometimes require window clipping regions to be applied for proper
|
||||
// transparency. These routines are called on size and move operations.
|
||||
// XXX this is apparently still needed in Windows 7 and later
|
||||
void nsWindow::ClearThemeRegion()
|
||||
{
|
||||
if (!HasGlass() &&
|
||||
if (IsVistaOrLater() && !HasGlass() &&
|
||||
(mWindowType == eWindowType_popup && !IsPopupWithTitleBar() &&
|
||||
(mPopupType == ePopupTypeTooltip || mPopupType == ePopupTypePanel))) {
|
||||
SetWindowRgn(mWnd, nullptr, false);
|
||||
|
@ -1663,7 +1670,7 @@ void nsWindow::SetThemeRegion()
|
|||
// so default constants are used for part and state. At some point we might need part and
|
||||
// state values from nsNativeThemeWin's GetThemePartAndState, but currently windows that
|
||||
// change shape based on state haven't come up.
|
||||
if (!HasGlass() &&
|
||||
if (IsVistaOrLater() && !HasGlass() &&
|
||||
(mWindowType == eWindowType_popup && !IsPopupWithTitleBar() &&
|
||||
(mPopupType == ePopupTypeTooltip || mPopupType == ePopupTypePanel))) {
|
||||
HRGN hRgn = nullptr;
|
||||
|
@ -2080,7 +2087,13 @@ nsWindow::SetSizeMode(nsSizeMode aMode)
|
|||
break;
|
||||
|
||||
case nsSizeMode_Minimized :
|
||||
mode = SW_MINIMIZE;
|
||||
// Using SW_SHOWMINIMIZED prevents the working set from being trimmed but
|
||||
// keeps the window active in the tray. So after the window is minimized,
|
||||
// windows will fire WM_WINDOWPOSCHANGED (OnWindowPosChanged) at which point
|
||||
// we will do some additional processing to get the active window set right.
|
||||
// If sTrimOnMinimize is set, we let windows handle minimization normally
|
||||
// using SW_MINIMIZE.
|
||||
mode = sTrimOnMinimize ? SW_MINIMIZE : SW_SHOWMINIMIZED;
|
||||
break;
|
||||
|
||||
default :
|
||||
|
@ -5818,6 +5831,12 @@ nsWindow::ProcessMessage(UINT msg, WPARAM& wParam, LPARAM& lParam,
|
|||
case WM_SYSCOMMAND:
|
||||
{
|
||||
WPARAM filteredWParam = (wParam &0xFFF0);
|
||||
// prevent Windows from trimming the working set. bug 76831
|
||||
if (!sTrimOnMinimize && filteredWParam == SC_MINIMIZE) {
|
||||
::ShowWindow(mWnd, SW_SHOWMINIMIZED);
|
||||
result = true;
|
||||
}
|
||||
|
||||
if (mSizeMode == nsSizeMode_Fullscreen &&
|
||||
filteredWParam == SC_RESTORE &&
|
||||
GetCurrentShowCmd(mWnd) != SW_SHOWMINIMIZED) {
|
||||
|
@ -6435,6 +6454,14 @@ void nsWindow::OnWindowPosChanged(WINDOWPOS* wp)
|
|||
else
|
||||
mSizeMode = nsSizeMode_Normal;
|
||||
|
||||
// If !sTrimOnMinimize, we minimize windows using SW_SHOWMINIMIZED (See
|
||||
// SetSizeMode for internal calls, and WM_SYSCOMMAND for external). This
|
||||
// prevents the working set from being trimmed but keeps the window active.
|
||||
// After the window is minimized, we need to do some touch up work on the
|
||||
// active window. (bugs 76831 & 499816)
|
||||
if (!sTrimOnMinimize && nsSizeMode_Minimized == mSizeMode)
|
||||
ActivateOtherWindowHelper(mWnd);
|
||||
|
||||
#ifdef WINSTATE_DEBUG_OUTPUT
|
||||
switch (mSizeMode) {
|
||||
case nsSizeMode_Normal:
|
||||
|
@ -6555,6 +6582,31 @@ void nsWindow::OnWindowPosChanged(WINDOWPOS* wp)
|
|||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void nsWindow::ActivateOtherWindowHelper(HWND aWnd)
|
||||
{
|
||||
// Find the next window that is enabled, visible, and not minimized.
|
||||
HWND hwndBelow = ::GetNextWindow(aWnd, GW_HWNDNEXT);
|
||||
while (hwndBelow && (!::IsWindowEnabled(hwndBelow) || !::IsWindowVisible(hwndBelow) ||
|
||||
::IsIconic(hwndBelow))) {
|
||||
hwndBelow = ::GetNextWindow(hwndBelow, GW_HWNDNEXT);
|
||||
}
|
||||
|
||||
// Push ourselves to the bottom of the stack, then activate the
|
||||
// next window.
|
||||
::SetWindowPos(aWnd, HWND_BOTTOM, 0, 0, 0, 0,
|
||||
SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
|
||||
if (hwndBelow)
|
||||
::SetForegroundWindow(hwndBelow);
|
||||
|
||||
// Play the minimize sound while we're here, since that is also
|
||||
// forgotten when we use SW_SHOWMINIMIZED.
|
||||
nsCOMPtr<nsISound> sound(do_CreateInstance("@mozilla.org/sound;1"));
|
||||
if (sound) {
|
||||
sound->PlaySystemSound(NS_LITERAL_STRING("Minimize"));
|
||||
}
|
||||
}
|
||||
|
||||
void nsWindow::OnWindowPosChanging(LPWINDOWPOS& info)
|
||||
{
|
||||
// Update non-client margins if the frame size is changing, and let the
|
||||
|
|
|
@ -486,6 +486,7 @@ protected:
|
|||
bool aIntersectWithExisting) override;
|
||||
nsIntRegion GetRegionToPaint(bool aForceFullRepaint,
|
||||
PAINTSTRUCT ps, HDC aDC);
|
||||
static void ActivateOtherWindowHelper(HWND aWnd);
|
||||
void ClearCachedResources();
|
||||
nsIWidgetListener* GetPaintListener();
|
||||
|
||||
|
@ -551,7 +552,7 @@ protected:
|
|||
static bool sJustGotDeactivate;
|
||||
static bool sJustGotActivate;
|
||||
static bool sIsInMouseCapture;
|
||||
static bool sHaveInitializedPrefs;
|
||||
static int sTrimOnMinimize;
|
||||
|
||||
// Always use the helper method to read this property. See bug 603793.
|
||||
static TriStateBool sHasBogusPopupsDropShadowOnMultiMonitor;
|
||||
|
|
|
@ -111,6 +111,7 @@ extern nsresult nsStringInputStreamConstructor(nsISupports*, REFNSIID, void**);
|
|||
#include "SpecialSystemDirectory.h"
|
||||
|
||||
#if defined(XP_WIN)
|
||||
#include "mozilla/WindowsVersion.h"
|
||||
#include "nsWindowsRegKey.h"
|
||||
#endif
|
||||
|
||||
|
@ -583,6 +584,8 @@ NS_InitXPCOM2(nsIServiceManager** aResult,
|
|||
|
||||
NS_StartupLocalFile();
|
||||
|
||||
StartupSpecialSystemDirectory();
|
||||
|
||||
nsDirectoryService::RealInit();
|
||||
|
||||
bool value;
|
||||
|
|
|
@ -20,10 +20,15 @@
|
|||
|
||||
#ifdef XP_WIN
|
||||
#include <windows.h>
|
||||
#include "mozilla/WindowsVersion.h"
|
||||
using mozilla::IsVistaOrLater;
|
||||
#elif defined(XP_MACOSX)
|
||||
#include <sys/resource.h>
|
||||
#endif
|
||||
|
||||
#include <pratom.h>
|
||||
#include <prthread.h>
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
#ifndef XPCOM_GLUE_AVOID_NSPR
|
||||
|
@ -438,7 +443,8 @@ nsThreadPoolNaming::SetThreadPoolName(const nsACString& aPoolName,
|
|||
nsAutoLowPriorityIO::nsAutoLowPriorityIO()
|
||||
{
|
||||
#if defined(XP_WIN)
|
||||
lowIOPrioritySet = SetThreadPriority(GetCurrentThread(),
|
||||
lowIOPrioritySet = IsVistaOrLater() &&
|
||||
SetThreadPriority(GetCurrentThread(),
|
||||
THREAD_MODE_BACKGROUND_BEGIN);
|
||||
#elif defined(XP_MACOSX)
|
||||
oldPriority = getiopolicy_np(IOPOL_TYPE_DISK, IOPOL_SCOPE_THREAD);
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#if defined(XP_WIN)
|
||||
|
||||
#include <windows.h>
|
||||
#include <shlobj.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
@ -19,6 +20,9 @@
|
|||
#include <shlobj.h>
|
||||
#include <knownfolders.h>
|
||||
#include <guiddef.h>
|
||||
#include "mozilla/WindowsVersion.h"
|
||||
|
||||
using mozilla::IsWin7OrLater;
|
||||
|
||||
#elif defined(XP_UNIX)
|
||||
|
||||
|
@ -47,17 +51,40 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef XP_WIN
|
||||
typedef HRESULT (WINAPI* nsGetKnownFolderPath)(GUID& rfid,
|
||||
DWORD dwFlags,
|
||||
HANDLE hToken,
|
||||
PWSTR* ppszPath);
|
||||
|
||||
static nsGetKnownFolderPath gGetKnownFolderPath = nullptr;
|
||||
#endif
|
||||
|
||||
void
|
||||
StartupSpecialSystemDirectory()
|
||||
{
|
||||
#if defined (XP_WIN)
|
||||
// SHGetKnownFolderPath is only available on Windows Vista
|
||||
// so that we need to use GetProcAddress to get the pointer.
|
||||
HMODULE hShell32DLLInst = GetModuleHandleW(L"shell32.dll");
|
||||
if (hShell32DLLInst) {
|
||||
gGetKnownFolderPath = (nsGetKnownFolderPath)
|
||||
GetProcAddress(hShell32DLLInst, "SHGetKnownFolderPath");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined (XP_WIN)
|
||||
|
||||
static nsresult
|
||||
GetKnownFolder(GUID* aGuid, nsIFile** aFile)
|
||||
{
|
||||
if (!aGuid) {
|
||||
if (!aGuid || !gGetKnownFolderPath) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
PWSTR path = nullptr;
|
||||
SHGetKnownFolderPath(*aGuid, 0, nullptr, &path);
|
||||
gGetKnownFolderPath(*aGuid, 0, nullptr, &path);
|
||||
|
||||
if (!path) {
|
||||
return NS_ERROR_FAILURE;
|
||||
|
@ -112,13 +139,19 @@ SHLoadLibraryFromKnownFolder(REFKNOWNFOLDERID aFolderId, DWORD aMode,
|
|||
}
|
||||
|
||||
/*
|
||||
* Return the default save-to location for the Windows Library passed in
|
||||
* through aFolderId.
|
||||
* Check to see if we're on Win7 and up, and if so, returns the default
|
||||
* save-to location for the Windows Library passed in through aFolderId.
|
||||
* Otherwise falls back on pre-win7 GetWindowsFolder.
|
||||
*/
|
||||
static nsresult
|
||||
GetLibrarySaveToPath(int aFallbackFolderId, REFKNOWNFOLDERID aFolderId,
|
||||
nsIFile** aFile)
|
||||
{
|
||||
// Skip off checking for library support if the os is Vista or lower.
|
||||
if (!IsWin7OrLater()) {
|
||||
return GetWindowsFolder(aFallbackFolderId, aFile);
|
||||
}
|
||||
|
||||
RefPtr<IShellLibrary> shellLib;
|
||||
RefPtr<IShellItem> savePath;
|
||||
HRESULT hr =
|
||||
|
|
|
@ -16,6 +16,9 @@
|
|||
#include "prenv.h"
|
||||
#endif
|
||||
|
||||
extern void StartupSpecialSystemDirectory();
|
||||
|
||||
|
||||
enum SystemDirectories {
|
||||
OS_DriveDirectory = 1,
|
||||
OS_TemporaryDirectory = 2,
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "mozilla/ArrayUtils.h"
|
||||
#include "mozilla/DebugOnly.h"
|
||||
#include "mozilla/UniquePtrExtensions.h"
|
||||
#include "mozilla/WindowsVersion.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsAutoPtr.h"
|
||||
|
@ -1974,11 +1975,13 @@ nsLocalFile::CopySingleFile(nsIFile* aSourceFile, nsIFile* aDestParent,
|
|||
// So we only use COPY_FILE_NO_BUFFERING when we have a remote drive.
|
||||
int copyOK;
|
||||
DWORD dwCopyFlags = COPY_FILE_ALLOW_DECRYPTED_DESTINATION;
|
||||
bool path1Remote, path2Remote;
|
||||
if (!IsRemoteFilePath(filePath.get(), path1Remote) ||
|
||||
!IsRemoteFilePath(destPath.get(), path2Remote) ||
|
||||
path1Remote || path2Remote) {
|
||||
dwCopyFlags |= COPY_FILE_NO_BUFFERING;
|
||||
if (IsVistaOrLater()) {
|
||||
bool path1Remote, path2Remote;
|
||||
if (!IsRemoteFilePath(filePath.get(), path1Remote) ||
|
||||
!IsRemoteFilePath(destPath.get(), path2Remote) ||
|
||||
path1Remote || path2Remote) {
|
||||
dwCopyFlags |= COPY_FILE_NO_BUFFERING;
|
||||
}
|
||||
}
|
||||
|
||||
if (FilePreferences::IsBlockedUNCPath(destPath)) {
|
||||
|
|
Loading…
Reference in New Issue