mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 03:15:11 +00:00
Bug 1002354 - Proxy nsIScreenManager and nsIScreen's from the child process to the parent process, with caching. r=roc,jimm,smichaud,snorp.
Changes to nsIScreen and nsIScreenManager were reviewed by roc. Changes to dom/ipc were reviewed by jimm. Changes to gfx/src/nsDeviceContext.cpp were reviewed by roc. Changes to widget/android were reviewed by snorp. Changes to widget/cocoa were reviewed by smichaud. Changes to widget/gtk were reviewed by roc. Changes to widget/windows were reviewed by jimm. Changes to widget/xpwidgets were reviewed by roc. --HG-- extra : rebase_source : 90d263235b40f6f6937d361705a4dfa44253318e extra : histedit_source : bab4e689269c67fe3eb65033b6987b93caf9a482%2C86645be32f82f0d80724532e528e597db165b1d1
This commit is contained in:
parent
29d2ce2ffe
commit
78e56ed33a
@ -59,6 +59,7 @@
|
||||
#include "nsIMutable.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
#include "nsScreenManagerProxy.h"
|
||||
#include "nsMemoryInfoDumper.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsStyleSheetService.h"
|
||||
@ -169,6 +170,7 @@ using namespace mozilla::jsipc;
|
||||
#if defined(MOZ_WIDGET_GONK)
|
||||
using namespace mozilla::system;
|
||||
#endif
|
||||
using namespace mozilla::widget;
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
static bool sNuwaForking = false;
|
||||
@ -1200,6 +1202,28 @@ ContentChild::DeallocPNeckoChild(PNeckoChild* necko)
|
||||
return true;
|
||||
}
|
||||
|
||||
PScreenManagerChild*
|
||||
ContentChild::AllocPScreenManagerChild(uint32_t* aNumberOfScreens,
|
||||
float* aSystemDefaultScale,
|
||||
bool* aSuccess)
|
||||
{
|
||||
// The ContentParent should never attempt to allocate the
|
||||
// nsScreenManagerProxy. Instead, the nsScreenManagerProxy
|
||||
// service is requested and instantiated via XPCOM, and the
|
||||
// constructor of nsScreenManagerProxy sets up the IPC connection.
|
||||
NS_NOTREACHED("Should never get here!");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
ContentChild::DeallocPScreenManagerChild(PScreenManagerChild* aService)
|
||||
{
|
||||
// nsScreenManagerProxy is AddRef'd in its constructor.
|
||||
nsScreenManagerProxy *child = static_cast<nsScreenManagerProxy*>(aService);
|
||||
child->Release();
|
||||
return true;
|
||||
}
|
||||
|
||||
PExternalHelperAppChild*
|
||||
ContentChild::AllocPExternalHelperAppChild(const OptionalURIParams& uri,
|
||||
const nsCString& aMimeContentType,
|
||||
|
@ -193,6 +193,12 @@ public:
|
||||
virtual PNeckoChild* AllocPNeckoChild() MOZ_OVERRIDE;
|
||||
virtual bool DeallocPNeckoChild(PNeckoChild*) MOZ_OVERRIDE;
|
||||
|
||||
virtual PScreenManagerChild*
|
||||
AllocPScreenManagerChild(uint32_t* aNumberOfScreens,
|
||||
float* aSystemDefaultScale,
|
||||
bool* aSuccess) MOZ_OVERRIDE;
|
||||
virtual bool DeallocPScreenManagerChild(PScreenManagerChild*) MOZ_OVERRIDE;
|
||||
|
||||
virtual PExternalHelperAppChild *AllocPExternalHelperAppChild(
|
||||
const OptionalURIParams& uri,
|
||||
const nsCString& aMimeContentType,
|
||||
|
@ -113,6 +113,7 @@
|
||||
#include "PreallocatedProcessManager.h"
|
||||
#include "ProcessPriorityManager.h"
|
||||
#include "SandboxHal.h"
|
||||
#include "ScreenManagerParent.h"
|
||||
#include "StructuredCloneUtils.h"
|
||||
#include "TabParent.h"
|
||||
#include "URIUtils.h"
|
||||
@ -189,6 +190,7 @@ using namespace mozilla::ipc;
|
||||
using namespace mozilla::layers;
|
||||
using namespace mozilla::net;
|
||||
using namespace mozilla::jsipc;
|
||||
using namespace mozilla::widget;
|
||||
|
||||
#ifdef ENABLE_TESTS
|
||||
|
||||
@ -2903,6 +2905,21 @@ ContentParent::DeallocPNeckoParent(PNeckoParent* necko)
|
||||
return true;
|
||||
}
|
||||
|
||||
PScreenManagerParent*
|
||||
ContentParent::AllocPScreenManagerParent(uint32_t* aNumberOfScreens,
|
||||
float* aSystemDefaultScale,
|
||||
bool* aSuccess)
|
||||
{
|
||||
return new ScreenManagerParent(aNumberOfScreens, aSystemDefaultScale, aSuccess);
|
||||
}
|
||||
|
||||
bool
|
||||
ContentParent::DeallocPScreenManagerParent(PScreenManagerParent* aActor)
|
||||
{
|
||||
delete aActor;
|
||||
return true;
|
||||
}
|
||||
|
||||
PExternalHelperAppParent*
|
||||
ContentParent::AllocPExternalHelperAppParent(const OptionalURIParams& uri,
|
||||
const nsCString& aMimeContentType,
|
||||
|
@ -230,6 +230,12 @@ public:
|
||||
return PContentParent::RecvPNeckoConstructor(aActor);
|
||||
}
|
||||
|
||||
virtual PScreenManagerParent*
|
||||
AllocPScreenManagerParent(uint32_t* aNumberOfScreens,
|
||||
float* aSystemDefaultScale,
|
||||
bool* aSuccess) MOZ_OVERRIDE;
|
||||
virtual bool DeallocPScreenManagerParent(PScreenManagerParent* aActor) MOZ_OVERRIDE;
|
||||
|
||||
virtual PHalParent* AllocPHalParent() MOZ_OVERRIDE;
|
||||
virtual bool RecvPHalConstructor(PHalParent* aActor) MOZ_OVERRIDE {
|
||||
return PContentParent::RecvPHalConstructor(aActor);
|
||||
|
@ -23,6 +23,7 @@ include protocol PImageBridge;
|
||||
include protocol PIndexedDB;
|
||||
include protocol PMemoryReportRequest;
|
||||
include protocol PNecko;
|
||||
include protocol PScreenManager;
|
||||
include protocol PSharedBufferManager;
|
||||
include protocol PSms;
|
||||
include protocol PSpeechSynthesis;
|
||||
@ -303,6 +304,7 @@ intr protocol PContent
|
||||
manages PIndexedDB;
|
||||
manages PMemoryReportRequest;
|
||||
manages PNecko;
|
||||
manages PScreenManager;
|
||||
manages PSms;
|
||||
manages PSpeechSynthesis;
|
||||
manages PStorage;
|
||||
@ -479,6 +481,11 @@ parent:
|
||||
|
||||
PNecko();
|
||||
|
||||
sync PScreenManager()
|
||||
returns (uint32_t numberOfScreens,
|
||||
float systemDefaultScale,
|
||||
bool success);
|
||||
|
||||
PSms();
|
||||
|
||||
PSpeechSynthesis();
|
||||
|
57
dom/ipc/PScreenManager.ipdl
Normal file
57
dom/ipc/PScreenManager.ipdl
Normal file
@ -0,0 +1,57 @@
|
||||
/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
include protocol PBrowser;
|
||||
include protocol PContent;
|
||||
|
||||
using struct nsIntRect from "nsRect.h";
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
struct ScreenDetails {
|
||||
uint32_t id;
|
||||
nsIntRect rect;
|
||||
nsIntRect availRect;
|
||||
int32_t pixelDepth;
|
||||
int32_t colorDepth;
|
||||
double contentsScaleFactor;
|
||||
};
|
||||
|
||||
sync protocol PScreenManager
|
||||
{
|
||||
manager PContent;
|
||||
|
||||
parent:
|
||||
sync Refresh()
|
||||
returns (uint32_t numberOfScreens,
|
||||
float systemDefaultScale,
|
||||
bool success);
|
||||
|
||||
sync ScreenRefresh(uint32_t aId)
|
||||
returns (ScreenDetails screen,
|
||||
bool success);
|
||||
|
||||
sync GetPrimaryScreen()
|
||||
returns (ScreenDetails screen,
|
||||
bool success);
|
||||
|
||||
sync ScreenForRect(int32_t aLeft,
|
||||
int32_t aTop,
|
||||
int32_t aWidth,
|
||||
int32_t aHeight)
|
||||
returns (ScreenDetails screen,
|
||||
bool success);
|
||||
|
||||
sync ScreenForBrowser(PBrowser aBrowser)
|
||||
returns (ScreenDetails screen,
|
||||
bool success);
|
||||
|
||||
child:
|
||||
__delete__();
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
195
dom/ipc/ScreenManagerParent.cpp
Normal file
195
dom/ipc/ScreenManagerParent.cpp
Normal file
@ -0,0 +1,195 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* vim: set sw=4 ts=8 et tw=80 : */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/dom/TabParent.h"
|
||||
#include "mozilla/unused.h"
|
||||
#include "nsIWidget.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "ScreenManagerParent.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
static const char *sScreenManagerContractID = "@mozilla.org/gfx/screenmanager;1";
|
||||
|
||||
ScreenManagerParent::ScreenManagerParent(uint32_t* aNumberOfScreens,
|
||||
float* aSystemDefaultScale,
|
||||
bool* aSuccess)
|
||||
{
|
||||
mScreenMgr = do_GetService(sScreenManagerContractID);
|
||||
if (!mScreenMgr) {
|
||||
MOZ_CRASH("Couldn't get nsIScreenManager from ScreenManagerParent.");
|
||||
}
|
||||
|
||||
unused << RecvRefresh(aNumberOfScreens, aSystemDefaultScale, aSuccess);
|
||||
}
|
||||
|
||||
bool
|
||||
ScreenManagerParent::RecvRefresh(uint32_t* aNumberOfScreens,
|
||||
float* aSystemDefaultScale,
|
||||
bool* aSuccess)
|
||||
{
|
||||
*aSuccess = false;
|
||||
|
||||
nsresult rv = mScreenMgr->GetNumberOfScreens(aNumberOfScreens);
|
||||
if (NS_FAILED(rv)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
rv = mScreenMgr->GetSystemDefaultScale(aSystemDefaultScale);
|
||||
if (NS_FAILED(rv)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
*aSuccess = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ScreenManagerParent::RecvScreenRefresh(const uint32_t& aId,
|
||||
ScreenDetails* aRetVal,
|
||||
bool* aSuccess)
|
||||
{
|
||||
*aSuccess = false;
|
||||
|
||||
nsCOMPtr<nsIScreen> screen;
|
||||
nsresult rv = mScreenMgr->ScreenForId(aId, getter_AddRefs(screen));
|
||||
if (NS_FAILED(rv)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
ScreenDetails details;
|
||||
unused << ExtractScreenDetails(screen, details);
|
||||
|
||||
*aRetVal = details;
|
||||
*aSuccess = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ScreenManagerParent::RecvGetPrimaryScreen(ScreenDetails* aRetVal,
|
||||
bool* aSuccess)
|
||||
{
|
||||
*aSuccess = false;
|
||||
|
||||
nsCOMPtr<nsIScreen> screen;
|
||||
nsresult rv = mScreenMgr->GetPrimaryScreen(getter_AddRefs(screen));
|
||||
|
||||
NS_ENSURE_SUCCESS(rv, true);
|
||||
|
||||
ScreenDetails details;
|
||||
if (!ExtractScreenDetails(screen, details)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
*aRetVal = details;
|
||||
*aSuccess = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ScreenManagerParent::RecvScreenForRect(const int32_t& aLeft,
|
||||
const int32_t& aTop,
|
||||
const int32_t& aWidth,
|
||||
const int32_t& aHeight,
|
||||
ScreenDetails* aRetVal,
|
||||
bool* aSuccess)
|
||||
{
|
||||
*aSuccess = false;
|
||||
|
||||
nsCOMPtr<nsIScreen> screen;
|
||||
nsresult rv = mScreenMgr->ScreenForRect(aLeft, aTop, aWidth, aHeight, getter_AddRefs(screen));
|
||||
|
||||
NS_ENSURE_SUCCESS(rv, true);
|
||||
|
||||
ScreenDetails details;
|
||||
if (!ExtractScreenDetails(screen, details)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
*aRetVal = details;
|
||||
*aSuccess = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ScreenManagerParent::RecvScreenForBrowser(PBrowserParent* aBrowser,
|
||||
ScreenDetails* aRetVal,
|
||||
bool* aSuccess)
|
||||
{
|
||||
*aSuccess = false;
|
||||
|
||||
// Find the mWidget associated with the tabparent, and then return
|
||||
// the nsIScreen it's on.
|
||||
TabParent* tabParent = static_cast<TabParent*>(aBrowser);
|
||||
nsCOMPtr<nsIWidget> widget = tabParent->GetWidget();
|
||||
if (!widget) {
|
||||
return true;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIScreen> screen;
|
||||
if (widget->GetNativeData(NS_NATIVE_WINDOW)) {
|
||||
mScreenMgr->ScreenForNativeWidget(widget->GetNativeData(NS_NATIVE_WINDOW),
|
||||
getter_AddRefs(screen));
|
||||
}
|
||||
|
||||
NS_ENSURE_TRUE(screen, true);
|
||||
|
||||
ScreenDetails details;
|
||||
if (!ExtractScreenDetails(screen, details)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
*aRetVal = details;
|
||||
*aSuccess = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ScreenManagerParent::ExtractScreenDetails(nsIScreen* aScreen, ScreenDetails &aDetails)
|
||||
{
|
||||
uint32_t id;
|
||||
nsresult rv = aScreen->GetId(&id);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
aDetails.id() = id;
|
||||
|
||||
nsIntRect rect;
|
||||
rv = aScreen->GetRect(&rect.x, &rect.y, &rect.width, &rect.height);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
aDetails.rect() = rect;
|
||||
|
||||
nsIntRect availRect;
|
||||
rv = aScreen->GetAvailRect(&availRect.x, &availRect.y, &availRect.width,
|
||||
&availRect.height);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
aDetails.availRect() = availRect;
|
||||
|
||||
int32_t pixelDepth = 0;
|
||||
rv = aScreen->GetPixelDepth(&pixelDepth);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
aDetails.pixelDepth() = pixelDepth;
|
||||
|
||||
int32_t colorDepth = 0;
|
||||
rv = aScreen->GetColorDepth(&colorDepth);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
aDetails.colorDepth() = colorDepth;
|
||||
|
||||
double contentsScaleFactor = 1.0;
|
||||
rv = aScreen->GetContentsScaleFactor(&contentsScaleFactor);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
aDetails.contentsScaleFactor() = contentsScaleFactor;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
ScreenManagerParent::ActorDestroy(ActorDestroyReason why)
|
||||
{
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
56
dom/ipc/ScreenManagerParent.h
Normal file
56
dom/ipc/ScreenManagerParent.h
Normal file
@ -0,0 +1,56 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* vim: set sw=4 ts=8 et tw=80 : */
|
||||
/* 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/. */
|
||||
|
||||
#ifndef mozilla_dom_ScreenManagerParent_h
|
||||
#define mozilla_dom_ScreenManagerParent_h
|
||||
|
||||
#include "mozilla/dom/PScreenManagerParent.h"
|
||||
#include "nsIScreenManager.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class ScreenManagerParent : public PScreenManagerParent
|
||||
{
|
||||
public:
|
||||
ScreenManagerParent(uint32_t* aNumberOfScreens,
|
||||
float* aSystemDefaultScale,
|
||||
bool* aSuccess);
|
||||
~ScreenManagerParent() {};
|
||||
|
||||
virtual bool RecvRefresh(uint32_t* aNumberOfScreens,
|
||||
float* aSystemDefaultScale,
|
||||
bool* aSuccess) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool RecvScreenRefresh(const uint32_t& aId,
|
||||
ScreenDetails* aRetVal,
|
||||
bool* aSuccess) MOZ_OVERRIDE;
|
||||
|
||||
virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool RecvGetPrimaryScreen(ScreenDetails* aRetVal,
|
||||
bool* aSuccess) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool RecvScreenForRect(const int32_t& aLeft,
|
||||
const int32_t& aTop,
|
||||
const int32_t& aWidth,
|
||||
const int32_t& aHeight,
|
||||
ScreenDetails* aRetVal,
|
||||
bool* aSuccess) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool RecvScreenForBrowser(PBrowserParent* aBrowser,
|
||||
ScreenDetails* aRetVal,
|
||||
bool* aSuccess);
|
||||
|
||||
private:
|
||||
bool ExtractScreenDetails(nsIScreen* aScreen, ScreenDetails &aDetails);
|
||||
nsCOMPtr<nsIScreenManager> mScreenMgr;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_ScreenManagerParent_h
|
@ -309,6 +309,8 @@ public:
|
||||
*/
|
||||
bool IsDestroyed() const { return mIsDestroyed; }
|
||||
|
||||
already_AddRefed<nsIWidget> GetWidget() const;
|
||||
|
||||
protected:
|
||||
bool ReceiveMessage(const nsString& aMessage,
|
||||
bool aSync,
|
||||
@ -380,7 +382,6 @@ protected:
|
||||
|
||||
private:
|
||||
already_AddRefed<nsFrameLoader> GetFrameLoader() const;
|
||||
already_AddRefed<nsIWidget> GetWidget() const;
|
||||
layout::RenderFrameParent* GetRenderFrame();
|
||||
nsRefPtr<nsIContentParent> mManager;
|
||||
void TryCacheDPIAndScale();
|
||||
|
@ -59,6 +59,7 @@ UNIFIED_SOURCES += [
|
||||
'PermissionMessageUtils.cpp',
|
||||
'PreallocatedProcessManager.cpp',
|
||||
'ProcessPriorityManager.cpp',
|
||||
'ScreenManagerParent.cpp',
|
||||
'StructuredCloneUtils.cpp',
|
||||
'TabChild.cpp',
|
||||
'TabContext.cpp',
|
||||
@ -92,6 +93,7 @@ IPDL_SOURCES += [
|
||||
'PFileDescriptorSet.ipdl',
|
||||
'PFilePicker.ipdl',
|
||||
'PMemoryReportRequest.ipdl',
|
||||
'PScreenManager.ipdl',
|
||||
'PTabContext.ipdlh',
|
||||
]
|
||||
|
||||
|
@ -631,11 +631,17 @@ nsDeviceContext::ComputeFullAreaUsingScreen(nsRect* outRect)
|
||||
void
|
||||
nsDeviceContext::FindScreen(nsIScreen** outScreen)
|
||||
{
|
||||
if (mWidget && mWidget->GetNativeData(NS_NATIVE_WINDOW))
|
||||
if (mWidget && mWidget->GetOwningTabChild()) {
|
||||
mScreenManager->ScreenForNativeWidget((void *)mWidget->GetOwningTabChild(),
|
||||
outScreen);
|
||||
}
|
||||
else if (mWidget && mWidget->GetNativeData(NS_NATIVE_WINDOW)) {
|
||||
mScreenManager->ScreenForNativeWidget(mWidget->GetNativeData(NS_NATIVE_WINDOW),
|
||||
outScreen);
|
||||
else
|
||||
}
|
||||
else {
|
||||
mScreenManager->GetPrimaryScreen(outScreen);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -19,6 +19,13 @@ nsScreenAndroid::~nsScreenAndroid()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScreenAndroid::GetId(uint32_t *outId)
|
||||
{
|
||||
*outId = 1;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScreenAndroid::GetRect(int32_t *outLeft, int32_t *outTop, int32_t *outWidth, int32_t *outHeight)
|
||||
{
|
||||
@ -80,6 +87,13 @@ nsScreenManagerAndroid::GetPrimaryScreen(nsIScreen **outScreen)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScreenManagerAndroid::ScreenForId(uint32_t aId,
|
||||
nsIScreen **outScreen)
|
||||
{
|
||||
return GetPrimaryScreen(outScreen);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScreenManagerAndroid::ScreenForRect(int32_t inLeft,
|
||||
int32_t inTop,
|
||||
|
@ -18,6 +18,7 @@ public:
|
||||
nsScreenAndroid(void *nativeScreen);
|
||||
~nsScreenAndroid();
|
||||
|
||||
NS_IMETHOD GetId(uint32_t* aId);
|
||||
NS_IMETHOD GetRect(int32_t* aLeft, int32_t* aTop, int32_t* aWidth, int32_t* aHeight);
|
||||
NS_IMETHOD GetAvailRect(int32_t* aLeft, int32_t* aTop, int32_t* aWidth, int32_t* aHeight);
|
||||
NS_IMETHOD GetPixelDepth(int32_t* aPixelDepth);
|
||||
|
@ -16,6 +16,7 @@ public:
|
||||
nsScreenCocoa (NSScreen *screen);
|
||||
~nsScreenCocoa ();
|
||||
|
||||
NS_IMETHOD GetId(uint32_t* outId);
|
||||
NS_IMETHOD GetRect(int32_t* aLeft, int32_t* aTop, int32_t* aWidth, int32_t* aHeight);
|
||||
NS_IMETHOD GetAvailRect(int32_t* aLeft, int32_t* aTop, int32_t* aWidth, int32_t* aHeight);
|
||||
NS_IMETHOD GetRectDisplayPix(int32_t* aLeft, int32_t* aTop, int32_t* aWidth, int32_t* aHeight);
|
||||
@ -30,6 +31,7 @@ private:
|
||||
CGFloat BackingScaleFactor();
|
||||
|
||||
NSScreen *mScreen;
|
||||
uint32_t mId;
|
||||
};
|
||||
|
||||
#endif // nsScreenCocoa_h_
|
||||
|
@ -7,11 +7,14 @@
|
||||
#include "nsObjCExceptions.h"
|
||||
#include "nsCocoaUtils.h"
|
||||
|
||||
static uint32_t sScreenId = 0;
|
||||
|
||||
nsScreenCocoa::nsScreenCocoa (NSScreen *screen)
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
mScreen = [screen retain];
|
||||
mId = ++sScreenId;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
@ -25,6 +28,17 @@ nsScreenCocoa::~nsScreenCocoa ()
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScreenCocoa::GetId(uint32_t *outId)
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
|
||||
|
||||
*outId = mId;
|
||||
return NS_OK;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScreenCocoa::GetRect(int32_t *outX, int32_t *outY, int32_t *outWidth, int32_t *outHeight)
|
||||
{
|
||||
|
@ -35,6 +35,30 @@ nsScreenManagerCocoa::ScreenForCocoaScreen(NSScreen *screen)
|
||||
return sc.get();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScreenManagerCocoa::ScreenForId (uint32_t aId, nsIScreen **outScreen)
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT
|
||||
|
||||
*outScreen = nullptr;
|
||||
|
||||
for (uint32_t i = 0; i < mScreenList.Length(); ++i) {
|
||||
nsScreenCocoa* sc = mScreenList[i];
|
||||
uint32_t id;
|
||||
nsresult rv = sc->GetId(&id);
|
||||
|
||||
if (NS_SUCCEEDED(rv) && id == aId) {
|
||||
*outScreen = sc;
|
||||
NS_ADDREF(*outScreen);
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScreenManagerCocoa::ScreenForRect (int32_t aX, int32_t aY, int32_t aWidth, int32_t aHeight,
|
||||
nsIScreen **outScreen)
|
||||
|
@ -134,7 +134,8 @@ static const mozilla::Module::CIDEntry kWidgetCIDs[] = {
|
||||
mozilla::Module::MAIN_PROCESS_ONLY },
|
||||
{ &kNS_BIDIKEYBOARD_CID, false, NULL, nsBidiKeyboardConstructor },
|
||||
{ &kNS_THEMERENDERER_CID, false, NULL, nsNativeThemeCocoaConstructor },
|
||||
{ &kNS_SCREENMANAGER_CID, false, NULL, nsScreenManagerCocoaConstructor },
|
||||
{ &kNS_SCREENMANAGER_CID, false, NULL, nsScreenManagerCocoaConstructor,
|
||||
mozilla::Module::MAIN_PROCESS_ONLY },
|
||||
{ &kNS_DEVICE_CONTEXT_SPEC_CID, false, NULL, nsDeviceContextSpecXConstructor,
|
||||
mozilla::Module::MAIN_PROCESS_ONLY },
|
||||
{ &kNS_PRINTSESSION_CID, false, NULL, nsPrintSessionConstructor,
|
||||
@ -172,7 +173,8 @@ static const mozilla::Module::ContractIDEntry kWidgetContracts[] = {
|
||||
mozilla::Module::MAIN_PROCESS_ONLY },
|
||||
{ "@mozilla.org/widget/bidikeyboard;1", &kNS_BIDIKEYBOARD_CID },
|
||||
{ "@mozilla.org/chrome/chrome-native-theme;1", &kNS_THEMERENDERER_CID },
|
||||
{ "@mozilla.org/gfx/screenmanager;1", &kNS_SCREENMANAGER_CID },
|
||||
{ "@mozilla.org/gfx/screenmanager;1", &kNS_SCREENMANAGER_CID,
|
||||
mozilla::Module::MAIN_PROCESS_ONLY },
|
||||
{ "@mozilla.org/gfx/devicecontextspec;1", &kNS_DEVICE_CONTEXT_SPEC_CID,
|
||||
mozilla::Module::MAIN_PROCESS_ONLY },
|
||||
{ "@mozilla.org/gfx/printsession;1", &kNS_PRINTSESSION_CID,
|
||||
|
@ -31,6 +31,7 @@ public:
|
||||
nsScreenGonk(void* nativeScreen);
|
||||
~nsScreenGonk();
|
||||
|
||||
NS_IMETHOD GetId(uint32_t* aId);
|
||||
NS_IMETHOD GetRect(int32_t* aLeft, int32_t* aTop, int32_t* aWidth, int32_t* aHeight);
|
||||
NS_IMETHOD GetAvailRect(int32_t* aLeft, int32_t* aTop, int32_t* aWidth, int32_t* aHeight);
|
||||
NS_IMETHOD GetPixelDepth(int32_t* aPixelDepth);
|
||||
|
@ -609,6 +609,13 @@ nsScreenGonk::~nsScreenGonk()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScreenGonk::GetId(uint32_t *outId)
|
||||
{
|
||||
*outId = 1;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScreenGonk::GetRect(int32_t *outLeft, int32_t *outTop,
|
||||
int32_t *outWidth, int32_t *outHeight)
|
||||
@ -754,6 +761,13 @@ nsScreenManagerGonk::GetPrimaryScreen(nsIScreen **outScreen)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScreenManagerGonk::ScreenForId(uint32_t aId,
|
||||
nsIScreen **outScreen)
|
||||
{
|
||||
return GetPrimaryScreen(outScreen);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScreenManagerGonk::ScreenForRect(int32_t inLeft,
|
||||
int32_t inTop,
|
||||
|
@ -12,10 +12,14 @@
|
||||
#endif
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
static uint32_t sScreenId = 0;
|
||||
|
||||
|
||||
nsScreenGtk :: nsScreenGtk ( )
|
||||
: mScreenNum(0),
|
||||
mRect(0, 0, 0, 0),
|
||||
mAvailRect(0, 0, 0, 0)
|
||||
mAvailRect(0, 0, 0, 0),
|
||||
mId(++sScreenId)
|
||||
{
|
||||
}
|
||||
|
||||
@ -25,6 +29,20 @@ nsScreenGtk :: ~nsScreenGtk()
|
||||
}
|
||||
|
||||
|
||||
nsScreenGtk :: GetId(uint32_t *aId)
|
||||
{
|
||||
*aId = mId;
|
||||
return NS_OK;
|
||||
} // GetId
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScreenGtk :: GetId(uint32_t *aId)
|
||||
{
|
||||
*aId = mId;
|
||||
return NS_OK;
|
||||
} // GetId
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScreenGtk :: GetRect(int32_t *outLeft, int32_t *outTop, int32_t *outWidth, int32_t *outHeight)
|
||||
{
|
||||
|
@ -30,6 +30,7 @@ public:
|
||||
nsScreenGtk();
|
||||
~nsScreenGtk();
|
||||
|
||||
NS_IMETHOD GetId(uint32_t* aId);
|
||||
NS_IMETHOD GetRect(int32_t* aLeft, int32_t* aTop, int32_t* aWidth, int32_t* aHeight);
|
||||
NS_IMETHOD GetAvailRect(int32_t* aLeft, int32_t* aTop, int32_t* aWidth, int32_t* aHeight);
|
||||
NS_IMETHOD GetPixelDepth(int32_t* aPixelDepth);
|
||||
@ -44,6 +45,7 @@ private:
|
||||
uint32_t mScreenNum;
|
||||
nsIntRect mRect;
|
||||
nsIntRect mAvailRect;
|
||||
uint32_t mId;
|
||||
};
|
||||
|
||||
#endif // nsScreenGtk_h___
|
||||
|
@ -188,6 +188,30 @@ nsScreenManagerGtk :: Init()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScreenManagerGtk :: ScreenForId ( uint32_t aId, nsIScreen **outScreen )
|
||||
{
|
||||
*outScreen = nullptr;
|
||||
|
||||
nsresult rv;
|
||||
rv = EnsureInit();
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_ERROR("nsScreenManagerGtk::EnsureInit() failed from ScreenForId");
|
||||
return rv;
|
||||
}
|
||||
|
||||
for (int32_t i = 0, i_end = mCachedScreenArray.Count(); i < i_end; ++i) {
|
||||
uint32_t id;
|
||||
rv = mCachedScreenArray[i]->GetId(&id);
|
||||
if (NS_SUCCEEDED(rv) && id == aId) {
|
||||
NS_IF_ADDREF(*outScreen = mCachedScreenArray[i]);
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// ScreenForRect
|
||||
|
@ -214,7 +214,8 @@ static const mozilla::Module::CIDEntry kWidgetCIDs[] = {
|
||||
#endif
|
||||
{ &kNS_HTMLFORMATCONVERTER_CID, false, nullptr, nsHTMLFormatConverterConstructor },
|
||||
{ &kNS_BIDIKEYBOARD_CID, false, nullptr, nsBidiKeyboardConstructor },
|
||||
{ &kNS_SCREENMANAGER_CID, false, nullptr, nsScreenManagerGtkConstructor },
|
||||
{ &kNS_SCREENMANAGER_CID, false, nullptr, nsScreenManagerGtkConstructor,
|
||||
Module::MAIN_PROCESS_ONLY },
|
||||
{ &kNS_THEMERENDERER_CID, false, nullptr, nsNativeThemeGTKConstructor },
|
||||
#ifdef NS_PRINTING
|
||||
{ &kNS_PRINTSETTINGSSERVICE_CID, false, nullptr, nsPrintOptionsGTKConstructor },
|
||||
@ -250,7 +251,8 @@ static const mozilla::Module::ContractIDEntry kWidgetContracts[] = {
|
||||
#endif
|
||||
{ "@mozilla.org/widget/htmlformatconverter;1", &kNS_HTMLFORMATCONVERTER_CID },
|
||||
{ "@mozilla.org/widget/bidikeyboard;1", &kNS_BIDIKEYBOARD_CID },
|
||||
{ "@mozilla.org/gfx/screenmanager;1", &kNS_SCREENMANAGER_CID },
|
||||
{ "@mozilla.org/gfx/screenmanager;1", &kNS_SCREENMANAGER_CID,
|
||||
Module::MAIN_PROCESS_ONLY },
|
||||
{ "@mozilla.org/chrome/chrome-native-theme;1", &kNS_THEMERENDERER_CID },
|
||||
#ifdef NS_PRINTING
|
||||
{ "@mozilla.org/gfx/printsettings-service;1", &kNS_PRINTSETTINGSSERVICE_CID },
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
[scriptable, uuid(D6F13AF4-8ACA-4A10-8687-3F99C3692AC0)]
|
||||
[scriptable, uuid(826e80c8-d70f-42e2-8aa9-82c05f2a370a)]
|
||||
interface nsIScreen : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -29,6 +29,12 @@ interface nsIScreen : nsISupports
|
||||
const unsigned long ROTATION_180_DEG = 2;
|
||||
const unsigned long ROTATION_270_DEG = 3;
|
||||
|
||||
/**
|
||||
* A unique identifier for this device, useful for requerying
|
||||
* for it via nsIScreenManager.
|
||||
*/
|
||||
readonly attribute unsigned long id;
|
||||
|
||||
/**
|
||||
* These report screen dimensions in (screen-specific) device pixels
|
||||
*/
|
||||
|
@ -7,7 +7,7 @@
|
||||
#include "nsISupports.idl"
|
||||
#include "nsIScreen.idl"
|
||||
|
||||
[scriptable, uuid(1C195990-FF9E-412B-AFE7-67D1C660BB27)]
|
||||
[scriptable, uuid(e8a96e60-6b61-4a14-bacc-53891604b502)]
|
||||
interface nsIScreenManager : nsISupports
|
||||
{
|
||||
//
|
||||
@ -17,11 +17,18 @@ interface nsIScreenManager : nsISupports
|
||||
// The coordinates are in pixels (not twips) and in screen coordinates.
|
||||
//
|
||||
nsIScreen screenForRect ( in long left, in long top, in long width, in long height ) ;
|
||||
|
||||
|
||||
//
|
||||
// Returns the screen corresponding to the id. If no such screen exists,
|
||||
// this will throw NS_ERROR_FAILURE. The id is a unique numeric value
|
||||
// assigned to each screen, and is an attribute available on the nsIScreen
|
||||
// interface.
|
||||
nsIScreen screenForId ( in unsigned long id ) ;
|
||||
|
||||
// The screen with the menubar/taskbar. This shouldn't be needed very
|
||||
// often.
|
||||
readonly attribute nsIScreen primaryScreen;
|
||||
|
||||
|
||||
// Holds the number of screens that are available
|
||||
readonly attribute unsigned long numberOfScreens;
|
||||
|
||||
|
@ -59,6 +59,23 @@ nsScreenManagerWin :: CreateNewScreenObject ( HMONITOR inScreen )
|
||||
return retScreen;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScreenManagerWin::ScreenForId(uint32_t aId, nsIScreen **outScreen)
|
||||
{
|
||||
*outScreen = nullptr;
|
||||
|
||||
for (unsigned i = 0; i < mScreenList.Length(); ++i) {
|
||||
ScreenListItem& curr = mScreenList[i];
|
||||
uint32_t id;
|
||||
nsresult rv = curr.mScreen->GetId(&id);
|
||||
if (NS_SUCCEEDED(rv) && id == aId) {
|
||||
NS_IF_ADDREF(*outScreen = curr.mScreen.get());
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
//
|
||||
// ScreenForRect
|
||||
|
@ -8,9 +8,11 @@
|
||||
#include "gfxWindowsPlatform.h"
|
||||
#include "nsIWidget.h"
|
||||
|
||||
static uint32_t sScreenId;
|
||||
|
||||
nsScreenWin :: nsScreenWin ( HMONITOR inScreen )
|
||||
: mScreen(inScreen)
|
||||
, mId(++sScreenId)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
HDC hDCScreen = ::GetDC(nullptr);
|
||||
@ -31,6 +33,14 @@ nsScreenWin :: ~nsScreenWin()
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScreenWin::GetId(uint32_t *outId)
|
||||
{
|
||||
*outId = mId;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScreenWin :: GetRect(int32_t *outLeft, int32_t *outTop, int32_t *outWidth, int32_t *outHeight)
|
||||
{
|
||||
|
@ -17,6 +17,8 @@ public:
|
||||
nsScreenWin ( HMONITOR inScreen );
|
||||
~nsScreenWin();
|
||||
|
||||
NS_IMETHOD GetId(uint32_t* aId);
|
||||
|
||||
// These methods return the size in device (physical) pixels
|
||||
NS_IMETHOD GetRect(int32_t* aLeft, int32_t* aTop, int32_t* aWidth, int32_t* aHeight);
|
||||
NS_IMETHOD GetAvailRect(int32_t* aLeft, int32_t* aTop, int32_t* aWidth, int32_t* aHeight);
|
||||
@ -34,6 +36,7 @@ public:
|
||||
private:
|
||||
|
||||
HMONITOR mScreen;
|
||||
uint32_t mId;
|
||||
};
|
||||
|
||||
#endif // nsScreenWin_h___
|
||||
|
@ -221,7 +221,8 @@ static const mozilla::Module::CIDEntry kWidgetCIDs[] = {
|
||||
{ &kNS_FILEPICKER_CID, false, nullptr, FilePickerConstructor, Module::MAIN_PROCESS_ONLY },
|
||||
{ &kNS_COLORPICKER_CID, false, nullptr, ColorPickerConstructor, Module::MAIN_PROCESS_ONLY },
|
||||
{ &kNS_APPSHELL_CID, false, nullptr, nsAppShellConstructor },
|
||||
{ &kNS_SCREENMANAGER_CID, false, nullptr, nsScreenManagerWinConstructor },
|
||||
{ &kNS_SCREENMANAGER_CID, false, nullptr, nsScreenManagerWinConstructor,
|
||||
Module::MAIN_PROCESS_ONLY },
|
||||
{ &kNS_GFXINFO_CID, false, nullptr, GfxInfoConstructor },
|
||||
{ &kNS_THEMERENDERER_CID, false, nullptr, NS_NewNativeTheme },
|
||||
{ &kNS_IDLE_SERVICE_CID, false, nullptr, nsIdleServiceWinConstructor },
|
||||
@ -259,7 +260,7 @@ static const mozilla::Module::ContractIDEntry kWidgetContracts[] = {
|
||||
{ "@mozilla.org/filepicker;1", &kNS_FILEPICKER_CID, Module::MAIN_PROCESS_ONLY },
|
||||
{ "@mozilla.org/colorpicker;1", &kNS_COLORPICKER_CID, Module::MAIN_PROCESS_ONLY },
|
||||
{ "@mozilla.org/widget/appshell/win;1", &kNS_APPSHELL_CID },
|
||||
{ "@mozilla.org/gfx/screenmanager;1", &kNS_SCREENMANAGER_CID },
|
||||
{ "@mozilla.org/gfx/screenmanager;1", &kNS_SCREENMANAGER_CID, Module::MAIN_PROCESS_ONLY },
|
||||
{ "@mozilla.org/gfx/info;1", &kNS_GFXINFO_CID },
|
||||
{ "@mozilla.org/chrome/chrome-native-theme;1", &kNS_THEMERENDERER_CID },
|
||||
{ "@mozilla.org/widget/idleservice;1", &kNS_IDLE_SERVICE_CID },
|
||||
|
@ -803,6 +803,13 @@ ScreenConfig()
|
||||
return config;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PuppetScreen::GetId(uint32_t *outId)
|
||||
{
|
||||
*outId = 1;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PuppetScreen::GetRect(int32_t *outLeft, int32_t *outTop,
|
||||
int32_t *outWidth, int32_t *outHeight)
|
||||
@ -822,7 +829,6 @@ PuppetScreen::GetAvailRect(int32_t *outLeft, int32_t *outTop,
|
||||
return GetRect(outLeft, outTop, outWidth, outHeight);
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
PuppetScreen::GetPixelDepth(int32_t *aPixelDepth)
|
||||
{
|
||||
@ -862,6 +868,14 @@ PuppetScreenManager::~PuppetScreenManager()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PuppetScreenManager::ScreenForId(uint32_t aId,
|
||||
nsIScreen** outScreen)
|
||||
{
|
||||
NS_IF_ADDREF(*outScreen = mOneScreen.get());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PuppetScreenManager::GetPrimaryScreen(nsIScreen** outScreen)
|
||||
{
|
||||
|
@ -305,6 +305,7 @@ public:
|
||||
PuppetScreen(void* nativeScreen);
|
||||
~PuppetScreen();
|
||||
|
||||
NS_IMETHOD GetId(uint32_t* aId) MOZ_OVERRIDE;
|
||||
NS_IMETHOD GetRect(int32_t* aLeft, int32_t* aTop, int32_t* aWidth, int32_t* aHeight) MOZ_OVERRIDE;
|
||||
NS_IMETHOD GetAvailRect(int32_t* aLeft, int32_t* aTop, int32_t* aWidth, int32_t* aHeight) MOZ_OVERRIDE;
|
||||
NS_IMETHOD GetPixelDepth(int32_t* aPixelDepth) MOZ_OVERRIDE;
|
||||
|
157
widget/xpwidgets/ScreenProxy.cpp
Normal file
157
widget/xpwidgets/ScreenProxy.cpp
Normal file
@ -0,0 +1,157 @@
|
||||
/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 2; -*- */
|
||||
/* vim: set sw=4 ts=8 et tw=80 : */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/unused.h"
|
||||
#include "nsIAppShell.h"
|
||||
#include "nsScreenManagerProxy.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsWidgetsCID.h"
|
||||
#include "ScreenProxy.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace widget {
|
||||
|
||||
using namespace mozilla::dom;
|
||||
|
||||
static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
|
||||
|
||||
ScreenProxy::ScreenProxy(nsScreenManagerProxy* aScreenManager, ScreenDetails aDetails)
|
||||
: mScreenManager(aScreenManager)
|
||||
, mCacheValid(false)
|
||||
, mCacheWillInvalidate(false)
|
||||
{
|
||||
PopulateByDetails(aDetails);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ScreenProxy::GetId(uint32_t *outId)
|
||||
{
|
||||
*outId = mId;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ScreenProxy::GetRect(int32_t *outLeft,
|
||||
int32_t *outTop,
|
||||
int32_t *outWidth,
|
||||
int32_t *outHeight)
|
||||
{
|
||||
if (!EnsureCacheIsValid()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
*outLeft = mRect.x;
|
||||
*outTop = mRect.y;
|
||||
*outWidth = mRect.width;
|
||||
*outHeight = mRect.height;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ScreenProxy::GetAvailRect(int32_t *outLeft,
|
||||
int32_t *outTop,
|
||||
int32_t *outWidth,
|
||||
int32_t *outHeight)
|
||||
{
|
||||
if (!EnsureCacheIsValid()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
*outLeft = mAvailRect.x;
|
||||
*outTop = mAvailRect.y;
|
||||
*outWidth = mAvailRect.width;
|
||||
*outHeight = mAvailRect.height;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ScreenProxy::GetPixelDepth(int32_t *aPixelDepth)
|
||||
{
|
||||
if (!EnsureCacheIsValid()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
*aPixelDepth = mPixelDepth;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ScreenProxy::GetColorDepth(int32_t *aColorDepth)
|
||||
{
|
||||
if (!EnsureCacheIsValid()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
*aColorDepth = mColorDepth;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
ScreenProxy::PopulateByDetails(ScreenDetails aDetails)
|
||||
{
|
||||
mId = aDetails.id();
|
||||
mRect = nsIntRect(aDetails.rect());
|
||||
mAvailRect = nsIntRect(aDetails.availRect());
|
||||
mPixelDepth = aDetails.pixelDepth();
|
||||
mColorDepth = aDetails.colorDepth();
|
||||
mContentsScaleFactor = aDetails.contentsScaleFactor();
|
||||
}
|
||||
|
||||
bool
|
||||
ScreenProxy::EnsureCacheIsValid()
|
||||
{
|
||||
if (mCacheValid) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool success = false;
|
||||
// Kick off a synchronous IPC call to the parent to get the
|
||||
// most up-to-date information.
|
||||
ScreenDetails details;
|
||||
unused << mScreenManager->SendScreenRefresh(mId, &details, &success);
|
||||
if (!success) {
|
||||
NS_WARNING("Updating a ScreenProxy in the child process failed on parent side.");
|
||||
return false;
|
||||
}
|
||||
|
||||
PopulateByDetails(details);
|
||||
mCacheValid = true;
|
||||
|
||||
InvalidateCacheOnNextTick();
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
ScreenProxy::InvalidateCacheOnNextTick()
|
||||
{
|
||||
if (mCacheWillInvalidate) {
|
||||
return;
|
||||
}
|
||||
|
||||
mCacheWillInvalidate = true;
|
||||
|
||||
nsCOMPtr<nsIAppShell> appShell = do_GetService(kAppShellCID);
|
||||
if (appShell) {
|
||||
appShell->RunInStableState(
|
||||
NS_NewRunnableMethod(this, &ScreenProxy::InvalidateCache)
|
||||
);
|
||||
} else {
|
||||
// It's pretty bad news if we can't get the appshell. In that case,
|
||||
// let's just invalidate the cache right away.
|
||||
InvalidateCache();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ScreenProxy::InvalidateCache()
|
||||
{
|
||||
mCacheValid = false;
|
||||
mCacheWillInvalidate = false;
|
||||
}
|
||||
|
||||
} // namespace widget
|
||||
} // namespace mozilla
|
||||
|
60
widget/xpwidgets/ScreenProxy.h
Normal file
60
widget/xpwidgets/ScreenProxy.h
Normal file
@ -0,0 +1,60 @@
|
||||
/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 2; -*- */
|
||||
/* vim: set sw=4 ts=8 et tw=80 : */
|
||||
/* 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/. */
|
||||
|
||||
#ifndef mozilla_widget_ScreenProxy_h
|
||||
#define mozilla_widget_ScreenProxy_h
|
||||
|
||||
#include "nsBaseScreen.h"
|
||||
#include "mozilla/dom/PScreenManagerChild.h"
|
||||
#include "mozilla/dom/TabChild.h"
|
||||
|
||||
class nsScreenManagerProxy;
|
||||
|
||||
namespace mozilla {
|
||||
namespace widget {
|
||||
|
||||
class ScreenProxy : public nsBaseScreen
|
||||
{
|
||||
public:
|
||||
ScreenProxy(nsScreenManagerProxy* aScreenManager,
|
||||
mozilla::dom::ScreenDetails aDetails);
|
||||
~ScreenProxy() {};
|
||||
|
||||
NS_IMETHOD GetId(uint32_t* aId) MOZ_OVERRIDE;
|
||||
|
||||
NS_IMETHOD GetRect(int32_t* aLeft,
|
||||
int32_t* aTop,
|
||||
int32_t* aWidth,
|
||||
int32_t* aHeight) MOZ_OVERRIDE;
|
||||
NS_IMETHOD GetAvailRect(int32_t* aLeft,
|
||||
int32_t* aTop,
|
||||
int32_t* aWidth,
|
||||
int32_t* aHeight) MOZ_OVERRIDE;
|
||||
NS_IMETHOD GetPixelDepth(int32_t* aPixelDepth) MOZ_OVERRIDE;
|
||||
NS_IMETHOD GetColorDepth(int32_t* aColorDepth) MOZ_OVERRIDE;
|
||||
|
||||
private:
|
||||
|
||||
void PopulateByDetails(mozilla::dom::ScreenDetails aDetails);
|
||||
bool EnsureCacheIsValid();
|
||||
void InvalidateCacheOnNextTick();
|
||||
void InvalidateCache();
|
||||
|
||||
double mContentsScaleFactor;
|
||||
nsRefPtr<nsScreenManagerProxy> mScreenManager;
|
||||
uint32_t mId;
|
||||
int32_t mPixelDepth;
|
||||
int32_t mColorDepth;
|
||||
nsIntRect mRect;
|
||||
nsIntRect mAvailRect;
|
||||
bool mCacheValid;
|
||||
bool mCacheWillInvalidate;
|
||||
};
|
||||
|
||||
} // namespace widget
|
||||
} // namespace mozilla
|
||||
#endif
|
||||
|
@ -34,9 +34,11 @@ UNIFIED_SOURCES += [
|
||||
'nsPrintOptionsImpl.cpp',
|
||||
'nsPrintSession.cpp',
|
||||
'nsPrintSettingsImpl.cpp',
|
||||
'nsScreenManagerProxy.cpp',
|
||||
'nsTransferable.cpp',
|
||||
'nsXPLookAndFeel.cpp',
|
||||
'PuppetWidget.cpp',
|
||||
'ScreenProxy.cpp',
|
||||
'WidgetUtils.cpp',
|
||||
]
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "nsClipboardProxy.h"
|
||||
#include "nsColorPickerProxy.h"
|
||||
#include "nsFilePickerProxy.h"
|
||||
#include "nsScreenManagerProxy.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
@ -18,10 +19,12 @@ using namespace mozilla;
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsClipboardProxy)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsColorPickerProxy)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsFilePickerProxy)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsScreenManagerProxy)
|
||||
|
||||
NS_DEFINE_NAMED_CID(NS_CLIPBOARD_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_COLORPICKER_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_FILEPICKER_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_SCREENMANAGER_CID);
|
||||
|
||||
static const mozilla::Module::CIDEntry kWidgetCIDs[] = {
|
||||
{ &kNS_CLIPBOARD_CID, false, nullptr, nsClipboardProxyConstructor,
|
||||
@ -30,6 +33,8 @@ static const mozilla::Module::CIDEntry kWidgetCIDs[] = {
|
||||
Module::CONTENT_PROCESS_ONLY },
|
||||
{ &kNS_FILEPICKER_CID, false, nullptr, nsFilePickerProxyConstructor,
|
||||
Module::CONTENT_PROCESS_ONLY },
|
||||
{ &kNS_SCREENMANAGER_CID, false, nullptr, nsScreenManagerProxyConstructor,
|
||||
Module::CONTENT_PROCESS_ONLY },
|
||||
{ nullptr }
|
||||
};
|
||||
|
||||
@ -37,6 +42,7 @@ static const mozilla::Module::ContractIDEntry kWidgetContracts[] = {
|
||||
{ "@mozilla.org/widget/clipboard;1", &kNS_CLIPBOARD_CID, Module::CONTENT_PROCESS_ONLY },
|
||||
{ "@mozilla.org/colorpicker;1", &kNS_COLORPICKER_CID, Module::CONTENT_PROCESS_ONLY },
|
||||
{ "@mozilla.org/filepicker;1", &kNS_FILEPICKER_CID, Module::CONTENT_PROCESS_ONLY },
|
||||
{ "@mozilla.org/gfx/screenmanager;1", &kNS_SCREENMANAGER_CID, Module::CONTENT_PROCESS_ONLY },
|
||||
{ nullptr }
|
||||
};
|
||||
|
||||
|
226
widget/xpwidgets/nsScreenManagerProxy.cpp
Normal file
226
widget/xpwidgets/nsScreenManagerProxy.cpp
Normal file
@ -0,0 +1,226 @@
|
||||
/* -*- 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/. */
|
||||
|
||||
#include "mozilla/unused.h"
|
||||
#include "mozilla/dom/ContentChild.h"
|
||||
#include "nsScreenManagerProxy.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsIAppShell.h"
|
||||
#include "nsIScreen.h"
|
||||
#include "nsIScreenManager.h"
|
||||
#include "nsWidgetsCID.h"
|
||||
|
||||
static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
using namespace mozilla::widget;
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsScreenManagerProxy, nsIScreenManager)
|
||||
|
||||
nsScreenManagerProxy::nsScreenManagerProxy()
|
||||
: mNumberOfScreens(-1)
|
||||
, mSystemDefaultScale(1.0)
|
||||
, mCacheValid(true)
|
||||
, mCacheWillInvalidate(false)
|
||||
{
|
||||
bool success = false;
|
||||
unused << ContentChild::GetSingleton()->SendPScreenManagerConstructor(
|
||||
this,
|
||||
&mNumberOfScreens,
|
||||
&mSystemDefaultScale,
|
||||
&success);
|
||||
|
||||
if (!success) {
|
||||
// We're in bad shape. We'll return the default values, but we'll basically
|
||||
// be lying.
|
||||
NS_WARNING("Setting up communications with the parent nsIScreenManager failed.");
|
||||
}
|
||||
|
||||
InvalidateCacheOnNextTick();
|
||||
|
||||
// nsScreenManagerProxy is a service, which will always have a reference
|
||||
// held to it by the Component Manager once the service is requested.
|
||||
// However, nsScreenManagerProxy also implements PScreenManagerChild, and
|
||||
// that means that the manager of the PScreenManager protocol (PContent
|
||||
// in this case) needs to know how to deallocate this actor. We AddRef here
|
||||
// so that in the event that PContent tries to deallocate us either before
|
||||
// or after process shutdown, we don't try to do a double-free.
|
||||
AddRef();
|
||||
}
|
||||
|
||||
/**
|
||||
* nsIScreenManager
|
||||
**/
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScreenManagerProxy::GetPrimaryScreen(nsIScreen** outScreen)
|
||||
{
|
||||
InvalidateCacheOnNextTick();
|
||||
|
||||
if (!mPrimaryScreen) {
|
||||
ScreenDetails details;
|
||||
bool success = false;
|
||||
unused << SendGetPrimaryScreen(&details, &success);
|
||||
if (!success) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mPrimaryScreen = new ScreenProxy(this, details);
|
||||
}
|
||||
NS_ADDREF(*outScreen = mPrimaryScreen);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScreenManagerProxy::ScreenForId(uint32_t aId, nsIScreen** outScreen)
|
||||
{
|
||||
// At this time, there's no need for child processes to query for
|
||||
// screens by ID.
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScreenManagerProxy::ScreenForRect(int32_t inLeft,
|
||||
int32_t inTop,
|
||||
int32_t inWidth,
|
||||
int32_t inHeight,
|
||||
nsIScreen** outScreen)
|
||||
{
|
||||
bool success = false;
|
||||
ScreenDetails details;
|
||||
unused << SendScreenForRect(inLeft, inTop, inWidth, inHeight, &details, &success);
|
||||
if (!success) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsRefPtr<ScreenProxy> screen = new ScreenProxy(this, details);
|
||||
NS_ADDREF(*outScreen = screen);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScreenManagerProxy::ScreenForNativeWidget(void* aWidget,
|
||||
nsIScreen** outScreen)
|
||||
{
|
||||
// Because ScreenForNativeWidget can be called numerous times
|
||||
// indirectly from content via the DOM Screen API, we cache the
|
||||
// results for this tick of the event loop.
|
||||
TabChild* tabChild = static_cast<TabChild*>(aWidget);
|
||||
|
||||
// Enumerate the cached screen array, looking for one that has
|
||||
// the TabChild that we're looking for...
|
||||
for (uint32_t i = 0; i < mScreenCache.Length(); ++i) {
|
||||
ScreenCacheEntry& curr = mScreenCache[i];
|
||||
if (curr.mTabChild == aWidget) {
|
||||
NS_ADDREF(*outScreen = static_cast<nsIScreen*>(curr.mScreenProxy));
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// Never cached this screen, so we have to ask the parent process
|
||||
// for it.
|
||||
bool success = false;
|
||||
ScreenDetails details;
|
||||
unused << SendScreenForBrowser(tabChild, &details, &success);
|
||||
if (!success) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
ScreenCacheEntry newEntry;
|
||||
nsRefPtr<ScreenProxy> screen = new ScreenProxy(this, details);
|
||||
|
||||
newEntry.mScreenProxy = screen;
|
||||
newEntry.mTabChild = tabChild;
|
||||
|
||||
mScreenCache.AppendElement(newEntry);
|
||||
|
||||
NS_ADDREF(*outScreen = screen);
|
||||
|
||||
InvalidateCacheOnNextTick();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScreenManagerProxy::GetNumberOfScreens(uint32_t* aNumberOfScreens)
|
||||
{
|
||||
if (!EnsureCacheIsValid()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
*aNumberOfScreens = mNumberOfScreens;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScreenManagerProxy::GetSystemDefaultScale(float *aSystemDefaultScale)
|
||||
{
|
||||
if (!EnsureCacheIsValid()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
*aSystemDefaultScale = mSystemDefaultScale;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
nsScreenManagerProxy::EnsureCacheIsValid()
|
||||
{
|
||||
if (mCacheValid) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool success = false;
|
||||
// Kick off a synchronous IPC call to the parent to get the
|
||||
// most up-to-date information.
|
||||
unused << SendRefresh(&mNumberOfScreens, &mSystemDefaultScale, &success);
|
||||
if (!success) {
|
||||
NS_WARNING("Refreshing nsScreenManagerProxy failed in the parent process.");
|
||||
return false;
|
||||
}
|
||||
|
||||
mCacheValid = true;
|
||||
|
||||
InvalidateCacheOnNextTick();
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
nsScreenManagerProxy::InvalidateCacheOnNextTick()
|
||||
{
|
||||
if (mCacheWillInvalidate) {
|
||||
return;
|
||||
}
|
||||
|
||||
mCacheWillInvalidate = true;
|
||||
|
||||
nsCOMPtr<nsIAppShell> appShell = do_GetService(kAppShellCID);
|
||||
if (appShell) {
|
||||
appShell->RunInStableState(
|
||||
NS_NewRunnableMethod(this, &nsScreenManagerProxy::InvalidateCache)
|
||||
);
|
||||
} else {
|
||||
// It's pretty bad news if we can't get the appshell. In that case,
|
||||
// let's just invalidate the cache right away.
|
||||
InvalidateCache();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsScreenManagerProxy::InvalidateCache()
|
||||
{
|
||||
mCacheValid = false;
|
||||
mCacheWillInvalidate = false;
|
||||
|
||||
if (mPrimaryScreen) {
|
||||
mPrimaryScreen = nullptr;
|
||||
}
|
||||
for (int32_t i = mScreenCache.Length() - 1; i >= 0; --i) {
|
||||
mScreenCache.RemoveElementAt(i);
|
||||
}
|
||||
}
|
||||
|
67
widget/xpwidgets/nsScreenManagerProxy.h
Normal file
67
widget/xpwidgets/nsScreenManagerProxy.h
Normal file
@ -0,0 +1,67 @@
|
||||
/* -*- Mode: C++; tab-width: 2; 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/. */
|
||||
|
||||
#ifndef nsScreenManagerProxy_h
|
||||
#define nsScreenManagerProxy_h
|
||||
|
||||
#include "nsIScreenManager.h"
|
||||
#include "mozilla/dom/PScreenManagerChild.h"
|
||||
#include "mozilla/dom/TabChild.h"
|
||||
#include "ScreenProxy.h"
|
||||
|
||||
/**
|
||||
* The nsScreenManagerProxy is used by the content process to get
|
||||
* information about system screens. It uses the PScreenManager protocol
|
||||
* to communicate with a PScreenManagerParent to get this information,
|
||||
* and also caches the information it gets back.
|
||||
*
|
||||
* We cache both the system screen information that nsIScreenManagers
|
||||
* provide, as well as the nsIScreens that callers can query for.
|
||||
*
|
||||
* Both of these caches are invalidated on the next tick of the event
|
||||
* loop.
|
||||
*/
|
||||
class nsScreenManagerProxy MOZ_FINAL : public nsIScreenManager,
|
||||
public mozilla::dom::PScreenManagerChild
|
||||
{
|
||||
public:
|
||||
nsScreenManagerProxy();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSISCREENMANAGER
|
||||
|
||||
private:
|
||||
~nsScreenManagerProxy() {};
|
||||
|
||||
bool EnsureCacheIsValid();
|
||||
void InvalidateCacheOnNextTick();
|
||||
void InvalidateCache();
|
||||
|
||||
uint32_t mNumberOfScreens;
|
||||
float mSystemDefaultScale;
|
||||
bool mCacheValid;
|
||||
bool mCacheWillInvalidate;
|
||||
|
||||
nsRefPtr<mozilla::widget::ScreenProxy> mPrimaryScreen;
|
||||
|
||||
// nsScreenManagerProxy caches the results to repeated calls to
|
||||
// ScreenForNativeWidget, which can be triggered indirectly by
|
||||
// web content using the DOM Screen API. This allows us to bypass
|
||||
// a lot of IPC traffic.
|
||||
//
|
||||
// The cache stores ScreenProxy's mapped to the TabChild that
|
||||
// asked for the ScreenForNativeWidget was called with via
|
||||
// ScreenCacheEntry's. The cache is cleared on the next tick of
|
||||
// the event loop.
|
||||
struct ScreenCacheEntry
|
||||
{
|
||||
nsRefPtr<mozilla::widget::ScreenProxy> mScreenProxy;
|
||||
nsRefPtr<mozilla::dom::TabChild> mTabChild;
|
||||
};
|
||||
|
||||
nsTArray<ScreenCacheEntry> mScreenCache;
|
||||
};
|
||||
|
||||
#endif // nsScreenManagerProxy_h
|
Loading…
Reference in New Issue
Block a user