Merge mozilla-central to autoland

This commit is contained in:
Sebastian Hengst 2019-01-23 11:31:44 +02:00
commit 2ecf173b14
8722 changed files with 16302 additions and 19207 deletions

View File

@ -20,20 +20,12 @@
using namespace mozilla;
using namespace mozilla::a11y;
AccessibleWrap::
AccessibleWrap(nsIContent* aContent, DocAccessible* aDoc) :
Accessible(aContent, aDoc), mNativeObject(nil),
mNativeInited(false)
{
}
AccessibleWrap::AccessibleWrap(nsIContent* aContent, DocAccessible* aDoc)
: Accessible(aContent, aDoc), mNativeObject(nil), mNativeInited(false) {}
AccessibleWrap::~AccessibleWrap()
{
}
AccessibleWrap::~AccessibleWrap() {}
mozAccessible*
AccessibleWrap::GetNativeObject()
{
mozAccessible* AccessibleWrap::GetNativeObject() {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
if (!mNativeInited && !mNativeObject && !IsDefunct() && !AncestorIsFlat()) {
@ -48,30 +40,22 @@ AccessibleWrap::GetNativeObject()
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
}
void
AccessibleWrap::GetNativeInterface(void** aOutInterface)
{
void AccessibleWrap::GetNativeInterface(void** aOutInterface) {
*aOutInterface = static_cast<void*>(GetNativeObject());
}
// overridden in subclasses to create the right kind of object. by default we create a generic
// 'mozAccessible' node.
Class
AccessibleWrap::GetNativeType ()
{
Class AccessibleWrap::GetNativeType() {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
if (IsXULTabpanels())
return [mozPaneAccessible class];
if (IsXULTabpanels()) return [mozPaneAccessible class];
if (IsTable())
return [mozTableAccessible class];
if (IsTable()) return [mozTableAccessible class];
if (IsTableRow())
return [mozTableRowAccessible class];
if (IsTableRow()) return [mozTableRowAccessible class];
if (IsTableCell())
return [mozTableCellAccessible class];
if (IsTableCell()) return [mozTableCellAccessible class];
return GetTypeFromRole(Role());
@ -81,9 +65,7 @@ AccessibleWrap::GetNativeType ()
// this method is very important. it is fired when an accessible object "dies". after this point
// the object might still be around (because some 3rd party still has a ref to it), but it is
// in fact 'dead'.
void
AccessibleWrap::Shutdown ()
{
void AccessibleWrap::Shutdown() {
// this ensure we will not try to re-create the native object.
mNativeInited = true;
@ -97,9 +79,7 @@ AccessibleWrap::Shutdown ()
Accessible::Shutdown();
}
nsresult
AccessibleWrap::HandleAccEvent(AccEvent* aEvent)
{
nsresult AccessibleWrap::HandleAccEvent(AccEvent* aEvent) {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
nsresult rv = Accessible::HandleAccEvent(aEvent);
@ -124,10 +104,9 @@ AccessibleWrap::HandleAccEvent(AccEvent* aEvent)
Accessible* accessible = aEvent->GetAccessible();
NS_ENSURE_STATE(accessible);
mozAccessible *nativeAcc = nil;
mozAccessible* nativeAcc = nil;
accessible->GetNativeInterface((void**)&nativeAcc);
if (!nativeAcc)
return NS_ERROR_FAILURE;
if (!nativeAcc) return NS_ERROR_FAILURE;
FireNativeEvent(nativeAcc, eventType);
@ -136,23 +115,17 @@ AccessibleWrap::HandleAccEvent(AccEvent* aEvent)
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
}
bool
AccessibleWrap::InsertChildAt(uint32_t aIdx, Accessible* aAccessible)
{
bool AccessibleWrap::InsertChildAt(uint32_t aIdx, Accessible* aAccessible) {
bool inserted = Accessible::InsertChildAt(aIdx, aAccessible);
if (inserted && mNativeObject)
[mNativeObject appendChild:aAccessible];
if (inserted && mNativeObject) [mNativeObject appendChild:aAccessible];
return inserted;
}
bool
AccessibleWrap::RemoveChild(Accessible* aAccessible)
{
bool AccessibleWrap::RemoveChild(Accessible* aAccessible) {
bool removed = Accessible::RemoveChild(aAccessible);
if (removed && mNativeObject)
[mNativeObject invalidateChildren];
if (removed && mNativeObject) [mNativeObject invalidateChildren];
return removed;
}
@ -160,9 +133,7 @@ AccessibleWrap::RemoveChild(Accessible* aAccessible)
////////////////////////////////////////////////////////////////////////////////
// AccessibleWrap protected
bool
AccessibleWrap::AncestorIsFlat()
{
bool AccessibleWrap::AncestorIsFlat() {
// We don't create a native object if we're child of a "flat" accessible;
// for example, on OS X buttons shouldn't have any children, because that
// makes the OS confused.
@ -173,8 +144,7 @@ AccessibleWrap::AncestorIsFlat()
Accessible* parent = Parent();
while (parent) {
if (nsAccUtils::MustPrune(parent))
return true;
if (nsAccUtils::MustPrune(parent)) return true;
parent = parent->Parent();
}
@ -182,9 +152,7 @@ AccessibleWrap::AncestorIsFlat()
return false;
}
void
a11y::FireNativeEvent(mozAccessible* aNativeAcc, uint32_t aEventType)
{
void a11y::FireNativeEvent(mozAccessible* aNativeAcc, uint32_t aEventType) {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
// Under headless mode we don't have access to a native window, so we skip
@ -213,18 +181,15 @@ a11y::FireNativeEvent(mozAccessible* aNativeAcc, uint32_t aEventType)
NS_OBJC_END_TRY_ABORT_BLOCK;
}
Class
a11y::GetTypeFromRole(roles::Role aRole)
{
Class a11y::GetTypeFromRole(roles::Role aRole) {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
switch (aRole) {
case roles::COMBOBOX:
case roles::PUSHBUTTON:
case roles::SPLITBUTTON:
case roles::TOGGLE_BUTTON:
{
return [mozButtonAccessible class];
case roles::TOGGLE_BUTTON: {
return [mozButtonAccessible class];
}
case roles::PAGETAB:

View File

@ -9,13 +9,7 @@
using namespace mozilla::a11y;
DocAccessibleWrap::
DocAccessibleWrap(mozilla::dom::Document* aDocument, nsIPresShell* aPresShell) :
DocAccessible(aDocument, aPresShell)
{
}
DocAccessibleWrap::~DocAccessibleWrap()
{
}
DocAccessibleWrap::DocAccessibleWrap(mozilla::dom::Document* aDocument, nsIPresShell* aPresShell)
: DocAccessible(aDocument, aPresShell) {}
DocAccessibleWrap::~DocAccessibleWrap() {}

View File

@ -18,9 +18,7 @@ namespace utils {
* Get a localized string from the a11y string bundle.
* Return nil if not found.
*/
NSString*
LocalizedString(const nsString& aString)
{
NSString* LocalizedString(const nsString& aString) {
nsString text;
Accessible::TranslateString(aString, text);

View File

@ -19,26 +19,17 @@ namespace a11y {
// Mac a11y whitelisting
static bool sA11yShouldBeEnabled = false;
bool
ShouldA11yBeEnabled()
{
bool ShouldA11yBeEnabled() {
EPlatformDisabledState disabledState = PlatformDisabledState();
return (disabledState == ePlatformIsForceEnabled) || ((disabledState == ePlatformIsEnabled) && sA11yShouldBeEnabled);
return (disabledState == ePlatformIsForceEnabled) ||
((disabledState == ePlatformIsEnabled) && sA11yShouldBeEnabled);
}
void
PlatformInit()
{
}
void PlatformInit() {}
void
PlatformShutdown()
{
}
void PlatformShutdown() {}
void
ProxyCreated(ProxyAccessible* aProxy, uint32_t)
{
void ProxyCreated(ProxyAccessible* aProxy, uint32_t) {
// Pass in dummy state for now as retrieving proxy state requires IPC.
// Note that we can use ProxyAccessible::IsTable* functions here because they
// do not use IPC calls but that might change after bug 1210477.
@ -76,9 +67,7 @@ ProxyCreated(ProxyAccessible* aProxy, uint32_t)
}
}
void
ProxyDestroyed(ProxyAccessible* aProxy)
{
void ProxyDestroyed(ProxyAccessible* aProxy) {
mozAccessible* nativeParent = nil;
if (aProxy->IsDoc() && aProxy->AsDoc()->IsTopLevel()) {
// Invalidate native parent in parent process's children on proxy destruction
@ -108,9 +97,7 @@ ProxyDestroyed(ProxyAccessible* aProxy)
}
}
void
ProxyEvent(ProxyAccessible* aProxy, uint32_t aEventType)
{
void ProxyEvent(ProxyAccessible* aProxy, uint32_t aEventType) {
// ignore everything but focus-changed, value-changed, caret and selection
// events for now.
if (aEventType != nsIAccessibleEvent::EVENT_FOCUS &&
@ -121,50 +108,33 @@ ProxyEvent(ProxyAccessible* aProxy, uint32_t aEventType)
return;
mozAccessible* wrapper = GetNativeFromProxy(aProxy);
if (wrapper)
FireNativeEvent(wrapper, aEventType);
if (wrapper) FireNativeEvent(wrapper, aEventType);
}
void
ProxyStateChangeEvent(ProxyAccessible* aProxy, uint64_t, bool)
{
void ProxyStateChangeEvent(ProxyAccessible* aProxy, uint64_t, bool) {
// mac doesn't care about state change events
}
void
ProxyCaretMoveEvent(ProxyAccessible* aTarget, int32_t aOffset)
{
void ProxyCaretMoveEvent(ProxyAccessible* aTarget, int32_t aOffset) {
mozAccessible* wrapper = GetNativeFromProxy(aTarget);
if (wrapper)
[wrapper selectedTextDidChange];
if (wrapper) [wrapper selectedTextDidChange];
}
void
ProxyTextChangeEvent(ProxyAccessible*, const nsString&, int32_t, uint32_t,
bool, bool)
{
}
void ProxyTextChangeEvent(ProxyAccessible*, const nsString&, int32_t, uint32_t, bool, bool) {}
void
ProxyShowHideEvent(ProxyAccessible*, ProxyAccessible*, bool, bool)
{
}
void ProxyShowHideEvent(ProxyAccessible*, ProxyAccessible*, bool, bool) {}
void
ProxySelectionEvent(ProxyAccessible*, ProxyAccessible*, uint32_t)
{
}
} // namespace a11y
} // namespace mozilla
void ProxySelectionEvent(ProxyAccessible*, ProxyAccessible*, uint32_t) {}
} // namespace a11y
} // namespace mozilla
@interface GeckoNSApplication(a11y)
-(void)accessibilitySetValue:(id)value forAttribute:(NSString*)attribute;
@interface GeckoNSApplication (a11y)
- (void)accessibilitySetValue:(id)value forAttribute:(NSString*)attribute;
@end
@implementation GeckoNSApplication(a11y)
@implementation GeckoNSApplication (a11y)
-(void)accessibilitySetValue:(id)value forAttribute:(NSString*)attribute
{
- (void)accessibilitySetValue:(id)value forAttribute:(NSString*)attribute {
if ([attribute isEqualToString:@"AXEnhancedUserInterface"])
mozilla::a11y::sA11yShouldBeEnabled = ([value intValue] == 1);
@ -172,4 +142,3 @@ ProxySelectionEvent(ProxyAccessible*, ProxyAccessible*, uint32_t)
}
@end

View File

@ -15,19 +15,12 @@
using namespace mozilla::a11y;
RootAccessibleWrap::
RootAccessibleWrap(mozilla::dom::Document* aDocument, nsIPresShell* aPresShell) :
RootAccessible(aDocument, aPresShell)
{
}
RootAccessibleWrap::RootAccessibleWrap(mozilla::dom::Document* aDocument, nsIPresShell* aPresShell)
: RootAccessible(aDocument, aPresShell) {}
RootAccessibleWrap::~RootAccessibleWrap()
{
}
RootAccessibleWrap::~RootAccessibleWrap() {}
Class
RootAccessibleWrap::GetNativeType()
{
Class RootAccessibleWrap::GetNativeType() {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
return [mozRootAccessible class];
@ -35,18 +28,16 @@ RootAccessibleWrap::GetNativeType()
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
}
void
RootAccessibleWrap::GetNativeWidget(void** aOutView)
{
nsIFrame *frame = GetFrame();
void RootAccessibleWrap::GetNativeWidget(void** aOutView) {
nsIFrame* frame = GetFrame();
if (frame) {
nsView *view = frame->GetView();
nsView* view = frame->GetView();
if (view) {
nsIWidget *widget = view->GetWidget();
nsIWidget* widget = view->GetWidget();
if (widget) {
*aOutView = (void**)widget->GetNativeData (NS_NATIVE_WIDGET);
NS_ASSERTION (*aOutView,
"Couldn't get the native NSView parent we need to connect the accessibility hierarchy!");
*aOutView = (void**)widget->GetNativeData(NS_NATIVE_WIDGET);
NS_ASSERTION(*aOutView, "Couldn't get the native NSView parent we need to connect the "
"accessibility hierarchy!");
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -24,49 +24,45 @@ enum CheckboxValue {
@implementation mozButtonAccessible
- (NSArray*)accessibilityAttributeNames
{
- (NSArray*)accessibilityAttributeNames {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
static NSArray *attributes = nil;
static NSArray* attributes = nil;
if (!attributes) {
attributes = [[NSArray alloc] initWithObjects:NSAccessibilityParentAttribute, // required
NSAccessibilityRoleAttribute, // required
NSAccessibilityRoleDescriptionAttribute,
NSAccessibilityPositionAttribute, // required
NSAccessibilitySizeAttribute, // required
NSAccessibilityWindowAttribute, // required
NSAccessibilityPositionAttribute, // required
NSAccessibilityTopLevelUIElementAttribute, // required
NSAccessibilityHelpAttribute,
NSAccessibilityEnabledAttribute, // required
NSAccessibilityFocusedAttribute, // required
NSAccessibilityTitleAttribute, // required
NSAccessibilityChildrenAttribute,
NSAccessibilityDescriptionAttribute,
attributes = [[NSArray alloc]
initWithObjects:NSAccessibilityParentAttribute, // required
NSAccessibilityRoleAttribute, // required
NSAccessibilityRoleDescriptionAttribute,
NSAccessibilityPositionAttribute, // required
NSAccessibilitySizeAttribute, // required
NSAccessibilityWindowAttribute, // required
NSAccessibilityPositionAttribute, // required
NSAccessibilityTopLevelUIElementAttribute, // required
NSAccessibilityHelpAttribute,
NSAccessibilityEnabledAttribute, // required
NSAccessibilityFocusedAttribute, // required
NSAccessibilityTitleAttribute, // required
NSAccessibilityChildrenAttribute, NSAccessibilityDescriptionAttribute,
#if DEBUG
@"AXMozDescription",
@"AXMozDescription",
#endif
nil];
nil];
}
return attributes;
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
}
- (id)accessibilityAttributeValue:(NSString *)attribute
{
- (id)accessibilityAttributeValue:(NSString*)attribute {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
if ([attribute isEqualToString:NSAccessibilityChildrenAttribute]) {
if ([self hasPopup])
return [self children];
if ([self hasPopup]) return [self children];
return nil;
}
if ([attribute isEqualToString:NSAccessibilityRoleDescriptionAttribute]) {
if ([self isTab])
return utils::LocalizedString(NS_LITERAL_STRING("tab"));
if ([self isTab]) return utils::LocalizedString(NS_LITERAL_STRING("tab"));
return NSAccessibilityRoleDescription([self role], nil);
}
@ -76,20 +72,17 @@ enum CheckboxValue {
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
}
- (BOOL)accessibilityIsIgnored
{
- (BOOL)accessibilityIsIgnored {
return ![self getGeckoAccessible] && ![self getProxyAccessible];
}
- (NSArray*)accessibilityActionNames
{
- (NSArray*)accessibilityActionNames {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
if ([self isEnabled]) {
if ([self hasPopup])
return [NSArray arrayWithObjects:NSAccessibilityPressAction,
NSAccessibilityShowMenuAction,
nil];
return
[NSArray arrayWithObjects:NSAccessibilityPressAction, NSAccessibilityShowMenuAction, nil];
return [NSArray arrayWithObject:NSAccessibilityPressAction];
}
return nil;
@ -97,20 +90,17 @@ enum CheckboxValue {
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
}
- (NSString*)accessibilityActionDescription:(NSString*)action
{
- (NSString*)accessibilityActionDescription:(NSString*)action {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
if ([action isEqualToString:NSAccessibilityPressAction]) {
if ([self isTab])
return utils::LocalizedString(NS_LITERAL_STRING("switch"));
if ([self isTab]) return utils::LocalizedString(NS_LITERAL_STRING("switch"));
return @"press button"; // XXX: localize this later?
return @"press button"; // XXX: localize this later?
}
if ([self hasPopup]) {
if ([action isEqualToString:NSAccessibilityShowMenuAction])
return @"show menu";
if ([action isEqualToString:NSAccessibilityShowMenuAction]) return @"show menu";
}
return nil;
@ -118,8 +108,7 @@ enum CheckboxValue {
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
}
- (void)accessibilityPerformAction:(NSString*)action
{
- (void)accessibilityPerformAction:(NSString*)action {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
if ([self isEnabled] && [action isEqualToString:NSAccessibilityPressAction]) {
@ -132,8 +121,7 @@ enum CheckboxValue {
NS_OBJC_END_TRY_ABORT_BLOCK;
}
- (void)click
{
- (void)click {
// both buttons and checkboxes have only one action. we should really stop using arbitrary
// arrays with actions, and define constants for these actions.
if (AccessibleWrap* accWrap = [self getGeckoAccessible])
@ -142,19 +130,15 @@ enum CheckboxValue {
proxy->DoAction(0);
}
- (BOOL)isTab
{
if (AccessibleWrap* accWrap = [self getGeckoAccessible])
return accWrap->Role() == roles::PAGETAB;
- (BOOL)isTab {
if (AccessibleWrap* accWrap = [self getGeckoAccessible]) return accWrap->Role() == roles::PAGETAB;
if (ProxyAccessible* proxy = [self getProxyAccessible])
return proxy->Role() == roles::PAGETAB;
if (ProxyAccessible* proxy = [self getProxyAccessible]) return proxy->Role() == roles::PAGETAB;
return false;
}
- (BOOL)hasPopup
{
- (BOOL)hasPopup {
if (AccessibleWrap* accWrap = [self getGeckoAccessible])
return accWrap->NativeState() & states::HASPOPUP;
@ -168,15 +152,13 @@ enum CheckboxValue {
@implementation mozCheckboxAccessible
- (NSString*)accessibilityActionDescription:(NSString*)action
{
- (NSString*)accessibilityActionDescription:(NSString*)action {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
if ([action isEqualToString:NSAccessibilityPressAction]) {
if ([self isChecked] != kUnchecked)
return @"uncheck checkbox"; // XXX: localize this later?
if ([self isChecked] != kUnchecked) return @"uncheck checkbox"; // XXX: localize this later?
return @"check checkbox"; // XXX: localize this later?
return @"check checkbox"; // XXX: localize this later?
}
return nil;
@ -184,8 +166,7 @@ enum CheckboxValue {
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
}
- (int)isChecked
{
- (int)isChecked {
uint64_t state = 0;
if (AccessibleWrap* accWrap = [self getGeckoAccessible])
state = accWrap->NativeState();
@ -200,8 +181,7 @@ enum CheckboxValue {
return kUnchecked;
}
- (id)value
{
- (id)value {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
return [NSNumber numberWithInt:[self isChecked]];
@ -213,15 +193,13 @@ enum CheckboxValue {
@implementation mozTabsAccessible
- (void)dealloc
{
- (void)dealloc {
[mTabs release];
[super dealloc];
}
- (NSArray*)accessibilityAttributeNames
{
- (NSArray*)accessibilityAttributeNames {
// standard attributes that are shared and supported by root accessible (AXMain) elements.
static NSMutableArray* attributes = nil;
@ -234,12 +212,9 @@ enum CheckboxValue {
return attributes;
}
- (id)accessibilityAttributeValue:(NSString *)attribute
{
if ([attribute isEqualToString:NSAccessibilityContentsAttribute])
return [super children];
if ([attribute isEqualToString:NSAccessibilityTabsAttribute])
return [self tabs];
- (id)accessibilityAttributeValue:(NSString*)attribute {
if ([attribute isEqualToString:NSAccessibilityContentsAttribute]) return [super children];
if ([attribute isEqualToString:NSAccessibilityTabsAttribute]) return [self tabs];
return [super accessibilityAttributeValue:attribute];
}
@ -247,8 +222,7 @@ enum CheckboxValue {
/**
* Returns the selected tab (the mozAccessible)
*/
- (id)value
{
- (id)value {
mozAccessible* nativeAcc = nil;
if (AccessibleWrap* accWrap = [self getGeckoAccessible]) {
if (Accessible* accTab = accWrap->GetSelectedItem(0)) {
@ -266,10 +240,8 @@ enum CheckboxValue {
/**
* Return the mozAccessibles that are the tabs.
*/
- (id)tabs
{
if (mTabs)
return mTabs;
- (id)tabs {
if (mTabs) return mTabs;
NSArray* children = [self children];
NSEnumerator* enumerator = [children objectEnumerator];
@ -277,14 +249,12 @@ enum CheckboxValue {
id obj;
while ((obj = [enumerator nextObject]))
if ([obj isTab])
[mTabs addObject:obj];
if ([obj isTab]) [mTabs addObject:obj];
return mTabs;
}
- (void)invalidateChildren
{
- (void)invalidateChildren {
[super invalidateChildren];
[mTabs release];
@ -295,18 +265,15 @@ enum CheckboxValue {
@implementation mozPaneAccessible
- (NSUInteger)accessibilityArrayAttributeCount:(NSString*)attribute
{
- (NSUInteger)accessibilityArrayAttributeCount:(NSString*)attribute {
AccessibleWrap* accWrap = [self getGeckoAccessible];
ProxyAccessible* proxy = [self getProxyAccessible];
if (!accWrap && !proxy)
return 0;
if (!accWrap && !proxy) return 0;
// By default this calls -[[mozAccessible children] count].
// Since we don't cache mChildren. This is faster.
if ([attribute isEqualToString:NSAccessibilityChildrenAttribute]) {
if (accWrap)
return accWrap->ChildCount() ? 1 : 0;
if (accWrap) return accWrap->ChildCount() ? 1 : 0;
return proxy->ChildrenCount() ? 1 : 0;
}
@ -314,24 +281,21 @@ enum CheckboxValue {
return [super accessibilityArrayAttributeCount:attribute];
}
- (NSArray*)children
{
if (![self getGeckoAccessible])
return nil;
- (NSArray*)children {
if (![self getGeckoAccessible]) return nil;
nsDeckFrame* deckFrame = do_QueryFrame([self getGeckoAccessible]->GetFrame());
nsDeckFrame* deckFrame = do_QueryFrame([self getGeckoAccessible] -> GetFrame());
nsIFrame* selectedFrame = deckFrame ? deckFrame->GetSelectedBox() : nullptr;
Accessible* selectedAcc = nullptr;
if (selectedFrame) {
nsINode* node = selectedFrame->GetContent();
selectedAcc = [self getGeckoAccessible]->Document()->GetAccessible(node);
selectedAcc = [self getGeckoAccessible] -> Document() -> GetAccessible(node);
}
if (selectedAcc) {
mozAccessible *curNative = GetNativeFromGeckoAccessible(selectedAcc);
if (curNative)
return [NSArray arrayWithObjects:GetObjectOrRepresentedView(curNative), nil];
mozAccessible* curNative = GetNativeFromGeckoAccessible(selectedAcc);
if (curNative) return [NSArray arrayWithObjects:GetObjectOrRepresentedView(curNative), nil];
}
return nil;

View File

@ -14,13 +14,10 @@
using namespace mozilla::a11y;
static id <mozAccessible, mozView>
getNativeViewFromRootAccessible(Accessible* aAccessible)
{
RootAccessibleWrap* root =
static_cast<RootAccessibleWrap*>(aAccessible->AsRoot());
id <mozAccessible, mozView> nativeView = nil;
root->GetNativeWidget ((void**)&nativeView);
static id<mozAccessible, mozView> getNativeViewFromRootAccessible(Accessible* aAccessible) {
RootAccessibleWrap* root = static_cast<RootAccessibleWrap*>(aAccessible->AsRoot());
id<mozAccessible, mozView> nativeView = nil;
root->GetNativeWidget((void**)&nativeView);
return nativeView;
}
@ -28,13 +25,11 @@ getNativeViewFromRootAccessible(Accessible* aAccessible)
@implementation mozRootAccessible
- (NSArray*)accessibilityAttributeNames
{
- (NSArray*)accessibilityAttributeNames {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
// if we're expired, we don't support any attributes.
if (![self getGeckoAccessible])
return [NSArray array];
if (![self getGeckoAccessible]) return [NSArray array];
// standard attributes that are shared and supported by root accessible (AXMain) elements.
static NSMutableArray* attributes = nil;
@ -50,8 +45,7 @@ getNativeViewFromRootAccessible(Accessible* aAccessible)
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
}
- (id)accessibilityAttributeValue:(NSString *)attribute
{
- (id)accessibilityAttributeValue:(NSString*)attribute {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
if ([attribute isEqualToString:NSAccessibilityMainAttribute])
@ -64,14 +58,11 @@ getNativeViewFromRootAccessible(Accessible* aAccessible)
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
}
// return the AXParent that our parallell NSView tells us about.
- (id)parent
{
- (id)parent {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
if (!mParallelView)
mParallelView = (id<mozView, mozAccessible>)[self representedView];
if (!mParallelView) mParallelView = (id<mozView, mozAccessible>)[self representedView];
if (mParallelView)
return [mParallelView accessibilityAttributeValue:NSAccessibilityParentAttribute];
@ -82,20 +73,17 @@ getNativeViewFromRootAccessible(Accessible* aAccessible)
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
}
- (BOOL)hasRepresentedView
{
- (BOOL)hasRepresentedView {
return YES;
}
// this will return our parallell NSView. see mozDocAccessible.h
- (id)representedView
{
- (id)representedView {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
if (mParallelView)
return (id)mParallelView;
if (mParallelView) return (id)mParallelView;
mParallelView = getNativeViewFromRootAccessible ([self getGeckoAccessible]);
mParallelView = getNativeViewFromRootAccessible([self getGeckoAccessible]);
NSAssert(mParallelView, @"can't return root accessible's native parallel view.");
return mParallelView;
@ -103,8 +91,7 @@ getNativeViewFromRootAccessible(Accessible* aAccessible)
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
}
- (BOOL)isRoot
{
- (BOOL)isRoot {
return YES;
}

View File

@ -14,8 +14,7 @@
@implementation mozHeadingAccessible
- (NSString*)title
{
- (NSString*)title {
nsAutoString title;
if (AccessibleWrap* accWrap = [self getGeckoAccessible]) {
mozilla::ErrorResult rv;
@ -29,8 +28,7 @@
return nsCocoaUtils::ToNSString(title);
}
- (id)value
{
- (id)value {
uint32_t level = 0;
if (AccessibleWrap* accWrap = [self getGeckoAccessible]) {
level = accWrap->GetLevelInternal();
@ -44,16 +42,14 @@
@end
@interface mozLinkAccessible ()
-(NSURL*)url;
- (NSURL*)url;
@end
@implementation mozLinkAccessible
- (NSArray*)accessibilityAttributeNames
{
- (NSArray*)accessibilityAttributeNames {
// if we're expired, we don't support any attributes.
if (![self getGeckoAccessible] && ![self getProxyAccessible])
return [NSArray array];
if (![self getGeckoAccessible] && ![self getProxyAccessible]) return [NSArray array];
static NSMutableArray* attributes = nil;
@ -65,32 +61,26 @@
return attributes;
}
- (id)accessibilityAttributeValue:(NSString *)attribute
{
if ([attribute isEqualToString:NSAccessibilityURLAttribute])
return [self url];
- (id)accessibilityAttributeValue:(NSString*)attribute {
if ([attribute isEqualToString:NSAccessibilityURLAttribute]) return [self url];
return [super accessibilityAttributeValue:attribute];
}
- (NSArray*)accessibilityActionNames
{
// if we're expired, we don't support any attributes.
if (![self getGeckoAccessible] && ![self getProxyAccessible])
return [NSArray array];
- (NSArray*)accessibilityActionNames {
// if we're expired, we don't support any attributes.
if (![self getGeckoAccessible] && ![self getProxyAccessible]) return [NSArray array];
static NSArray* actionNames = nil;
if (!actionNames) {
actionNames = [[NSArray alloc] initWithObjects:NSAccessibilityPressAction,
nil];
actionNames = [[NSArray alloc] initWithObjects:NSAccessibilityPressAction, nil];
}
return actionNames;
}
- (void)accessibilityPerformAction:(NSString*)action
{
- (void)accessibilityPerformAction:(NSString*)action {
AccessibleWrap* accWrap = [self getGeckoAccessible];
ProxyAccessible* proxy = [self getProxyAccessible];
if (!accWrap && !proxy) {
@ -107,21 +97,17 @@
}
[super accessibilityPerformAction:action];
}
- (NSString*)customDescription
{
- (NSString*)customDescription {
return @"";
}
- (NSString*)value
{
- (NSString*)value {
return @"";
}
- (NSURL*)url
{
- (NSURL*)url {
nsAutoString value;
if (AccessibleWrap* accWrap = [self getGeckoAccessible]) {
accWrap->Value(value);
@ -130,8 +116,7 @@
}
NSString* urlString = value.IsEmpty() ? nil : nsCocoaUtils::ToNSString(value);
if (!urlString)
return nil;
if (!urlString) return nil;
return [NSURL URLWithString:urlString];
}

View File

@ -33,15 +33,13 @@
return false;
}
- (NSString*)role
{
- (NSString*)role {
return [self isLayoutTablePart] ? NSAccessibilityGroupRole : [super role];
}
@end
@implementation mozTableAccessible
- (NSArray*)additionalAccessibilityAttributeNames
{
- (NSArray*)additionalAccessibilityAttributeNames {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
NSArray* additionalAttributes = [super additionalAccessibilityAttributeNames];
@ -64,12 +62,10 @@
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
}
- (id)accessibilityAttributeValue:(NSString*)attribute
{
- (id)accessibilityAttributeValue:(NSString*)attribute {
if (AccessibleWrap* accWrap = [self getGeckoAccessible]) {
TableAccessible* table = accWrap->AsTable();
if ([attribute isEqualToString:NSAccessibilityRowCountAttribute])
return @(table->RowCount());
if ([attribute isEqualToString:NSAccessibilityRowCountAttribute]) return @(table->RowCount());
if ([attribute isEqualToString:NSAccessibilityColumnCountAttribute])
return @(table->ColCount());
if ([attribute isEqualToString:NSAccessibilityRowsAttribute]) {
@ -78,10 +74,8 @@
uint32_t totalCount = accWrap->ChildCount();
for (uint32_t i = 0; i < totalCount; i++) {
if (accWrap->GetChildAt(i)->IsTableRow()) {
mozAccessible* curNative =
GetNativeFromGeckoAccessible(accWrap->GetChildAt(i));
if (curNative)
[nativeArray addObject:GetObjectOrRepresentedView(curNative)];
mozAccessible* curNative = GetNativeFromGeckoAccessible(accWrap->GetChildAt(i));
if (curNative) [nativeArray addObject:GetObjectOrRepresentedView(curNative)];
}
}
return nativeArray;
@ -97,10 +91,8 @@
uint32_t totalCount = proxy->ChildrenCount();
for (uint32_t i = 0; i < totalCount; i++) {
if (proxy->ChildAt(i)->IsTableRow()) {
mozAccessible* curNative =
GetNativeFromProxy(proxy->ChildAt(i));
if (curNative)
[nativeArray addObject:GetObjectOrRepresentedView(curNative)];
mozAccessible* curNative = GetNativeFromProxy(proxy->ChildAt(i));
if (curNative) [nativeArray addObject:GetObjectOrRepresentedView(curNative)];
}
}
return nativeArray;
@ -112,8 +104,7 @@
@end
@implementation mozTableRowAccessible
- (NSArray*)additionalAccessibilityAttributeNames
{
- (NSArray*)additionalAccessibilityAttributeNames {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
NSArray* additionalAttributes = [super additionalAccessibilityAttributeNames];
@ -134,8 +125,7 @@
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
}
- (id)accessibilityAttributeValue:(NSString*)attribute
{
- (id)accessibilityAttributeValue:(NSString*)attribute {
if (AccessibleWrap* accWrap = [self getGeckoAccessible]) {
if ([attribute isEqualToString:NSAccessibilityIndexAttribute]) {
// Count the number of rows before that one to obtain the row index.
@ -171,8 +161,7 @@
@end
@implementation mozTableCellAccessible
- (NSArray*)additionalAccessibilityAttributeNames
{
- (NSArray*)additionalAccessibilityAttributeNames {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
NSArray* additionalAttributes = [super additionalAccessibilityAttributeNames];
@ -196,16 +185,13 @@
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
}
- (id)accessibilityAttributeValue:(NSString*)attribute
{
- (id)accessibilityAttributeValue:(NSString*)attribute {
if (AccessibleWrap* accWrap = [self getGeckoAccessible]) {
TableCellAccessible* cell = accWrap->AsTableCell();
if ([attribute isEqualToString:NSAccessibilityRowIndexRangeAttribute])
return [NSValue valueWithRange:NSMakeRange(cell->RowIdx(),
cell->RowExtent())];
return [NSValue valueWithRange:NSMakeRange(cell->RowIdx(), cell->RowExtent())];
if ([attribute isEqualToString:NSAccessibilityColumnIndexRangeAttribute])
return [NSValue valueWithRange:NSMakeRange(cell->ColIdx(),
cell->ColExtent())];
return [NSValue valueWithRange:NSMakeRange(cell->ColIdx(), cell->ColExtent())];
if ([attribute isEqualToString:NSAccessibilityRowHeaderUIElementsAttribute]) {
AutoTArray<Accessible*, 10> headerCells;
cell->RowHeaderCells(&headerCells);
@ -218,11 +204,9 @@
}
} else if (ProxyAccessible* proxy = [self getProxyAccessible]) {
if ([attribute isEqualToString:NSAccessibilityRowIndexRangeAttribute])
return [NSValue valueWithRange:NSMakeRange(proxy->RowIdx(),
proxy->RowExtent())];
return [NSValue valueWithRange:NSMakeRange(proxy->RowIdx(), proxy->RowExtent())];
if ([attribute isEqualToString:NSAccessibilityColumnIndexRangeAttribute])
return [NSValue valueWithRange:NSMakeRange(proxy->ColIdx(),
proxy->ColExtent())];
return [NSValue valueWithRange:NSMakeRange(proxy->ColIdx(), proxy->ColExtent())];
if ([attribute isEqualToString:NSAccessibilityRowHeaderUIElementsAttribute]) {
nsTArray<ProxyAccessible*> headerCells;
proxy->RowHeaderCells(&headerCells);

View File

@ -14,9 +14,7 @@
using namespace mozilla::a11y;
inline bool
ToNSRange(id aValue, NSRange* aRange)
{
inline bool ToNSRange(id aValue, NSRange* aRange) {
MOZ_ASSERT(aRange, "aRange is nil");
if ([aValue isKindOfClass:[NSValue class]] &&
@ -28,9 +26,7 @@ ToNSRange(id aValue, NSRange* aRange)
return false;
}
inline NSString*
ToNSString(id aValue)
{
inline NSString* ToNSString(id aValue) {
if ([aValue isKindOfClass:[NSString class]]) {
return aValue;
}
@ -53,28 +49,23 @@ ToNSString(id aValue)
@implementation mozTextAccessible
- (BOOL)accessibilityIsIgnored
{
- (BOOL)accessibilityIsIgnored {
return ![self getGeckoAccessible] && ![self getProxyAccessible];
}
- (NSArray*)accessibilityAttributeNames
{
- (NSArray*)accessibilityAttributeNames {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
static NSMutableArray* supportedAttributes = nil;
if (!supportedAttributes) {
// text-specific attributes to supplement the standard one
supportedAttributes = [[NSMutableArray alloc] initWithObjects:
NSAccessibilitySelectedTextAttribute, // required
NSAccessibilitySelectedTextRangeAttribute, // required
NSAccessibilityNumberOfCharactersAttribute, // required
NSAccessibilityVisibleCharacterRangeAttribute, // required
NSAccessibilityInsertionPointLineNumberAttribute,
@"AXRequired",
@"AXInvalid",
nil
];
supportedAttributes = [[NSMutableArray alloc]
initWithObjects:NSAccessibilitySelectedTextAttribute, // required
NSAccessibilitySelectedTextRangeAttribute, // required
NSAccessibilityNumberOfCharactersAttribute, // required
NSAccessibilityVisibleCharacterRangeAttribute, // required
NSAccessibilityInsertionPointLineNumberAttribute, @"AXRequired",
@"AXInvalid", nil];
[supportedAttributes addObjectsFromArray:[super accessibilityAttributeNames]];
}
return supportedAttributes;
@ -82,8 +73,7 @@ ToNSString(id aValue)
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
}
- (id)accessibilityAttributeValue:(NSString*)attribute
{
- (id)accessibilityAttributeValue:(NSString*)attribute {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
if ([attribute isEqualToString:NSAccessibilityNumberOfCharactersAttribute])
@ -95,11 +85,9 @@ ToNSString(id aValue)
if ([attribute isEqualToString:NSAccessibilitySelectedTextRangeAttribute])
return [self selectedTextRange];
if ([attribute isEqualToString:NSAccessibilitySelectedTextAttribute])
return [self selectedText];
if ([attribute isEqualToString:NSAccessibilitySelectedTextAttribute]) return [self selectedText];
if ([attribute isEqualToString:NSAccessibilityTitleAttribute])
return @"";
if ([attribute isEqualToString:NSAccessibilityTitleAttribute]) return @"";
if ([attribute isEqualToString:NSAccessibilityValueAttribute]) {
// Apple's SpeechSynthesisServer expects AXValue to return an AXStaticText
@ -141,37 +129,33 @@ ToNSString(id aValue)
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
}
- (NSArray*)accessibilityParameterizedAttributeNames
{
- (NSArray*)accessibilityParameterizedAttributeNames {
static NSArray* supportedParametrizedAttributes = nil;
// text specific parametrized attributes
if (!supportedParametrizedAttributes) {
supportedParametrizedAttributes = [[NSArray alloc] initWithObjects:
NSAccessibilityStringForRangeParameterizedAttribute,
NSAccessibilityLineForIndexParameterizedAttribute,
NSAccessibilityRangeForLineParameterizedAttribute,
NSAccessibilityAttributedStringForRangeParameterizedAttribute,
NSAccessibilityBoundsForRangeParameterizedAttribute,
supportedParametrizedAttributes = [[NSArray alloc]
initWithObjects:NSAccessibilityStringForRangeParameterizedAttribute,
NSAccessibilityLineForIndexParameterizedAttribute,
NSAccessibilityRangeForLineParameterizedAttribute,
NSAccessibilityAttributedStringForRangeParameterizedAttribute,
NSAccessibilityBoundsForRangeParameterizedAttribute,
#if DEBUG
NSAccessibilityRangeForPositionParameterizedAttribute,
NSAccessibilityRangeForIndexParameterizedAttribute,
NSAccessibilityRTFForRangeParameterizedAttribute,
NSAccessibilityStyleRangeForIndexParameterizedAttribute,
NSAccessibilityRangeForPositionParameterizedAttribute,
NSAccessibilityRangeForIndexParameterizedAttribute,
NSAccessibilityRTFForRangeParameterizedAttribute,
NSAccessibilityStyleRangeForIndexParameterizedAttribute,
#endif
nil
];
nil];
}
return supportedParametrizedAttributes;
}
- (id)accessibilityAttributeValue:(NSString*)attribute forParameter:(id)parameter
{
- (id)accessibilityAttributeValue:(NSString*)attribute forParameter:(id)parameter {
AccessibleWrap* accWrap = [self getGeckoAccessible];
ProxyAccessible* proxy = [self getProxyAccessible];
HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
if (!textAcc && !proxy)
return nil;
HyperTextAccessible* textAcc = accWrap ? accWrap->AsHyperText() : nullptr;
if (!textAcc && !proxy) return nil;
if ([attribute isEqualToString:NSAccessibilityStringForRangeParameterizedAttribute]) {
NSRange range;
@ -220,11 +204,9 @@ ToNSString(id aValue)
int32_t end = start + range.length;
DesktopIntRect bounds;
if (textAcc) {
bounds =
DesktopIntRect::FromUnknownRect(textAcc->TextBounds(start, end));
bounds = DesktopIntRect::FromUnknownRect(textAcc->TextBounds(start, end));
} else if (proxy) {
bounds =
DesktopIntRect::FromUnknownRect(proxy->TextBounds(start, end));
bounds = DesktopIntRect::FromUnknownRect(proxy->TextBounds(start, end));
}
return [NSValue valueWithRect:nsCocoaUtils::GeckoRectToCocoaRect(bounds)];
@ -237,12 +219,10 @@ ToNSString(id aValue)
return nil;
}
- (BOOL)accessibilityIsAttributeSettable:(NSString*)attribute
{
- (BOOL)accessibilityIsAttributeSettable:(NSString*)attribute {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
if ([attribute isEqualToString:NSAccessibilityValueAttribute])
return ![self isReadOnly];
if ([attribute isEqualToString:NSAccessibilityValueAttribute]) return ![self isReadOnly];
if ([attribute isEqualToString:NSAccessibilitySelectedTextAttribute] ||
[attribute isEqualToString:NSAccessibilitySelectedTextRangeAttribute] ||
@ -254,16 +234,14 @@ ToNSString(id aValue)
NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(NO);
}
- (void)accessibilitySetValue:(id)value forAttribute:(NSString *)attribute
{
- (void)accessibilitySetValue:(id)value forAttribute:(NSString*)attribute {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
AccessibleWrap* accWrap = [self getGeckoAccessible];
ProxyAccessible* proxy = [self getProxyAccessible];
HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
if (!textAcc && !proxy)
return;
HyperTextAccessible* textAcc = accWrap ? accWrap->AsHyperText() : nullptr;
if (!textAcc && !proxy) return;
if ([attribute isEqualToString:NSAccessibilityValueAttribute]) {
[self setText:ToNSString(value)];
@ -273,8 +251,7 @@ ToNSString(id aValue)
if ([attribute isEqualToString:NSAccessibilitySelectedTextAttribute]) {
NSString* stringValue = ToNSString(value);
if (!stringValue)
return;
if (!stringValue) return;
int32_t start = 0, end = 0;
nsString text;
@ -294,23 +271,19 @@ ToNSString(id aValue)
if ([attribute isEqualToString:NSAccessibilitySelectedTextRangeAttribute]) {
NSRange range;
if (!ToNSRange(value, &range))
return;
if (!ToNSRange(value, &range)) return;
if (textAcc) {
textAcc->SetSelectionBoundsAt(0, range.location,
range.location + range.length);
textAcc->SetSelectionBoundsAt(0, range.location, range.location + range.length);
} else if (proxy) {
proxy->SetSelectionBoundsAt(0, range.location,
range.location + range.length);
proxy->SetSelectionBoundsAt(0, range.location, range.location + range.length);
}
return;
}
if ([attribute isEqualToString:NSAccessibilityVisibleCharacterRangeAttribute]) {
NSRange range;
if (!ToNSRange(value, &range))
return;
if (!ToNSRange(value, &range)) return;
if (textAcc) {
textAcc->ScrollSubstringTo(range.location, range.location + range.length,
@ -327,27 +300,22 @@ ToNSString(id aValue)
NS_OBJC_END_TRY_ABORT_BLOCK;
}
- (NSString*)subrole
{
if(mRole == roles::PASSWORD_TEXT)
return NSAccessibilitySecureTextFieldSubrole;
- (NSString*)subrole {
if (mRole == roles::PASSWORD_TEXT) return NSAccessibilitySecureTextFieldSubrole;
return nil;
}
#pragma mark -
- (BOOL)isReadOnly
{
- (BOOL)isReadOnly {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
if ([[self role] isEqualToString:NSAccessibilityStaticTextRole])
return YES;
if ([[self role] isEqualToString:NSAccessibilityStaticTextRole]) return YES;
AccessibleWrap* accWrap = [self getGeckoAccessible];
HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
if (textAcc)
return (accWrap->State() & states::READONLY) == 0;
HyperTextAccessible* textAcc = accWrap ? accWrap->AsHyperText() : nullptr;
if (textAcc) return (accWrap->State() & states::READONLY) == 0;
if (ProxyAccessible* proxy = [self getProxyAccessible])
return (proxy->State() & states::READONLY) == 0;
@ -357,10 +325,9 @@ ToNSString(id aValue)
NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(NO);
}
- (NSNumber*)caretLineNumber
{
- (NSNumber*)caretLineNumber {
AccessibleWrap* accWrap = [self getGeckoAccessible];
HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
HyperTextAccessible* textAcc = accWrap ? accWrap->AsHyperText() : nullptr;
int32_t lineNumber = -1;
if (textAcc) {
@ -372,12 +339,11 @@ ToNSString(id aValue)
return (lineNumber >= 0) ? [NSNumber numberWithInt:lineNumber] : nil;
}
- (void)setText:(NSString*)aNewString
{
- (void)setText:(NSString*)aNewString {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
AccessibleWrap* accWrap = [self getGeckoAccessible];
HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
HyperTextAccessible* textAcc = accWrap ? accWrap->AsHyperText() : nullptr;
nsString text;
nsCocoaUtils::GetStringForNSString(aNewString, text);
@ -390,17 +356,14 @@ ToNSString(id aValue)
NS_OBJC_END_TRY_ABORT_BLOCK;
}
- (NSString*)text
{
- (NSString*)text {
AccessibleWrap* accWrap = [self getGeckoAccessible];
ProxyAccessible* proxy = [self getProxyAccessible];
HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
if (!textAcc && !proxy)
return nil;
HyperTextAccessible* textAcc = accWrap ? accWrap->AsHyperText() : nullptr;
if (!textAcc && !proxy) return nil;
// A password text field returns an empty value
if (mRole == roles::PASSWORD_TEXT)
return @"";
if (mRole == roles::PASSWORD_TEXT) return @"";
nsAutoString text;
if (textAcc) {
@ -412,30 +375,26 @@ ToNSString(id aValue)
return nsCocoaUtils::ToNSString(text);
}
- (long)textLength
{
- (long)textLength {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
AccessibleWrap* accWrap = [self getGeckoAccessible];
ProxyAccessible* proxy = [self getProxyAccessible];
HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
if (!textAcc && !proxy)
return 0;
HyperTextAccessible* textAcc = accWrap ? accWrap->AsHyperText() : nullptr;
if (!textAcc && !proxy) return 0;
return textAcc ? textAcc->CharacterCount() : proxy->CharacterCount();
NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(0);
}
- (long)selectedTextLength
{
- (long)selectedTextLength {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
AccessibleWrap* accWrap = [self getGeckoAccessible];
ProxyAccessible* proxy = [self getProxyAccessible];
HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
if (!textAcc && !proxy)
return 0;
HyperTextAccessible* textAcc = accWrap ? accWrap->AsHyperText() : nullptr;
if (!textAcc && !proxy) return 0;
int32_t start = 0, end = 0;
if (textAcc) {
@ -449,15 +408,13 @@ ToNSString(id aValue)
NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(0);
}
- (NSString*)selectedText
{
- (NSString*)selectedText {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
AccessibleWrap* accWrap = [self getGeckoAccessible];
ProxyAccessible* proxy = [self getProxyAccessible];
HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
if (!textAcc && !proxy)
return nil;
HyperTextAccessible* textAcc = accWrap ? accWrap->AsHyperText() : nullptr;
if (!textAcc && !proxy) return nil;
int32_t start = 0, end = 0;
nsAutoString selText;
@ -475,13 +432,12 @@ ToNSString(id aValue)
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
}
- (NSValue*)selectedTextRange
{
- (NSValue*)selectedTextRange {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
AccessibleWrap* accWrap = [self getGeckoAccessible];
ProxyAccessible* proxy = [self getProxyAccessible];
HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
HyperTextAccessible* textAcc = accWrap ? accWrap->AsHyperText() : nullptr;
int32_t start = 0;
int32_t end = 0;
@ -514,23 +470,19 @@ ToNSString(id aValue)
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
}
- (NSValue*)visibleCharacterRange
{
- (NSValue*)visibleCharacterRange {
// XXX this won't work with Textarea and such as we actually don't give
// the visible character range.
AccessibleWrap* accWrap = [self getGeckoAccessible];
ProxyAccessible* proxy = [self getProxyAccessible];
HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
if (!textAcc && !proxy)
return 0;
HyperTextAccessible* textAcc = accWrap ? accWrap->AsHyperText() : nullptr;
if (!textAcc && !proxy) return 0;
return [NSValue valueWithRange:
NSMakeRange(0, textAcc ?
textAcc->CharacterCount() : proxy->CharacterCount())];
return [NSValue
valueWithRange:NSMakeRange(0, textAcc ? textAcc->CharacterCount() : proxy->CharacterCount())];
}
- (void)valueDidChange
{
- (void)valueDidChange {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
NSAccessibilityPostNotification(GetObjectOrRepresentedView(self),
@ -539,29 +491,24 @@ ToNSString(id aValue)
NS_OBJC_END_TRY_ABORT_BLOCK;
}
- (void)selectedTextDidChange
{
- (void)selectedTextDidChange {
NSAccessibilityPostNotification(GetObjectOrRepresentedView(self),
NSAccessibilitySelectedTextChangedNotification);
}
- (NSString*)stringFromRange:(NSRange*)range
{
- (NSString*)stringFromRange:(NSRange*)range {
MOZ_ASSERT(range, "no range");
AccessibleWrap* accWrap = [self getGeckoAccessible];
ProxyAccessible* proxy = [self getProxyAccessible];
HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
if (!textAcc && !proxy)
return nil;
HyperTextAccessible* textAcc = accWrap ? accWrap->AsHyperText() : nullptr;
if (!textAcc && !proxy) return nil;
nsAutoString text;
if (textAcc) {
textAcc->TextSubstring(range->location,
range->location + range->length, text);
textAcc->TextSubstring(range->location, range->location + range->length, text);
} else if (proxy) {
proxy->TextSubstring(range->location,
range->location + range->length, text);
proxy->TextSubstring(range->location, range->location + range->length, text);
}
return nsCocoaUtils::ToNSString(text);
@ -571,8 +518,7 @@ ToNSString(id aValue)
@implementation mozTextLeafAccessible
- (NSArray*)accessibilityAttributeNames
{
- (NSArray*)accessibilityAttributeNames {
static NSMutableArray* supportedAttributes = nil;
if (!supportedAttributes) {
supportedAttributes = [[super accessibilityAttributeNames] mutableCopy];
@ -582,19 +528,15 @@ ToNSString(id aValue)
return supportedAttributes;
}
- (id)accessibilityAttributeValue:(NSString*)attribute
{
if ([attribute isEqualToString:NSAccessibilityTitleAttribute])
return @"";
- (id)accessibilityAttributeValue:(NSString*)attribute {
if ([attribute isEqualToString:NSAccessibilityTitleAttribute]) return @"";
if ([attribute isEqualToString:NSAccessibilityValueAttribute])
return [self text];
if ([attribute isEqualToString:NSAccessibilityValueAttribute]) return [self text];
return [super accessibilityAttributeValue:attribute];
}
- (NSString*)text
{
- (NSString*)text {
if (AccessibleWrap* accWrap = [self getGeckoAccessible]) {
return nsCocoaUtils::ToNSString(accWrap->AsTextLeaf()->Text());
}
@ -608,8 +550,7 @@ ToNSString(id aValue)
return nil;
}
- (long)textLength
{
- (long)textLength {
if (AccessibleWrap* accWrap = [self getGeckoAccessible]) {
return accWrap->AsTextLeaf()->Text().Length();
}

View File

@ -5196,7 +5196,7 @@ class TabProgressListener {
}
}
if (!this.mBlank) {
if (!this.mBlank || this.mBrowser.hasContentOpener) {
this._callProgressListeners("onLocationChange",
[aWebProgress, aRequest, aLocation, aFlags]);
if (topLevel && !isSameDocument) {

View File

@ -40,6 +40,8 @@ skip-if = os != "win" # Windows only feature
[browser_urlbar_blanking.js]
support-files =
file_blank_but_not_blank.html
[browser_urlbar_content_opener.js]
skip-if = debug # Bug 1521835 - shutdown leaks
[browser_urlbar_locationchange_urlbar_edit_dos.js]
support-files =
file_urlbar_edit_dos.html

View File

@ -0,0 +1,18 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
const TEST_PATH = getRootDirectory(gTestPath).replace("chrome://mochitests/content", "https://example.com");
add_task(async function() {
await BrowserTestUtils.withNewTab(TEST_PATH + "dummy_page.html", async function(browser) {
let windowOpenedPromise = BrowserTestUtils.waitForNewWindow();
await ContentTask.spawn(browser, null, function() {
content.window.open("", "_BLANK", "toolbar=no,height=300,width=500");
});
let newWin = await windowOpenedPromise;
is(newWin.gURLBar.value, "about:blank", "Should be displaying about:blank for the opened window.");
await BrowserTestUtils.closeWindow(newWin);
});
});

View File

@ -10,6 +10,7 @@
exports.animations = require("devtools/client/inspector/animation/reducers/animations");
exports.boxModel = require("devtools/client/inspector/boxmodel/reducers/box-model");
exports.changes = require("devtools/client/inspector/changes/reducers/changes");
exports.classList = require("devtools/client/inspector/rules/reducers/class-list");
exports.extensionsSidebar = require("devtools/client/inspector/extensions/reducers/sidebar");
exports.flexbox = require("devtools/client/inspector/flexbox/reducers/flexbox");
exports.fontOptions = require("devtools/client/inspector/fonts/reducers/font-options");

View File

@ -0,0 +1,40 @@
/* 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/. */
"use strict";
const {
UPDATE_CLASSES,
UPDATE_CLASS_PANEL_EXPANDED,
} = require("./index");
module.exports = {
/**
* Updates the entire class list state with the new list of classes.
*
* @param {Array<Object>} classes
* Array of CSS classes object applied to the element.
*/
updateClasses(classes) {
return {
type: UPDATE_CLASSES,
classes,
};
},
/**
* Updates whether or not the class list panel is expanded.
*
* @param {Boolean} isClassPanelExpanded
* Whether or not the class list panel is expanded.
*/
updateClassPanelExpanded(isClassPanelExpanded) {
return {
type: UPDATE_CLASS_PANEL_EXPANDED,
isClassPanelExpanded,
};
},
};

View File

@ -19,6 +19,12 @@ createEnum([
// Toggles on or off the given pseudo class value for the current selected element.
"TOGGLE_PSEUDO_CLASS",
// Updates the entire class list state with the new list of classes.
"UPDATE_CLASSES",
// Updates whether or not the class list panel is expanded.
"UPDATE_CLASS_PANEL_EXPANDED",
// Updates the highlighted selector.
"UPDATE_HIGHLIGHTED_SELECTOR",

View File

@ -3,6 +3,7 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
DevToolsModules(
'class-list.js',
'index.js',
'pseudo-classes.js',
'rules.js',

View File

@ -4,14 +4,57 @@
"use strict";
const { PureComponent } = require("devtools/client/shared/vendor/react");
const { createRef, PureComponent } = require("devtools/client/shared/vendor/react");
const dom = require("devtools/client/shared/vendor/react-dom-factories");
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
const { connect } = require("devtools/client/shared/vendor/react-redux");
const { KeyCodes } = require("devtools/client/shared/keycodes");
const { getStr } = require("../utils/l10n");
const Types = require("../types");
class ClassListPanel extends PureComponent {
static get propTypes() {
return {};
return {
classes: PropTypes.arrayOf(PropTypes.shape(Types.class)).isRequired,
onAddClass: PropTypes.func.isRequired,
onSetClassState: PropTypes.func.isRequired,
};
}
constructor(props) {
super(props);
this.state = {
// Class list panel input value.
value: "",
};
this.inputRef = createRef();
this.onInputChange = this.onInputChange.bind(this);
this.onInputKeyUp = this.onInputKeyUp.bind(this);
this.onToggleChange = this.onToggleChange.bind(this);
}
componentDidMount() {
this.inputRef.current.focus();
}
onInputChange({ target }) {
this.setState({ value: target.value });
}
onInputKeyUp({ target, keyCode }) {
// On Enter, submit the input.
if (keyCode === KeyCodes.DOM_VK_RETURN) {
this.props.onAddClass(target.value);
this.setState({ value: "" });
}
}
onToggleChange({ target }) {
this.props.onSetClassState(target.value, target.checked);
}
render() {
@ -24,13 +67,42 @@ class ClassListPanel extends PureComponent {
dom.input({
className: "devtools-textinput add-class",
placeholder: getStr("rule.classPanel.newClass.placeholder"),
onChange: this.onInputChange,
onKeyUp: this.onInputKeyUp,
ref: this.inputRef,
value: this.state.value,
}),
dom.div({ className: "classes" },
dom.p({ className: "no-classes" }, getStr("rule.classPanel.noClasses"))
this.props.classes.length ?
this.props.classes.map(({ name, isApplied }) => {
return (
dom.label(
{
key: name,
title: name,
},
dom.input({
checked: isApplied,
onChange: this.onToggleChange,
type: "checkbox",
value: name,
}),
dom.span({}, name)
)
);
})
:
dom.p({ className: "no-classes" }, getStr("rule.classPanel.noClasses"))
)
)
);
}
}
module.exports = ClassListPanel;
const mapStateToProps = state => {
return {
classes: state.classList.classes,
};
};
module.exports = connect(mapStateToProps)(ClassListPanel);

View File

@ -21,6 +21,7 @@ class Rule extends PureComponent {
onToggleDeclaration: PropTypes.func.isRequired,
onToggleSelectorHighlighter: PropTypes.func.isRequired,
rule: PropTypes.shape(Types.rule).isRequired,
showSelectorEditor: PropTypes.func.isRequired,
};
}
@ -29,9 +30,11 @@ class Rule extends PureComponent {
onToggleDeclaration,
onToggleSelectorHighlighter,
rule,
showSelectorEditor,
} = this.props;
const {
declarations,
id,
isUnmatched,
isUserAgentStyle,
selector,
@ -50,7 +53,10 @@ class Rule extends PureComponent {
dom.div({ className: "ruleview-code" },
dom.div({},
Selector({
id,
isUserAgentStyle,
selector,
showSelectorEditor,
type,
}),
type !== CSSRule.KEYFRAME_RULE ?

View File

@ -17,6 +17,7 @@ class Rules extends PureComponent {
onToggleDeclaration: PropTypes.func.isRequired,
onToggleSelectorHighlighter: PropTypes.func.isRequired,
rules: PropTypes.arrayOf(PropTypes.shape(Types.rule)).isRequired,
showSelectorEditor: PropTypes.func.isRequired,
};
}
@ -25,6 +26,7 @@ class Rules extends PureComponent {
onToggleDeclaration,
onToggleSelectorHighlighter,
rules,
showSelectorEditor,
} = this.props;
return rules.map(rule => {
@ -33,6 +35,7 @@ class Rules extends PureComponent {
onToggleDeclaration,
onToggleSelectorHighlighter,
rule,
showSelectorEditor,
});
});
}

View File

@ -28,10 +28,22 @@ const SHOW_PSEUDO_ELEMENTS_PREF = "devtools.inspector.show_pseudo_elements";
class RulesApp extends PureComponent {
static get propTypes() {
return {
onAddClass: PropTypes.func.isRequired,
onSetClassState: PropTypes.func.isRequired,
onToggleClassPanelExpanded: PropTypes.func.isRequired,
onToggleDeclaration: PropTypes.func.isRequired,
onTogglePseudoClass: PropTypes.func.isRequired,
onToggleSelectorHighlighter: PropTypes.func.isRequired,
rules: PropTypes.arrayOf(PropTypes.shape(Types.rule)).isRequired,
showSelectorEditor: PropTypes.func.isRequired,
};
}
getRuleProps() {
return {
onToggleDeclaration: this.props.onToggleDeclaration,
onToggleSelectorHighlighter: this.props.onToggleSelectorHighlighter,
showSelectorEditor: this.props.showSelectorEditor,
};
}
@ -53,8 +65,7 @@ class RulesApp extends PureComponent {
}
output.push(Rule({
onToggleDeclaration: this.props.onToggleDeclaration,
onToggleSelectorHighlighter: this.props.onToggleSelectorHighlighter,
...this.getRuleProps(),
rule,
}));
}
@ -81,8 +92,7 @@ class RulesApp extends PureComponent {
{
component: Rules,
componentProps: {
onToggleDeclaration: this.props.onToggleDeclaration,
onToggleSelectorHighlighter: this.props.onToggleSelectorHighlighter,
...this.getRuleProps(),
rules: rules.filter(r => r.keyframesRule.id === lastKeyframes),
},
header: rule.keyframesRule.keyframesName,
@ -102,8 +112,7 @@ class RulesApp extends PureComponent {
}
return Rules({
onToggleDeclaration: this.props.onToggleDeclaration,
onToggleSelectorHighlighter: this.props.onToggleSelectorHighlighter,
...this.getRuleProps(),
rules,
});
}
@ -117,8 +126,7 @@ class RulesApp extends PureComponent {
{
component: Rules,
componentProps: {
onToggleDeclaration: this.props.onToggleDeclaration,
onToggleSelectorHighlighter: this.props.onToggleSelectorHighlighter,
...this.getRuleProps(),
rules,
},
header: getStr("rule.pseudoElement"),
@ -162,6 +170,9 @@ class RulesApp extends PureComponent {
className: "theme-sidebar inspector-tabpanel",
},
Toolbar({
onAddClass: this.props.onAddClass,
onSetClassState: this.props.onSetClassState,
onToggleClassPanelExpanded: this.props.onToggleClassPanelExpanded,
onTogglePseudoClass: this.props.onTogglePseudoClass,
}),
dom.div(

View File

@ -4,10 +4,10 @@
"use strict";
const { PureComponent } = require("devtools/client/shared/vendor/react");
const { createRef, PureComponent } = require("devtools/client/shared/vendor/react");
const dom = require("devtools/client/shared/vendor/react-dom-factories");
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
const { editableItem } = require("devtools/client/shared/inplace-editor");
const {
parsePseudoClassesAndAttributes,
SELECTOR_ATTRIBUTE,
@ -24,11 +24,34 @@ const Types = require("../types");
class Selector extends PureComponent {
static get propTypes() {
return {
id: PropTypes.string.isRequired,
isUserAgentStyle: PropTypes.bool.isRequired,
selector: PropTypes.shape(Types.selector).isRequired,
showSelectorEditor: PropTypes.func.isRequired,
type: PropTypes.number.isRequired,
};
}
constructor(props) {
super(props);
this.selectorRef = createRef();
}
componentDidMount() {
if (this.props.isUserAgentStyle ||
this.props.type === ELEMENT_STYLE ||
this.props.type === CSSRule.KEYFRAME_RULE) {
// Selector is not editable.
return;
}
editableItem({
element: this.selectorRef.current,
}, element => {
this.props.showSelectorEditor(element, this.props.id);
});
}
renderSelector() {
// Show the text directly for custom selector text (such as the inline "element"
// style and Keyframes rules).
@ -87,6 +110,7 @@ class Selector extends PureComponent {
dom.span(
{
className: "ruleview-selectorcontainer",
ref: this.selectorRef,
tabIndex: 0,
},
this.renderSelector()

View File

@ -7,6 +7,7 @@
const { createFactory, PureComponent } = require("devtools/client/shared/vendor/react");
const dom = require("devtools/client/shared/vendor/react-dom-factories");
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
const { connect } = require("devtools/client/shared/vendor/react-redux");
const SearchBox = createFactory(require("./SearchBox"));
@ -22,6 +23,10 @@ const { getStr } = require("../utils/l10n");
class Toolbar extends PureComponent {
static get propTypes() {
return {
isClassPanelExpanded: PropTypes.bool.isRequired,
onAddClass: PropTypes.func.isRequired,
onSetClassState: PropTypes.func.isRequired,
onToggleClassPanelExpanded: PropTypes.func.isRequired,
onTogglePseudoClass: PropTypes.func.isRequired,
};
}
@ -30,8 +35,6 @@ class Toolbar extends PureComponent {
super(props);
this.state = {
// Whether or not the class panel is expanded.
isClassPanelExpanded: false,
// Whether or not the pseudo class panel is expanded.
isPseudoClassPanelExpanded: false,
};
@ -43,14 +46,13 @@ class Toolbar extends PureComponent {
onClassPanelToggle(event) {
event.stopPropagation();
const isClassPanelExpanded = !this.props.isClassPanelExpanded;
this.props.onToggleClassPanelExpanded(isClassPanelExpanded);
this.setState(prevState => {
const isClassPanelExpanded = !prevState.isClassPanelExpanded;
const isPseudoClassPanelExpanded = isClassPanelExpanded ?
false : prevState.isPseudoClassPanelExpanded;
return {
isClassPanelExpanded,
isPseudoClassPanelExpanded,
isPseudoClassPanelExpanded: isClassPanelExpanded ?
false :
prevState.isPseudoClassPanelExpanded,
};
});
}
@ -58,23 +60,18 @@ class Toolbar extends PureComponent {
onPseudoClassPanelToggle(event) {
event.stopPropagation();
this.setState(prevState => {
const isPseudoClassPanelExpanded = !prevState.isPseudoClassPanelExpanded;
const isClassPanelExpanded = isPseudoClassPanelExpanded ?
false : prevState.isClassPanelExpanded;
const isPseudoClassPanelExpanded = !this.state.isPseudoClassPanelExpanded;
return {
isClassPanelExpanded,
isPseudoClassPanelExpanded,
};
});
if (isPseudoClassPanelExpanded) {
this.props.onToggleClassPanelExpanded(false);
}
this.setState({ isPseudoClassPanelExpanded });
}
render() {
const {
isClassPanelExpanded,
isPseudoClassPanelExpanded,
} = this.state;
const { isClassPanelExpanded } = this.props;
const { isPseudoClassPanelExpanded } = this.state;
return (
dom.div(
@ -107,7 +104,10 @@ class Toolbar extends PureComponent {
)
),
isClassPanelExpanded ?
ClassListPanel({})
ClassListPanel({
onAddClass: this.props.onAddClass,
onSetClassState: this.props.onSetClassState,
})
:
null,
isPseudoClassPanelExpanded ?
@ -121,4 +121,10 @@ class Toolbar extends PureComponent {
}
}
module.exports = Toolbar;
const mapStateToProps = state => {
return {
isClassPanelExpanded: state.classList.isClassPanelExpanded,
};
};
module.exports = connect(mapStateToProps)(Toolbar);

View File

@ -0,0 +1,191 @@
/* 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/. */
"use strict";
const EventEmitter = require("devtools/shared/event-emitter");
// This serves as a local cache for the classes applied to each of the node we care about
// here.
// The map is indexed by NodeFront. Any time a new node is selected in the inspector, an
// entry is added here, indexed by the corresponding NodeFront.
// The value for each entry is an array of each of the class this node has. Items of this
// array are objects like: { name, isApplied } where the name is the class itself, and
// isApplied is a Boolean indicating if the class is applied on the node or not.
const CLASSES = new WeakMap();
/**
* Manages the list classes per DOM elements we care about.
* The actual list is stored in the CLASSES const, indexed by NodeFront objects.
* The responsibility of this class is to be the source of truth for anyone who wants to
* know which classes a given NodeFront has, and which of these are enabled and which are
* disabled.
* It also reacts to DOM mutations so the list of classes is up to date with what is in
* the DOM.
* It can also be used to enable/disable a given class, or add classes.
*
* @param {Inspector} inspector
* The current inspector instance.
*/
function ClassList(inspector) {
EventEmitter.decorate(this);
this.inspector = inspector;
this.onMutations = this.onMutations.bind(this);
this.inspector.on("markupmutation", this.onMutations);
this.classListProxyNode = this.inspector.panelDoc.createElement("div");
}
ClassList.prototype = {
destroy() {
this.inspector.off("markupmutation", this.onMutations);
this.inspector = null;
this.classListProxyNode = null;
},
/**
* The current node selection (which only returns if the node is an ELEMENT_NODE type
* since that's the only type this model can work with.)
*/
get currentNode() {
if (this.inspector.selection.isElementNode() &&
!this.inspector.selection.isPseudoElementNode()) {
return this.inspector.selection.nodeFront;
}
return null;
},
/**
* The class states for the current node selection. See the documentation of the CLASSES
* constant.
*/
get currentClasses() {
if (!this.currentNode) {
return [];
}
if (!CLASSES.has(this.currentNode)) {
// Use the proxy node to get a clean list of classes.
this.classListProxyNode.className = this.currentNode.className;
const nodeClasses = [...new Set([...this.classListProxyNode.classList])]
.map(name => {
return { name, isApplied: true };
});
CLASSES.set(this.currentNode, nodeClasses);
}
return CLASSES.get(this.currentNode);
},
/**
* Same as currentClasses, but returns it in the form of a className string, where only
* enabled classes are added.
*/
get currentClassesPreview() {
return this.currentClasses.filter(({ isApplied }) => isApplied)
.map(({ name }) => name)
.join(" ");
},
/**
* Set the state for a given class on the current node.
*
* @param {String} name
* The class which state should be changed.
* @param {Boolean} isApplied
* True if the class should be enabled, false otherwise.
* @return {Promise} Resolves when the change has been made in the DOM.
*/
setClassState(name, isApplied) {
// Do the change in our local model.
const nodeClasses = this.currentClasses;
nodeClasses.find(({ name: cName }) => cName === name).isApplied = isApplied;
return this.applyClassState();
},
/**
* Add several classes to the current node at once.
*
* @param {String} classNameString
* The string that contains all classes.
* @return {Promise} Resolves when the change has been made in the DOM.
*/
addClassName(classNameString) {
this.classListProxyNode.className = classNameString;
return Promise.all([...new Set([...this.classListProxyNode.classList])].map(name => {
return this.addClass(name);
}));
},
/**
* Add a class to the current node at once.
*
* @param {String} name
* The class to be added.
* @return {Promise} Resolves when the change has been made in the DOM.
*/
addClass(name) {
// Avoid adding the same class again.
if (this.currentClasses.some(({ name: cName }) => cName === name)) {
return Promise.resolve();
}
// Change the local model, so we retain the state of the existing classes.
this.currentClasses.push({ name, isApplied: true });
return this.applyClassState();
},
/**
* Used internally by other functions like addClass or setClassState. Actually applies
* the class change to the DOM.
*
* @return {Promise} Resolves when the change has been made in the DOM.
*/
applyClassState() {
// If there is no valid inspector selection, bail out silently. No need to report an
// error here.
if (!this.currentNode) {
return Promise.resolve();
}
// Remember which node we changed and the className we applied, so we can filter out
// dom mutations that are caused by us in onMutations.
this.lastStateChange = {
node: this.currentNode,
className: this.currentClassesPreview,
};
// Apply the change to the node.
const mod = this.currentNode.startModifyingAttributes();
mod.setAttribute("class", this.currentClassesPreview);
return mod.apply();
},
onMutations(mutations) {
for (const {type, target, attributeName} of mutations) {
// Only care if this mutation is for the class attribute.
if (type !== "attributes" || attributeName !== "class") {
continue;
}
const isMutationForOurChange = this.lastStateChange &&
target === this.lastStateChange.node &&
target.className === this.lastStateChange.className;
if (!isMutationForOurChange) {
CLASSES.delete(target);
if (target === this.currentNode) {
this.emit("current-node-class-changed");
}
}
}
},
};
module.exports = ClassList;

View File

@ -332,6 +332,73 @@ ElementStyle.prototype = {
}
},
/**
* Modifies the existing rule's selector to the new given value.
*
* @param {String} ruleId
* The id of the Rule to be modified.
* @param {String} selector
* The new selector value.
*/
modifySelector: async function(ruleId, selector) {
try {
const rule = this.getRule(ruleId);
if (!rule) {
return;
}
const response = await rule.domRule.modifySelector(this.element, selector);
const { ruleProps, isMatching } = response;
if (!ruleProps) {
// Notify for changes, even when nothing changes, just to allow tests
// being able to track end of this request.
this.ruleView.emit("ruleview-invalid-selector");
return;
}
const newRule = new Rule(this, {
...ruleProps,
isUnmatched: !isMatching,
});
// Recompute the list of applied styles because editing a
// selector might cause this rule's position to change.
const appliedStyles = await this.pageStyle.getApplied(this.element, {
inherited: true,
matchedSelectors: true,
filter: this.showUserAgentStyles ? "ua" : undefined,
});
const newIndex = appliedStyles.findIndex(r => r.rule == ruleProps.rule);
const oldIndex = this.rules.indexOf(rule);
// Remove the old rule and insert the new rule according to where it appears
// in the list of applied styles.
this.rules.splice(oldIndex, 1);
// If the selector no longer matches, then we leave the rule in
// the same relative position.
this.rules.splice(newIndex === -1 ? oldIndex : newIndex, 0, newRule);
// Mark any properties that are overridden according to the new list of rules.
this.markOverriddenAll();
// In order to keep the new rule in place of the old in the rules view, we need
// to remove the rule again if the rule was inserted to its new index according
// to the list of applied styles.
// Note: you might think we would replicate the list-modification logic above,
// but that is complicated due to the way the UI installs pseudo-element rules
// and the like.
if (newIndex !== -1) {
this.rules.splice(newIndex, 1);
this.rules.splice(oldIndex, 0, newRule);
}
this._changed();
} catch (e) {
console.error(e);
}
},
/**
* Toggles the enabled state of the given CSS declaration.
*

View File

@ -5,6 +5,7 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
DevToolsModules(
'class-list.js',
'element-style.js',
'rule.js',
'text-property.js',

View File

@ -10,6 +10,10 @@ const { createFactory, createElement } = require("devtools/client/shared/vendor/
const { Provider } = require("devtools/client/shared/vendor/react-redux");
const EventEmitter = require("devtools/shared/event-emitter");
const {
updateClasses,
updateClassPanelExpanded,
} = require("./actions/class-list");
const {
disableAllPseudoClasses,
setPseudoClassLocks,
@ -26,6 +30,9 @@ const { LocalizationHelper } = require("devtools/shared/l10n");
const INSPECTOR_L10N =
new LocalizationHelper("devtools/client/locales/inspector.properties");
loader.lazyRequireGetter(this, "ClassList", "devtools/client/inspector/rules/models/class-list");
loader.lazyRequireGetter(this, "InplaceEditor", "devtools/client/shared/inplace-editor", true);
const PREF_UA_STYLES = "devtools.inspector.showUserAgentStyles";
class RulesView {
@ -41,10 +48,15 @@ class RulesView {
this.showUserAgentStyles = Services.prefs.getBoolPref(PREF_UA_STYLES);
this.onAddClass = this.onAddClass.bind(this);
this.onSelection = this.onSelection.bind(this);
this.onSetClassState = this.onSetClassState.bind(this);
this.onToggleClassPanelExpanded = this.onToggleClassPanelExpanded.bind(this);
this.onToggleDeclaration = this.onToggleDeclaration.bind(this);
this.onTogglePseudoClass = this.onTogglePseudoClass.bind(this);
this.onToggleSelectorHighlighter = this.onToggleSelectorHighlighter.bind(this);
this.showSelectorEditor = this.showSelectorEditor.bind(this);
this.updateClassList = this.updateClassList.bind(this);
this.updateRules = this.updateRules.bind(this);
this.inspector.sidebar.on("select", this.onSelection);
@ -62,9 +74,13 @@ class RulesView {
}
const rulesApp = RulesApp({
onAddClass: this.onAddClass,
onSetClassState: this.onSetClassState,
onToggleClassPanelExpanded: this.onToggleClassPanelExpanded,
onToggleDeclaration: this.onToggleDeclaration,
onTogglePseudoClass: this.onTogglePseudoClass,
onToggleSelectorHighlighter: this.onToggleSelectorHighlighter,
showSelectorEditor: this.showSelectorEditor,
});
const provider = createElement(Provider, {
@ -83,6 +99,12 @@ class RulesView {
this.selection.off("detached-front", this.onSelection);
this.selection.off("new-node-front", this.onSelection);
if (this._classList) {
this._classList.off("current-node-class-changed", this.refreshClassList);
this._classList.destroy();
this._classList = null;
}
if (this._selectHighlighter) {
this._selectorHighlighter.finalize();
this._selectorHighlighter = null;
@ -105,6 +127,19 @@ class RulesView {
this.toolbox = null;
}
/**
* Get an instance of the ClassList model used to manage the list of CSS classes
* applied to the element.
*
* @return {ClassList} used to manage the list of CSS classes applied to the element.
*/
get classList() {
if (!this._classList) {
this._classList = new ClassList(this.inspector);
}
return this._classList;
}
/**
* Creates a dummy element in the document that helps get the computed style in
* TextProperty.
@ -166,6 +201,17 @@ class RulesView {
this.inspector.sidebar.getCurrentTabID() === "newruleview";
}
/**
* Handler for adding the given CSS class value to the current element's class list.
*
* @param {String} value
* The string that contains all classes.
*/
async onAddClass(value) {
await this.classList.addClassName(value);
this.updateClassList();
}
/**
* Handler for selection events "detached-front" and "new-node-front" and inspector
* sidbar "select" event. Updates the rules view with the selected node if the panel
@ -185,6 +231,36 @@ class RulesView {
this.update(this.selection.nodeFront);
}
/**
* Handler for toggling a CSS class from the current element's class list. Sets the
* state of given CSS class name to the given checked value.
*
* @param {String} name
* The CSS class name.
* @param {Boolean} checked
* Whether or not the given CSS class is checked.
*/
async onSetClassState(name, checked) {
await this.classList.setClassState(name, checked);
this.updateClassList();
}
/**
* Handler for toggling the expanded property of the class list panel.
*
* @param {Boolean} isClassPanelExpanded
* Whether or not the class list panel is expanded.
*/
onToggleClassPanelExpanded(isClassPanelExpanded) {
if (isClassPanelExpanded) {
this.classList.on("current-node-class-changed", this.updateClassList);
} else {
this.classList.off("current-node-class-changed", this.updateClassList);
}
this.store.dispatch(updateClassPanelExpanded(isClassPanelExpanded));
}
/**
* Handler for toggling the enabled property for a given CSS declaration.
*
@ -251,6 +327,35 @@ class RulesView {
}
}
/**
* Shows the inplace editor for the a selector.
*
* @param {DOMNode} element
* The selector's span element to show the inplace editor.
* @param {String} ruleId
* The id of the Rule to be modified.
*/
showSelectorEditor(element, ruleId) {
new InplaceEditor({
element,
done: async (value, commit) => {
if (!value || !commit) {
return;
}
// Hide the selector highlighter if it matches the selector being edited.
if (this.highlighters.selectorHighlighterShown) {
const selector = await this.elementStyle.getRule(ruleId).getUniqueSelector();
if (this.highlighters.selectorHighlighterShown === selector) {
this.onToggleSelectorHighlighter(this.highlighters.selectorHighlighterShown);
}
}
await this.elementStyle.modifySelector(ruleId, value);
},
});
}
/**
* Updates the rules view by dispatching the new rules data of the newly selected
* element. This is called when the rules view becomes visible or upon new node
@ -262,6 +367,7 @@ class RulesView {
async update(element) {
if (!element) {
this.store.dispatch(disableAllPseudoClasses());
this.store.dispatch(updateClasses([]));
this.store.dispatch(updateRules([]));
return;
}
@ -272,9 +378,17 @@ class RulesView {
await this.elementStyle.populate();
this.store.dispatch(setPseudoClassLocks(this.elementStyle.element.pseudoClassLocks));
this.updateClassList();
this.updateRules();
}
/**
* Updates the class list panel with the current list of CSS classes.
*/
updateClassList() {
this.store.dispatch(updateClasses(this.classList.currentClasses));
}
/**
* Updates the rules view by dispatching the current rules state. This is called from
* the update() function, and from the ElementStyle's onChange() handler.

View File

@ -0,0 +1,44 @@
/* 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/. */
"use strict";
const {
UPDATE_CLASSES,
UPDATE_CLASS_PANEL_EXPANDED,
} = require("../actions/index");
const INITIAL_CLASS_LIST = {
// An array of objects containing the CSS class state that is applied to the current
// element.
classes: [],
// Whether or not the class list panel is expanded.
isClassPanelExpanded: false,
};
const reducers = {
[UPDATE_CLASSES](classList, { classes }) {
return {
...classList,
classes: [...classes],
};
},
[UPDATE_CLASS_PANEL_EXPANDED](classList, { isClassPanelExpanded }) {
return {
...classList,
isClassPanelExpanded,
};
},
};
module.exports = function(classList = INITIAL_CLASS_LIST, action) {
const reducer = reducers[action.type];
if (!reducer) {
return classList;
}
return reducer(classList, action);
};

View File

@ -3,6 +3,7 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
DevToolsModules(
'class-list.js',
'pseudo-classes.js',
'rules.js',
)

View File

@ -6,6 +6,17 @@
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
/**
* A CSS class.
*/
exports.classes = {
// The CSS class name.
name: PropTypes.string,
// Whether or not the CSS class is applied.
isApplied: PropTypes.bool,
};
/**
* A CSS declaration.
*/

View File

@ -4,193 +4,11 @@
"use strict";
const EventEmitter = require("devtools/shared/event-emitter");
const ClassList = require("devtools/client/inspector/rules/models/class-list");
const {LocalizationHelper} = require("devtools/shared/l10n");
const L10N = new LocalizationHelper("devtools/client/locales/inspector.properties");
// This serves as a local cache for the classes applied to each of the node we care about
// here.
// The map is indexed by NodeFront. Any time a new node is selected in the inspector, an
// entry is added here, indexed by the corresponding NodeFront.
// The value for each entry is an array of each of the class this node has. Items of this
// array are objects like: { name, isApplied } where the name is the class itself, and
// isApplied is a Boolean indicating if the class is applied on the node or not.
const CLASSES = new WeakMap();
/**
* Manages the list classes per DOM elements we care about.
* The actual list is stored in the CLASSES const, indexed by NodeFront objects.
* The responsibility of this class is to be the source of truth for anyone who wants to
* know which classes a given NodeFront has, and which of these are enabled and which are
* disabled.
* It also reacts to DOM mutations so the list of classes is up to date with what is in
* the DOM.
* It can also be used to enable/disable a given class, or add classes.
*
* @param {Inspector} inspector
* The current inspector instance.
*/
function ClassListPreviewerModel(inspector) {
EventEmitter.decorate(this);
this.inspector = inspector;
this.onMutations = this.onMutations.bind(this);
this.inspector.on("markupmutation", this.onMutations);
this.classListProxyNode = this.inspector.panelDoc.createElement("div");
}
ClassListPreviewerModel.prototype = {
destroy() {
this.inspector.off("markupmutation", this.onMutations);
this.inspector = null;
this.classListProxyNode = null;
},
/**
* The current node selection (which only returns if the node is an ELEMENT_NODE type
* since that's the only type this model can work with.)
*/
get currentNode() {
if (this.inspector.selection.isElementNode() &&
!this.inspector.selection.isPseudoElementNode()) {
return this.inspector.selection.nodeFront;
}
return null;
},
/**
* The class states for the current node selection. See the documentation of the CLASSES
* constant.
*/
get currentClasses() {
if (!this.currentNode) {
return [];
}
if (!CLASSES.has(this.currentNode)) {
// Use the proxy node to get a clean list of classes.
this.classListProxyNode.className = this.currentNode.className;
const nodeClasses = [...new Set([...this.classListProxyNode.classList])]
.map(name => {
return { name, isApplied: true };
});
CLASSES.set(this.currentNode, nodeClasses);
}
return CLASSES.get(this.currentNode);
},
/**
* Same as currentClasses, but returns it in the form of a className string, where only
* enabled classes are added.
*/
get currentClassesPreview() {
return this.currentClasses.filter(({ isApplied }) => isApplied)
.map(({ name }) => name)
.join(" ");
},
/**
* Set the state for a given class on the current node.
*
* @param {String} name
* The class which state should be changed.
* @param {Boolean} isApplied
* True if the class should be enabled, false otherwise.
* @return {Promise} Resolves when the change has been made in the DOM.
*/
setClassState(name, isApplied) {
// Do the change in our local model.
const nodeClasses = this.currentClasses;
nodeClasses.find(({ name: cName }) => cName === name).isApplied = isApplied;
return this.applyClassState();
},
/**
* Add several classes to the current node at once.
*
* @param {String} classNameString
* The string that contains all classes.
* @return {Promise} Resolves when the change has been made in the DOM.
*/
addClassName(classNameString) {
this.classListProxyNode.className = classNameString;
return Promise.all([...new Set([...this.classListProxyNode.classList])].map(name => {
return this.addClass(name);
}));
},
/**
* Add a class to the current node at once.
*
* @param {String} name
* The class to be added.
* @return {Promise} Resolves when the change has been made in the DOM.
*/
addClass(name) {
// Avoid adding the same class again.
if (this.currentClasses.some(({ name: cName }) => cName === name)) {
return Promise.resolve();
}
// Change the local model, so we retain the state of the existing classes.
this.currentClasses.push({ name, isApplied: true });
return this.applyClassState();
},
/**
* Used internally by other functions like addClass or setClassState. Actually applies
* the class change to the DOM.
*
* @return {Promise} Resolves when the change has been made in the DOM.
*/
applyClassState() {
// If there is no valid inspector selection, bail out silently. No need to report an
// error here.
if (!this.currentNode) {
return Promise.resolve();
}
// Remember which node we changed and the className we applied, so we can filter out
// dom mutations that are caused by us in onMutations.
this.lastStateChange = {
node: this.currentNode,
className: this.currentClassesPreview,
};
// Apply the change to the node.
const mod = this.currentNode.startModifyingAttributes();
mod.setAttribute("class", this.currentClassesPreview);
return mod.apply();
},
onMutations(mutations) {
for (const {type, target, attributeName} of mutations) {
// Only care if this mutation is for the class attribute.
if (type !== "attributes" || attributeName !== "class") {
continue;
}
const isMutationForOurChange = this.lastStateChange &&
target === this.lastStateChange.node &&
target.className === this.lastStateChange.className;
if (!isMutationForOurChange) {
CLASSES.delete(target);
if (target === this.currentNode) {
this.emit("current-node-class-changed");
}
}
}
},
};
/**
* This UI widget shows a textfield and a series of checkboxes in the rule-view. It is
* used to toggle classes on the current node selection, and add new classes.
@ -203,7 +21,7 @@ ClassListPreviewerModel.prototype = {
function ClassListPreviewer(inspector, containerEl) {
this.inspector = inspector;
this.containerEl = containerEl;
this.model = new ClassListPreviewerModel(inspector);
this.model = new ClassList(inspector);
this.onNewSelection = this.onNewSelection.bind(this);
this.onCheckBoxChanged = this.onCheckBoxChanged.bind(this);

View File

@ -45,8 +45,6 @@ function setupServer(mm) {
mm.addMessageListener("debug:content-process-destroy", function onDestroy() {
mm.removeMessageListener("debug:content-process-destroy", onDestroy);
Cu.unblockThreadedExecution();
DebuggerServer.destroy();
gLoader.destroy();
gLoader = null;
@ -59,32 +57,23 @@ function init(msg) {
const mm = msg.target;
const prefix = msg.data.prefix;
// Using the JS debugger causes problems when we're trying to
// schedule those zone groups across different threads. Calling
// blockThreadedExecution causes Gecko to switch to a simpler
// single-threaded model until unblockThreadedExecution is called
// later. We cannot start the debugger until the callback passed to
// blockThreadedExecution has run, signaling that we're running
// single-threaded.
Cu.blockThreadedExecution(() => {
// Setup a server if none started yet
const loader = setupServer(mm);
// Setup a server if none started yet
const loader = setupServer(mm);
// Connect both parent/child processes debugger servers RDP via message
// managers
const { DebuggerServer } = loader.require("devtools/server/main");
const conn = DebuggerServer.connectToParent(prefix, mm);
conn.parentMessageManager = mm;
// Connect both parent/child processes debugger servers RDP via message
// managers
const { DebuggerServer } = loader.require("devtools/server/main");
const conn = DebuggerServer.connectToParent(prefix, mm);
conn.parentMessageManager = mm;
const { ContentProcessTargetActor } =
loader.require("devtools/server/actors/targets/content-process");
const { ActorPool } = loader.require("devtools/server/actors/common");
const actor = new ContentProcessTargetActor(conn);
const actorPool = new ActorPool(conn);
actorPool.addActor(actor);
conn.addActorPool(actorPool);
const { ContentProcessTargetActor } =
loader.require("devtools/server/actors/targets/content-process");
const { ActorPool } = loader.require("devtools/server/actors/common");
const actor = new ContentProcessTargetActor(conn);
const actorPool = new ActorPool(conn);
actorPool.addActor(actor);
conn.addActorPool(actorPool);
const response = { actor: actor.form() };
mm.sendAsyncMessage("debug:content-process-actor", response);
});
const response = { actor: actor.form() };
mm.sendAsyncMessage("debug:content-process-actor", response);
}

View File

@ -39,34 +39,25 @@ try {
const prefix = msg.data.prefix;
const addonId = msg.data.addonId;
// Using the JS debugger causes problems when we're trying to
// schedule those zone groups across different threads. Calling
// blockThreadedExecution causes Gecko to switch to a simpler
// single-threaded model until unblockThreadedExecution is
// called later. We cannot start the debugger until the callback
// passed to blockThreadedExecution has run, signaling that
// we're running single-threaded.
Cu.blockThreadedExecution(() => {
const conn = DebuggerServer.connectToParent(prefix, mm);
conn.parentMessageManager = mm;
connections.set(prefix, conn);
const conn = DebuggerServer.connectToParent(prefix, mm);
conn.parentMessageManager = mm;
connections.set(prefix, conn);
let actor;
let actor;
if (addonId) {
const { WebExtensionTargetActor } = require("devtools/server/actors/targets/webextension");
actor = new WebExtensionTargetActor(conn, chromeGlobal, prefix, addonId);
} else {
const { FrameTargetActor } = require("devtools/server/actors/targets/frame");
actor = new FrameTargetActor(conn, chromeGlobal);
}
if (addonId) {
const { WebExtensionTargetActor } = require("devtools/server/actors/targets/webextension");
actor = new WebExtensionTargetActor(conn, chromeGlobal, prefix, addonId);
} else {
const { FrameTargetActor } = require("devtools/server/actors/targets/frame");
actor = new FrameTargetActor(conn, chromeGlobal);
}
const actorPool = new ActorPool(conn);
actorPool.addActor(actor);
conn.addActorPool(actorPool);
const actorPool = new ActorPool(conn);
actorPool.addActor(actor);
conn.addActorPool(actorPool);
sendAsyncMessage("debug:actor", {actor: actor.form(), prefix: prefix});
});
sendAsyncMessage("debug:actor", {actor: actor.form(), prefix: prefix});
});
addMessageListener("debug:connect", onConnect);
@ -113,8 +104,6 @@ try {
return;
}
Cu.unblockThreadedExecution();
removeMessageListener("debug:disconnect", onDisconnect);
// Call DebuggerServerConnection.close to destroy all child actors. It should end up
// calling DebuggerServerConnection.onClosed that would actually cleanup all actor

View File

@ -99,7 +99,6 @@
#include "mozilla/ProcessHangMonitorIPC.h"
#include "mozilla/RDDProcessManager.h"
#include "mozilla/recordreplay/ParentIPC.h"
#include "mozilla/Scheduler.h"
#include "mozilla/ScopeExit.h"
#include "mozilla/ScriptPreloader.h"
#include "mozilla/Services.h"
@ -2187,12 +2186,6 @@ void ContentParent::LaunchSubprocessInternal(
extraArgs.push_back("-prefMapSize");
extraArgs.push_back(formatPtrArg(prefSerializer.GetPrefMapSize()).get());
// Scheduler prefs need to be handled differently because the scheduler needs
// to start up in the content process before the normal preferences service.
nsPrintfCString schedulerPrefs = Scheduler::GetPrefs();
extraArgs.push_back("-schedulerPrefs");
extraArgs.push_back(schedulerPrefs.get());
if (gSafeMode) {
extraArgs.push_back("-safeMode");
}

View File

@ -9,7 +9,6 @@
#include "ContentProcess.h"
#include "base/shared_memory.h"
#include "mozilla/Preferences.h"
#include "mozilla/Scheduler.h"
#include "mozilla/recordreplay/ParentIPC.h"
#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX)
@ -81,7 +80,6 @@ static void SetUpSandboxEnvironment() {
bool ContentProcess::Init(int aArgc, char* aArgv[]) {
Maybe<uint64_t> childID;
Maybe<bool> isForBrowser;
Maybe<const char*> schedulerPrefs;
Maybe<const char*> parentBuildID;
char* prefsHandle = nullptr;
char* prefMapHandle = nullptr;
@ -142,12 +140,6 @@ bool ContentProcess::Init(int aArgc, char* aArgv[]) {
return false;
}
prefMapSize = aArgv[i];
} else if (strcmp(aArgv[i], "-schedulerPrefs") == 0) {
if (++i == aArgc) {
return false;
}
schedulerPrefs = Some(aArgv[i]);
} else if (strcmp(aArgv[i], "-safeMode") == 0) {
gSafeMode = true;
@ -174,7 +166,7 @@ bool ContentProcess::Init(int aArgc, char* aArgv[]) {
// Did we find all the mandatory flags?
if (childID.isNothing() || isForBrowser.isNothing() ||
schedulerPrefs.isNothing() || parentBuildID.isNothing()) {
parentBuildID.isNothing()) {
return false;
}
@ -184,8 +176,6 @@ bool ContentProcess::Init(int aArgc, char* aArgv[]) {
return false;
}
Scheduler::SetPrefs(*schedulerPrefs);
if (recordreplay::IsMiddleman()) {
recordreplay::parent::InitializeMiddleman(aArgc, aArgv, ParentPid(),
deserializer.GetPrefsHandle(),

View File

@ -27,11 +27,9 @@
using namespace mozilla;
class SpeechTaskCallback final : public nsISpeechTaskCallback
{
public:
SpeechTaskCallback(nsISpeechTask* aTask,
NSSpeechSynthesizer* aSynth,
class SpeechTaskCallback final : public nsISpeechTaskCallback {
public:
SpeechTaskCallback(nsISpeechTask* aTask, NSSpeechSynthesizer* aSynth,
const nsTArray<size_t>& aOffsets);
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
@ -43,7 +41,7 @@ public:
void OnError(uint32_t aIndex);
void OnDidFinishSpeaking();
private:
private:
virtual ~SpeechTaskCallback();
float GetTimeDurationFromStart();
@ -56,40 +54,35 @@ private:
nsTArray<size_t> mOffsets;
};
@interface SpeechDelegate : NSObject<NSSpeechSynthesizerDelegate>
{
@private
@interface SpeechDelegate : NSObject <NSSpeechSynthesizerDelegate> {
@private
SpeechTaskCallback* mCallback;
}
- (id)initWithCallback:(SpeechTaskCallback*)aCallback;
- (id)initWithCallback:(SpeechTaskCallback*)aCallback;
@end
@implementation SpeechDelegate
- (id)initWithCallback:(SpeechTaskCallback*)aCallback
{
- (id)initWithCallback:(SpeechTaskCallback*)aCallback {
[super init];
mCallback = aCallback;
return self;
}
- (void)speechSynthesizer:(NSSpeechSynthesizer *)aSender
willSpeakWord:(NSRange)aRange ofString:(NSString*)aString
{
- (void)speechSynthesizer:(NSSpeechSynthesizer*)aSender
willSpeakWord:(NSRange)aRange
ofString:(NSString*)aString {
mCallback->OnWillSpeakWord(aRange.location, aRange.length);
}
- (void)speechSynthesizer:(NSSpeechSynthesizer *)aSender
didFinishSpeaking:(BOOL)aFinishedSpeaking
{
- (void)speechSynthesizer:(NSSpeechSynthesizer*)aSender didFinishSpeaking:(BOOL)aFinishedSpeaking {
mCallback->OnDidFinishSpeaking();
}
- (void)speechSynthesizer:(NSSpeechSynthesizer*)aSender
didEncounterErrorAtIndex:(NSUInteger)aCharacterIndex
ofString:(NSString*)aString
message:(NSString*)aMessage
{
didEncounterErrorAtIndex:(NSUInteger)aCharacterIndex
ofString:(NSString*)aString
message:(NSString*)aMessage {
mCallback->OnError(aCharacterIndex);
}
@end
@ -104,29 +97,22 @@ NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTING_ADDREF(SpeechTaskCallback)
NS_IMPL_CYCLE_COLLECTING_RELEASE(SpeechTaskCallback)
SpeechTaskCallback::SpeechTaskCallback(nsISpeechTask* aTask,
NSSpeechSynthesizer* aSynth,
SpeechTaskCallback::SpeechTaskCallback(nsISpeechTask* aTask, NSSpeechSynthesizer* aSynth,
const nsTArray<size_t>& aOffsets)
: mTask(aTask)
, mSpeechSynthesizer(aSynth)
, mCurrentIndex(0)
, mOffsets(aOffsets)
{
: mTask(aTask), mSpeechSynthesizer(aSynth), mCurrentIndex(0), mOffsets(aOffsets) {
mDelegate = [[SpeechDelegate alloc] initWithCallback:this];
[mSpeechSynthesizer setDelegate:mDelegate];
mStartingTime = TimeStamp::Now();
}
SpeechTaskCallback::~SpeechTaskCallback()
{
SpeechTaskCallback::~SpeechTaskCallback() {
[mSpeechSynthesizer setDelegate:nil];
[mDelegate release];
[mSpeechSynthesizer release];
}
NS_IMETHODIMP
SpeechTaskCallback::OnCancel()
{
SpeechTaskCallback::OnCancel() {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
[mSpeechSynthesizer stopSpeaking];
@ -136,8 +122,7 @@ SpeechTaskCallback::OnCancel()
}
NS_IMETHODIMP
SpeechTaskCallback::OnPause()
{
SpeechTaskCallback::OnPause() {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
[mSpeechSynthesizer pauseSpeakingAtBoundary:NSSpeechImmediateBoundary];
@ -153,8 +138,7 @@ SpeechTaskCallback::OnPause()
}
NS_IMETHODIMP
SpeechTaskCallback::OnResume()
{
SpeechTaskCallback::OnResume() {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
[mSpeechSynthesizer continueSpeaking];
@ -170,48 +154,39 @@ SpeechTaskCallback::OnResume()
}
NS_IMETHODIMP
SpeechTaskCallback::OnVolumeChanged(float aVolume)
{
SpeechTaskCallback::OnVolumeChanged(float aVolume) {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
[mSpeechSynthesizer setObject:[NSNumber numberWithFloat:aVolume]
forProperty:NSSpeechVolumeProperty error:nil];
forProperty:NSSpeechVolumeProperty
error:nil];
return NS_OK;
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
}
float
SpeechTaskCallback::GetTimeDurationFromStart()
{
float SpeechTaskCallback::GetTimeDurationFromStart() {
TimeDuration duration = TimeStamp::Now() - mStartingTime;
return duration.ToMilliseconds();
}
void
SpeechTaskCallback::OnWillSpeakWord(uint32_t aIndex, uint32_t aLength)
{
void SpeechTaskCallback::OnWillSpeakWord(uint32_t aIndex, uint32_t aLength) {
mCurrentIndex = aIndex < mOffsets.Length() ? mOffsets[aIndex] : mCurrentIndex;
if (!mTask) {
return;
}
mTask->DispatchBoundary(NS_LITERAL_STRING("word"),
GetTimeDurationFromStart(),
mCurrentIndex, aLength, 1);
mTask->DispatchBoundary(NS_LITERAL_STRING("word"), GetTimeDurationFromStart(), mCurrentIndex,
aLength, 1);
}
void
SpeechTaskCallback::OnError(uint32_t aIndex)
{
void SpeechTaskCallback::OnError(uint32_t aIndex) {
if (!mTask) {
return;
}
mTask->DispatchError(GetTimeDurationFromStart(), aIndex);
}
void
SpeechTaskCallback::OnDidFinishSpeaking()
{
void SpeechTaskCallback::OnDidFinishSpeaking() {
mTask->DispatchEnd(GetTimeDurationFromStart(), mCurrentIndex);
// no longer needed
[mSpeechSynthesizer setDelegate:nil];
@ -221,11 +196,8 @@ SpeechTaskCallback::OnDidFinishSpeaking()
namespace mozilla {
namespace dom {
struct OSXVoice
{
OSXVoice() : mIsDefault(false)
{
}
struct OSXVoice {
OSXVoice() : mIsDefault(false) {}
nsString mUri;
nsString mName;
@ -233,20 +205,14 @@ struct OSXVoice
bool mIsDefault;
};
class RegisterVoicesRunnable final : public Runnable
{
public:
RegisterVoicesRunnable(OSXSpeechSynthesizerService* aSpeechService,
nsTArray<OSXVoice>& aList)
: Runnable("RegisterVoicesRunnable")
, mSpeechService(aSpeechService)
, mVoices(aList)
{
}
class RegisterVoicesRunnable final : public Runnable {
public:
RegisterVoicesRunnable(OSXSpeechSynthesizerService* aSpeechService, nsTArray<OSXVoice>& aList)
: Runnable("RegisterVoicesRunnable"), mSpeechService(aSpeechService), mVoices(aList) {}
NS_IMETHOD Run() override;
private:
private:
~RegisterVoicesRunnable() override = default;
// This runnable always use sync mode. It is unnecesarry to reference object
@ -255,11 +221,9 @@ private:
};
NS_IMETHODIMP
RegisterVoicesRunnable::Run()
{
RegisterVoicesRunnable::Run() {
nsresult rv;
nsCOMPtr<nsISynthVoiceRegistry> registry =
do_GetService(NS_SYNTHVOICEREGISTRY_CONTRACTID, &rv);
nsCOMPtr<nsISynthVoiceRegistry> registry = do_GetService(NS_SYNTHVOICEREGISTRY_CONTRACTID, &rv);
if (!registry) {
return rv;
}
@ -280,26 +244,21 @@ RegisterVoicesRunnable::Run()
return NS_OK;
}
class EnumVoicesRunnable final : public Runnable
{
public:
class EnumVoicesRunnable final : public Runnable {
public:
explicit EnumVoicesRunnable(OSXSpeechSynthesizerService* aSpeechService)
: Runnable("EnumVoicesRunnable")
, mSpeechService(aSpeechService)
{
}
: Runnable("EnumVoicesRunnable"), mSpeechService(aSpeechService) {}
NS_IMETHOD Run() override;
private:
private:
~EnumVoicesRunnable() override = default;
RefPtr<OSXSpeechSynthesizerService> mSpeechService;
};
NS_IMETHODIMP
EnumVoicesRunnable::Run()
{
EnumVoicesRunnable::Run() {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
AutoTArray<OSXVoice, 64> list;
@ -313,13 +272,11 @@ EnumVoicesRunnable::Run()
NSDictionary* attr = [NSSpeechSynthesizer attributesForVoice:voice];
nsAutoString identifier;
nsCocoaUtils::GetStringForNSString([attr objectForKey:NSVoiceIdentifier],
identifier);
nsCocoaUtils::GetStringForNSString([attr objectForKey:NSVoiceIdentifier], identifier);
nsCocoaUtils::GetStringForNSString([attr objectForKey:NSVoiceName], item.mName);
nsCocoaUtils::GetStringForNSString(
[attr objectForKey:NSVoiceLocaleIdentifier], item.mLocale);
nsCocoaUtils::GetStringForNSString([attr objectForKey:NSVoiceLocaleIdentifier], item.mLocale);
item.mLocale.ReplaceChar('_', '-');
item.mUri.AssignLiteral("urn:moz-tts:osx:");
@ -351,15 +308,9 @@ NS_INTERFACE_MAP_END
NS_IMPL_ADDREF(OSXSpeechSynthesizerService)
NS_IMPL_RELEASE(OSXSpeechSynthesizerService)
OSXSpeechSynthesizerService::OSXSpeechSynthesizerService()
: mInitialized(false)
{
}
OSXSpeechSynthesizerService::OSXSpeechSynthesizerService() : mInitialized(false) {}
bool
OSXSpeechSynthesizerService::Init()
{
bool OSXSpeechSynthesizerService::Init() {
if (Preferences::GetBool("media.webspeech.synth.test") ||
!Preferences::GetBool("media.webspeech.synth.enabled")) {
// When test is enabled, we shouldn't add OS backend (Bug 1160844)
@ -368,7 +319,7 @@ OSXSpeechSynthesizerService::Init()
nsCOMPtr<nsIThread> thread;
if (NS_FAILED(NS_NewNamedThread("SpeechWorker", getter_AddRefs(thread)))) {
return false;
return false;
}
// Get all the voices and register in the SynthVoiceRegistry
@ -380,13 +331,8 @@ OSXSpeechSynthesizerService::Init()
}
NS_IMETHODIMP
OSXSpeechSynthesizerService::Speak(const nsAString& aText,
const nsAString& aUri,
float aVolume,
float aRate,
float aPitch,
nsISpeechTask* aTask)
{
OSXSpeechSynthesizerService::Speak(const nsAString& aText, const nsAString& aUri, float aVolume,
float aRate, float aPitch, nsISpeechTask* aTask) {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
MOZ_ASSERT(StringBeginsWith(aUri, NS_LITERAL_STRING("urn:moz-tts:osx:")),
@ -398,18 +344,16 @@ OSXSpeechSynthesizerService::Speak(const nsAString& aText,
[synth setVoice:identifier];
// default rate is 180-220
[synth setObject:[NSNumber numberWithInt:aRate * 200]
forProperty:NSSpeechRateProperty error:nil];
[synth setObject:[NSNumber numberWithInt:aRate * 200] forProperty:NSSpeechRateProperty error:nil];
// volume allows 0.0-1.0
[synth setObject:[NSNumber numberWithFloat:aVolume]
forProperty:NSSpeechVolumeProperty error:nil];
[synth setObject:[NSNumber numberWithFloat:aVolume] forProperty:NSSpeechVolumeProperty error:nil];
// Use default pitch value to calculate this
NSNumber* defaultPitch =
[synth objectForProperty:NSSpeechPitchBaseProperty error:nil];
NSNumber* defaultPitch = [synth objectForProperty:NSSpeechPitchBaseProperty error:nil];
if (defaultPitch) {
int newPitch = [defaultPitch intValue] * (aPitch / 2 + 0.5);
[synth setObject:[NSNumber numberWithInt:newPitch]
forProperty:NSSpeechPitchBaseProperty error:nil];
forProperty:NSSpeechPitchBaseProperty
error:nil];
}
nsAutoString escapedText;
@ -423,8 +367,7 @@ OSXSpeechSynthesizerService::Speak(const nsAString& aText,
// populates the offsets array to supply a map to the original offsets.
for (size_t i = 0; i < aText.Length(); i++) {
if (aText.Length() > i + 1 &&
((aText[i] == ']' && aText[i+1] == ']') ||
(aText[i] == '[' && aText[i+1] == '['))) {
((aText[i] == ']' && aText[i + 1] == ']') || (aText[i] == '[' && aText[i + 1] == '['))) {
escapedText.AppendLiteral(DLIM_ESCAPE_START);
offsets.AppendElements(strlen(DLIM_ESCAPE_START));
escapedText.Append(aText[i]);
@ -455,22 +398,18 @@ OSXSpeechSynthesizerService::Speak(const nsAString& aText,
NS_IMETHODIMP
OSXSpeechSynthesizerService::Observe(nsISupports* aSubject, const char* aTopic,
const char16_t* aData)
{
const char16_t* aData) {
return NS_OK;
}
OSXSpeechSynthesizerService*
OSXSpeechSynthesizerService::GetInstance()
{
OSXSpeechSynthesizerService* OSXSpeechSynthesizerService::GetInstance() {
MOZ_ASSERT(NS_IsMainThread());
if (XRE_GetProcessType() != GeckoProcessType_Default) {
return nullptr;
}
if (!sSingleton) {
RefPtr<OSXSpeechSynthesizerService> speechService =
new OSXSpeechSynthesizerService();
RefPtr<OSXSpeechSynthesizerService> speechService = new OSXSpeechSynthesizerService();
if (speechService->Init()) {
sSingleton = speechService;
}
@ -478,21 +417,17 @@ OSXSpeechSynthesizerService::GetInstance()
return sSingleton;
}
already_AddRefed<OSXSpeechSynthesizerService>
OSXSpeechSynthesizerService::GetInstanceForService()
{
already_AddRefed<OSXSpeechSynthesizerService> OSXSpeechSynthesizerService::GetInstanceForService() {
RefPtr<OSXSpeechSynthesizerService> speechService = GetInstance();
return speechService.forget();
}
void
OSXSpeechSynthesizerService::Shutdown()
{
void OSXSpeechSynthesizerService::Shutdown() {
if (!sSingleton) {
return;
}
sSingleton = nullptr;
}
} // namespace dom
} // namespace mozilla
} // namespace dom
} // namespace mozilla

View File

@ -47,19 +47,13 @@ int32_t NSCursorInfo::mNativeCursorsSupported = -1;
// This constructor may be called from the browser process or the plugin
// process.
NSCursorInfo::NSCursorInfo()
: mType(TypeArrow)
, mHotSpot(nsPoint(0, 0))
, mCustomImageData(NULL)
, mCustomImageDataLength(0)
{
}
: mType(TypeArrow),
mHotSpot(nsPoint(0, 0)),
mCustomImageData(NULL),
mCustomImageDataLength(0) {}
NSCursorInfo::NSCursorInfo(NSCursor* aCursor)
: mType(TypeArrow)
, mHotSpot(nsPoint(0, 0))
, mCustomImageData(NULL)
, mCustomImageDataLength(0)
{
: mType(TypeArrow), mHotSpot(nsPoint(0, 0)), mCustomImageData(NULL), mCustomImageDataLength(0) {
// This constructor is only ever called from the plugin process, so the
// following is safe.
if (!GetNativeCursorsSupported()) {
@ -96,7 +90,7 @@ NSCursorInfo::NSCursorInfo(NSCursor* aCursor)
mType = TypeResizeUp;
} else if ([aCursor isEqual:[NSCursor resizeUpDownCursor]]) {
mType = TypeResizeUpDown;
// The following cursor types are only supported on OS X 10.6 and up.
// The following cursor types are only supported on OS X 10.6 and up.
} else if ([nsCursorClass respondsToSelector:@selector(contextualMenuCursor)] &&
[aCursor isEqual:[nsCursorClass performSelector:@selector(contextualMenuCursor)]]) {
mType = TypeContextualMenu;
@ -107,7 +101,8 @@ NSCursorInfo::NSCursorInfo(NSCursor* aCursor)
[aCursor isEqual:[nsCursorClass performSelector:@selector(dragLinkCursor)]]) {
mType = TypeDragLink;
} else if ([nsCursorClass respondsToSelector:@selector(operationNotAllowedCursor)] &&
[aCursor isEqual:[nsCursorClass performSelector:@selector(operationNotAllowedCursor)]]) {
[aCursor
isEqual:[nsCursorClass performSelector:@selector(operationNotAllowedCursor)]]) {
mType = TypeNotAllowed;
} else {
NSImage* image = [aCursor image];
@ -132,15 +127,13 @@ NSCursorInfo::NSCursorInfo(NSCursor* aCursor)
if (cgImage) {
CFMutableDataRef data = ::CFDataCreateMutable(kCFAllocatorDefault, 0);
if (data) {
CGImageDestinationRef dest = ::CGImageDestinationCreateWithData(data,
kUTTypePNG,
1,
NULL);
CGImageDestinationRef dest =
::CGImageDestinationCreateWithData(data, kUTTypePNG, 1, NULL);
if (dest) {
::CGImageDestinationAddImage(dest, cgImage, NULL);
if (::CGImageDestinationFinalize(dest)) {
uint32_t dataLength = (uint32_t) ::CFDataGetLength(data);
mCustomImageData = (uint8_t*) moz_xmalloc(dataLength);
uint32_t dataLength = (uint32_t)::CFDataGetLength(data);
mCustomImageData = (uint8_t*)moz_xmalloc(dataLength);
::CFDataGetBytes(data, ::CFRangeMake(0, dataLength), mCustomImageData);
mCustomImageDataLength = dataLength;
mType = TypeCustom;
@ -158,11 +151,7 @@ NSCursorInfo::NSCursorInfo(NSCursor* aCursor)
}
NSCursorInfo::NSCursorInfo(const Cursor* aCursor)
: mType(TypeArrow)
, mHotSpot(nsPoint(0, 0))
, mCustomImageData(NULL)
, mCustomImageDataLength(0)
{
: mType(TypeArrow), mHotSpot(nsPoint(0, 0)), mCustomImageData(NULL), mCustomImageDataLength(0) {
// This constructor is only ever called from the plugin process, so the
// following is safe.
if (!GetNativeCursorsSupported()) {
@ -178,7 +167,7 @@ NSCursorInfo::NSCursorInfo(const Cursor* aCursor)
bool isTransparent = true;
uint8_t* bitmap = (uint8_t*) moz_xmalloc(bitmapSize);
uint8_t* bitmap = (uint8_t*)moz_xmalloc(bitmapSize);
// The way we create 'bitmap' is largely "borrowed" from Chrome's
// WebCursor::InitFromCursor().
for (int y = 0; y < height; ++y) {
@ -195,11 +184,11 @@ NSCursorInfo::NSCursorInfo(const Cursor* aCursor)
int offset = (y * rowBytes) + (x * bytesPerPixel);
// Color value
if (data & 0x8000) {
bitmap[offset] = 0x0;
bitmap[offset] = 0x0;
bitmap[offset + 1] = 0x0;
bitmap[offset + 2] = 0x0;
} else {
bitmap[offset] = 0xFF;
bitmap[offset] = 0xFF;
bitmap[offset + 1] = 0xFF;
bitmap[offset + 2] = 0xFF;
}
@ -223,32 +212,21 @@ NSCursorInfo::NSCursorInfo(const Cursor* aCursor)
CGColorSpaceRef color = ::CGColorSpaceCreateDeviceRGB();
if (color) {
CGContextRef context =
::CGBitmapContextCreate(bitmap,
width,
height,
8,
rowBytes,
color,
kCGImageAlphaPremultipliedLast |
kCGBitmapByteOrder32Big);
::CGBitmapContextCreate(bitmap, width, height, 8, rowBytes, color,
kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
if (context) {
CGImageRef image = ::CGBitmapContextCreateImage(context);
if (image) {
::CFMutableDataRef data = ::CFDataCreateMutable(kCFAllocatorDefault, 0);
if (data) {
CGImageDestinationRef dest =
::CGImageDestinationCreateWithData(data,
kUTTypePNG,
1,
NULL);
::CGImageDestinationCreateWithData(data, kUTTypePNG, 1, NULL);
if (dest) {
::CGImageDestinationAddImage(dest, image, NULL);
if (::CGImageDestinationFinalize(dest)) {
uint32_t dataLength = (uint32_t) ::CFDataGetLength(data);
mCustomImageData = (uint8_t*) moz_xmalloc(dataLength);
::CFDataGetBytes(data,
::CFRangeMake(0, dataLength),
mCustomImageData);
uint32_t dataLength = (uint32_t)::CFDataGetLength(data);
mCustomImageData = (uint8_t*)moz_xmalloc(dataLength);
::CFDataGetBytes(data, ::CFRangeMake(0, dataLength), mCustomImageData);
mCustomImageDataLength = dataLength;
mType = TypeCustom;
}
@ -267,19 +245,17 @@ NSCursorInfo::NSCursorInfo(const Cursor* aCursor)
free(bitmap);
}
NSCursorInfo::~NSCursorInfo()
{
NSCursorInfo::~NSCursorInfo() {
if (mCustomImageData) {
free(mCustomImageData);
}
}
NSCursor* NSCursorInfo::GetNSCursor() const
{
NSCursor* NSCursorInfo::GetNSCursor() const {
NSCursor* retval = nil;
Class nsCursorClass = [NSCursor class];
switch(mType) {
switch (mType) {
case TypeArrow:
retval = [NSCursor arrowCursor];
break;
@ -352,24 +328,20 @@ NSCursor* NSCursorInfo::GetNSCursor() const
}
if (!retval && mCustomImageData && mCustomImageDataLength) {
CGDataProviderRef provider = ::CGDataProviderCreateWithData(NULL,
(const void*)mCustomImageData,
mCustomImageDataLength,
NULL);
CGDataProviderRef provider = ::CGDataProviderCreateWithData(NULL, (const void*)mCustomImageData,
mCustomImageDataLength, NULL);
if (provider) {
CGImageRef cgImage = ::CGImageCreateWithPNGDataProvider(provider,
NULL,
false,
kCGRenderingIntentDefault);
CGImageRef cgImage =
::CGImageCreateWithPNGDataProvider(provider, NULL, false, kCGRenderingIntentDefault);
if (cgImage) {
NSBitmapImageRep* rep = [[NSBitmapImageRep alloc] initWithCGImage:cgImage];
if (rep) {
NSImage* image = [[NSImage alloc] init];
if (image) {
[image addRepresentation:rep];
retval = [[[NSCursor alloc] initWithImage:image
hotSpot:NSMakePoint(mHotSpot.x, mHotSpot.y)]
autorelease];
retval =
[[[NSCursor alloc] initWithImage:image
hotSpot:NSMakePoint(mHotSpot.x, mHotSpot.y)] autorelease];
[image release];
}
[rep release];
@ -390,8 +362,7 @@ NSCursor* NSCursorInfo::GetNSCursor() const
// Get a transparent cursor with the appropriate hot spot. We need one if
// (for example) we have a custom cursor with no image data.
NSCursor* NSCursorInfo::GetTransparentCursor() const
{
NSCursor* NSCursorInfo::GetTransparentCursor() const {
NSCursor* retval = nil;
int width = 16, height = 16;
@ -399,40 +370,35 @@ NSCursor* NSCursorInfo::GetTransparentCursor() const
int rowBytes = width * bytesPerPixel;
int dataSize = height * rowBytes;
uint8_t* data = (uint8_t*) moz_xmalloc(dataSize);
uint8_t* data = (uint8_t*)moz_xmalloc(dataSize);
for (int y = 0; y < height; ++y) {
for (int x = 0; x < width; ++x) {
int offset = (y * rowBytes) + (x * bytesPerPixel);
data[offset] = 0x7E; // Arbitrary gray-scale value
data[offset + 1] = 0; // Alpha value to make us transparent
data[offset] = 0x7E; // Arbitrary gray-scale value
data[offset + 1] = 0; // Alpha value to make us transparent
}
}
NSBitmapImageRep* imageRep =
[[[NSBitmapImageRep alloc] initWithBitmapDataPlanes:nil
pixelsWide:width
pixelsHigh:height
bitsPerSample:8
samplesPerPixel:2
hasAlpha:YES
isPlanar:NO
colorSpaceName:NSCalibratedWhiteColorSpace
bytesPerRow:rowBytes
bitsPerPixel:16]
autorelease];
[[[NSBitmapImageRep alloc] initWithBitmapDataPlanes:nil
pixelsWide:width
pixelsHigh:height
bitsPerSample:8
samplesPerPixel:2
hasAlpha:YES
isPlanar:NO
colorSpaceName:NSCalibratedWhiteColorSpace
bytesPerRow:rowBytes
bitsPerPixel:16] autorelease];
if (imageRep) {
uint8_t* repDataPtr = [imageRep bitmapData];
if (repDataPtr) {
memcpy(repDataPtr, data, dataSize);
NSImage *image =
[[[NSImage alloc] initWithSize:NSMakeSize(width, height)]
autorelease];
NSImage* image = [[[NSImage alloc] initWithSize:NSMakeSize(width, height)] autorelease];
if (image) {
[image addRepresentation:imageRep];
retval =
[[[NSCursor alloc] initWithImage:image
hotSpot:NSMakePoint(mHotSpot.x, mHotSpot.y)]
autorelease];
retval = [[[NSCursor alloc] initWithImage:image
hotSpot:NSMakePoint(mHotSpot.x, mHotSpot.y)] autorelease];
}
}
}
@ -447,14 +413,10 @@ NSCursor* NSCursorInfo::GetTransparentCursor() const
return retval;
}
NSCursorInfo::Type NSCursorInfo::GetType() const
{
return mType;
}
NSCursorInfo::Type NSCursorInfo::GetType() const { return mType; }
const char* NSCursorInfo::GetTypeName() const
{
switch(mType) {
const char* NSCursorInfo::GetTypeName() const {
switch (mType) {
case TypeCustom:
return "TypeCustom";
case TypeArrow:
@ -499,38 +461,22 @@ const char* NSCursorInfo::GetTypeName() const
return "TypeUnknown";
}
nsPoint NSCursorInfo::GetHotSpot() const
{
return mHotSpot;
}
nsPoint NSCursorInfo::GetHotSpot() const { return mHotSpot; }
uint8_t* NSCursorInfo::GetCustomImageData() const
{
return mCustomImageData;
}
uint8_t* NSCursorInfo::GetCustomImageData() const { return mCustomImageData; }
uint32_t NSCursorInfo::GetCustomImageDataLength() const
{
return mCustomImageDataLength;
}
uint32_t NSCursorInfo::GetCustomImageDataLength() const { return mCustomImageDataLength; }
void NSCursorInfo::SetType(Type aType)
{
mType = aType;
}
void NSCursorInfo::SetType(Type aType) { mType = aType; }
void NSCursorInfo::SetHotSpot(nsPoint aHotSpot)
{
mHotSpot = aHotSpot;
}
void NSCursorInfo::SetHotSpot(nsPoint aHotSpot) { mHotSpot = aHotSpot; }
void NSCursorInfo::SetCustomImageData(uint8_t* aData, uint32_t aDataLength)
{
void NSCursorInfo::SetCustomImageData(uint8_t* aData, uint32_t aDataLength) {
if (mCustomImageData) {
free(mCustomImageData);
}
if (aDataLength) {
mCustomImageData = (uint8_t*) moz_xmalloc(aDataLength);
mCustomImageData = (uint8_t*)moz_xmalloc(aDataLength);
memcpy(mCustomImageData, aData, aDataLength);
} else {
mCustomImageData = NULL;
@ -540,11 +486,10 @@ void NSCursorInfo::SetCustomImageData(uint8_t* aData, uint32_t aDataLength)
// This should never be called from the browser process -- only from the
// plugin process.
bool NSCursorInfo::GetNativeCursorsSupported()
{
bool NSCursorInfo::GetNativeCursorsSupported() {
if (mNativeCursorsSupported == -1) {
ENSURE_PLUGIN_THREAD(false);
PluginModuleChild *pmc = PluginModuleChild::GetChrome();
PluginModuleChild* pmc = PluginModuleChild::GetChrome();
if (pmc) {
bool result = pmc->GetNativeCursorsSupported();
if (result) {
@ -557,7 +502,7 @@ bool NSCursorInfo::GetNativeCursorsSupported()
return (mNativeCursorsSupported == 1);
}
} // namespace mac_plugin_interposing
} // namespace mac_plugin_interposing
namespace mac_plugin_interposing {
namespace parent {
@ -569,19 +514,15 @@ std::set<uint32_t> plugin_fullscreen_windows_set_;
// Tracks modal windows currently visible.
std::set<uint32_t> plugin_modal_windows_set_;
void OnPluginShowWindow(uint32_t window_id,
CGRect window_bounds,
bool modal) {
void OnPluginShowWindow(uint32_t window_id, CGRect window_bounds, bool modal) {
plugin_visible_windows_set_.insert(window_id);
if (modal)
plugin_modal_windows_set_.insert(window_id);
if (modal) plugin_modal_windows_set_.insert(window_id);
CGRect main_display_bounds = ::CGDisplayBounds(CGMainDisplayID());
if (CGRectEqualToRect(window_bounds, main_display_bounds) &&
(plugin_fullscreen_windows_set_.find(window_id) ==
plugin_fullscreen_windows_set_.end())) {
(plugin_fullscreen_windows_set_.find(window_id) == plugin_fullscreen_windows_set_.end())) {
plugin_fullscreen_windows_set_.insert(window_id);
nsCocoaUtils::HideOSChromeOnScreen(true);
@ -617,12 +558,10 @@ static void ReleasePluginFullScreen(pid_t plugin_pid) {
void OnPluginHideWindow(uint32_t window_id, pid_t aPluginPid) {
bool had_windows = !plugin_visible_windows_set_.empty();
plugin_visible_windows_set_.erase(window_id);
bool browser_needs_activation = had_windows &&
plugin_visible_windows_set_.empty();
bool browser_needs_activation = had_windows && plugin_visible_windows_set_.empty();
plugin_modal_windows_set_.erase(window_id);
if (plugin_fullscreen_windows_set_.find(window_id) !=
plugin_fullscreen_windows_set_.end()) {
if (plugin_fullscreen_windows_set_.find(window_id) != plugin_fullscreen_windows_set_.end()) {
plugin_fullscreen_windows_set_.erase(window_id);
pid_t plugin_pid = browser_needs_activation ? -1 : aPluginPid;
browser_needs_activation = false;
@ -634,16 +573,14 @@ void OnPluginHideWindow(uint32_t window_id, pid_t aPluginPid) {
}
}
void OnSetCursor(const NSCursorInfo& cursorInfo)
{
void OnSetCursor(const NSCursorInfo& cursorInfo) {
NSCursor* aCursor = cursorInfo.GetNSCursor();
if (aCursor) {
[aCursor set];
}
}
void OnShowCursor(bool show)
{
void OnShowCursor(bool show) {
if (show) {
[NSCursor unhide];
} else {
@ -651,21 +588,17 @@ void OnShowCursor(bool show)
}
}
void OnPushCursor(const NSCursorInfo& cursorInfo)
{
void OnPushCursor(const NSCursorInfo& cursorInfo) {
NSCursor* aCursor = cursorInfo.GetNSCursor();
if (aCursor) {
[aCursor push];
}
}
void OnPopCursor()
{
[NSCursor pop];
}
void OnPopCursor() { [NSCursor pop]; }
} // namespace parent
} // namespace mac_plugin_interposing
} // namespace parent
} // namespace mac_plugin_interposing
namespace mac_plugin_interposing {
namespace child {
@ -674,66 +607,57 @@ namespace child {
// browser process only if the browser is current frontmost.
void FocusPluginProcess() {
ProcessSerialNumber this_process, front_process;
if ((GetCurrentProcess(&this_process) != noErr) ||
(GetFrontProcess(&front_process) != noErr)) {
if ((GetCurrentProcess(&this_process) != noErr) || (GetFrontProcess(&front_process) != noErr)) {
return;
}
Boolean matched = false;
if ((SameProcess(&this_process, &front_process, &matched) == noErr) &&
!matched) {
if ((SameProcess(&this_process, &front_process, &matched) == noErr) && !matched) {
SetFrontProcess(&this_process);
}
}
void NotifyBrowserOfPluginShowWindow(uint32_t window_id, CGRect bounds,
bool modal) {
void NotifyBrowserOfPluginShowWindow(uint32_t window_id, CGRect bounds, bool modal) {
ENSURE_PLUGIN_THREAD_VOID();
PluginModuleChild *pmc = PluginModuleChild::GetChrome();
if (pmc)
pmc->PluginShowWindow(window_id, modal, bounds);
PluginModuleChild* pmc = PluginModuleChild::GetChrome();
if (pmc) pmc->PluginShowWindow(window_id, modal, bounds);
}
void NotifyBrowserOfPluginHideWindow(uint32_t window_id, CGRect bounds) {
ENSURE_PLUGIN_THREAD_VOID();
PluginModuleChild *pmc = PluginModuleChild::GetChrome();
if (pmc)
pmc->PluginHideWindow(window_id);
PluginModuleChild* pmc = PluginModuleChild::GetChrome();
if (pmc) pmc->PluginHideWindow(window_id);
}
void NotifyBrowserOfSetCursor(NSCursorInfo& aCursorInfo)
{
void NotifyBrowserOfSetCursor(NSCursorInfo& aCursorInfo) {
ENSURE_PLUGIN_THREAD_VOID();
PluginModuleChild *pmc = PluginModuleChild::GetChrome();
PluginModuleChild* pmc = PluginModuleChild::GetChrome();
if (pmc) {
pmc->SetCursor(aCursorInfo);
}
}
void NotifyBrowserOfShowCursor(bool show)
{
void NotifyBrowserOfShowCursor(bool show) {
ENSURE_PLUGIN_THREAD_VOID();
PluginModuleChild *pmc = PluginModuleChild::GetChrome();
PluginModuleChild* pmc = PluginModuleChild::GetChrome();
if (pmc) {
pmc->ShowCursor(show);
}
}
void NotifyBrowserOfPushCursor(NSCursorInfo& aCursorInfo)
{
void NotifyBrowserOfPushCursor(NSCursorInfo& aCursorInfo) {
ENSURE_PLUGIN_THREAD_VOID();
PluginModuleChild *pmc = PluginModuleChild::GetChrome();
PluginModuleChild* pmc = PluginModuleChild::GetChrome();
if (pmc) {
pmc->PushCursor(aCursorInfo);
}
}
void NotifyBrowserOfPopCursor()
{
void NotifyBrowserOfPopCursor() {
ENSURE_PLUGIN_THREAD_VOID();
PluginModuleChild *pmc = PluginModuleChild::GetChrome();
PluginModuleChild* pmc = PluginModuleChild::GetChrome();
if (pmc) {
pmc->PopCursor();
}
@ -750,8 +674,7 @@ struct WindowInfo {
};
static void OnPluginWindowClosed(const WindowInfo& window_info) {
if (window_info.window_id == 0)
return;
if (window_info.window_id == 0) return;
mac_plugin_interposing::child::NotifyBrowserOfPluginHideWindow(window_info.window_id,
window_info.bounds);
}
@ -762,20 +685,18 @@ static void OnPluginWindowShown(const WindowInfo& window_info, BOOL is_modal) {
// it in _setWindowNumber instead.
static BOOL s_pending_display_is_modal = NO;
if (window_info.window_id == 0) {
if (is_modal)
s_pending_display_is_modal = YES;
if (is_modal) s_pending_display_is_modal = YES;
return;
}
if (s_pending_display_is_modal) {
is_modal = YES;
s_pending_display_is_modal = NO;
}
mac_plugin_interposing::child::NotifyBrowserOfPluginShowWindow(
window_info.window_id, window_info.bounds, is_modal);
mac_plugin_interposing::child::NotifyBrowserOfPluginShowWindow(window_info.window_id,
window_info.bounds, is_modal);
}
static BOOL OnSetCursor(NSCursorInfo &aInfo)
{
static BOOL OnSetCursor(NSCursorInfo& aInfo) {
if (NSCursorInfo::GetNativeCursorsSupported()) {
NotifyBrowserOfSetCursor(aInfo);
return YES;
@ -783,8 +704,7 @@ static BOOL OnSetCursor(NSCursorInfo &aInfo)
return NO;
}
static BOOL OnHideCursor()
{
static BOOL OnHideCursor() {
if (NSCursorInfo::GetNativeCursorsSupported()) {
NotifyBrowserOfShowCursor(NO);
return YES;
@ -792,8 +712,7 @@ static BOOL OnHideCursor()
return NO;
}
static BOOL OnUnhideCursor()
{
static BOOL OnUnhideCursor() {
if (NSCursorInfo::GetNativeCursorsSupported()) {
NotifyBrowserOfShowCursor(YES);
return YES;
@ -801,8 +720,7 @@ static BOOL OnUnhideCursor()
return NO;
}
static BOOL OnPushCursor(NSCursorInfo &aInfo)
{
static BOOL OnPushCursor(NSCursorInfo& aInfo) {
if (NSCursorInfo::GetNativeCursorsSupported()) {
NotifyBrowserOfPushCursor(aInfo);
return YES;
@ -810,8 +728,7 @@ static BOOL OnPushCursor(NSCursorInfo &aInfo)
return NO;
}
static BOOL OnPopCursor()
{
static BOOL OnPopCursor() {
if (NSCursorInfo::GetNativeCursorsSupported()) {
NotifyBrowserOfPopCursor();
return YES;
@ -819,8 +736,8 @@ static BOOL OnPopCursor()
return NO;
}
} // namespace child
} // namespace mac_plugin_interposing
} // namespace child
} // namespace mac_plugin_interposing
using namespace mac_plugin_interposing::child;
@ -852,11 +769,9 @@ using namespace mac_plugin_interposing::child;
}
- (void)pluginInterpose_setWindowNumber:(NSInteger)num {
if (num > 0)
mac_plugin_interposing::child::FocusPluginProcess();
if (num > 0) mac_plugin_interposing::child::FocusPluginProcess();
[self pluginInterpose_setWindowNumber:num];
if (num > 0)
OnPluginWindowShown(WindowInfo(self), NO);
if (num > 0) OnPluginWindowShown(WindowInfo(self), NO);
}
@end
@ -895,25 +810,20 @@ using namespace mac_plugin_interposing::child;
// The last element is always the current cursor.
static NSMutableArray* gCursorStack = nil;
static BOOL initCursorStack()
{
static BOOL initCursorStack() {
if (!gCursorStack) {
gCursorStack = [[NSMutableArray arrayWithCapacity:5] retain];
}
return (gCursorStack != NULL);
}
static NSCursor* currentCursorFromCache()
{
if (!initCursorStack())
return nil;
return (NSCursor*) [gCursorStack lastObject];
static NSCursor* currentCursorFromCache() {
if (!initCursorStack()) return nil;
return (NSCursor*)[gCursorStack lastObject];
}
static void setCursorInCache(NSCursor* aCursor)
{
if (!initCursorStack() || !aCursor)
return;
static void setCursorInCache(NSCursor* aCursor) {
if (!initCursorStack() || !aCursor) return;
NSUInteger count = [gCursorStack count];
if (count) {
[gCursorStack replaceObjectAtIndex:count - 1 withObject:aCursor];
@ -922,17 +832,13 @@ static void setCursorInCache(NSCursor* aCursor)
}
}
static void pushCursorInCache(NSCursor* aCursor)
{
if (!initCursorStack() || !aCursor)
return;
static void pushCursorInCache(NSCursor* aCursor) {
if (!initCursorStack() || !aCursor) return;
[gCursorStack addObject:aCursor];
}
static void popCursorInCache()
{
if (!initCursorStack())
return;
static void popCursorInCache() {
if (!initCursorStack()) return;
// Apple's doc on the +[NSCursor pop] method says: "If the current cursor
// is the only cursor on the stack, this method does nothing."
if ([gCursorStack count] > 1) {
@ -942,24 +848,21 @@ static void popCursorInCache()
@implementation NSCursor (PluginInterposing)
- (void)pluginInterpose_set
{
- (void)pluginInterpose_set {
NSCursorInfo info(self);
OnSetCursor(info);
setCursorInCache(self);
[self pluginInterpose_set];
}
- (void)pluginInterpose_push
{
- (void)pluginInterpose_push {
NSCursorInfo info(self);
OnPushCursor(info);
pushCursorInCache(self);
[self pluginInterpose_push];
}
- (void)pluginInterpose_pop
{
- (void)pluginInterpose_pop {
OnPopCursor();
popCursorInCache();
[self pluginInterpose_pop];
@ -972,8 +875,7 @@ static void popCursorInCache()
// currentCursor "only returns the cursor set by your application using
// NSCursor methods". So we don't need to worry about changes to the cursor
// made by other methods like SetThemeCursor().
+ (NSCursor*)pluginInterpose_currentCursor
{
+ (NSCursor*)pluginInterpose_currentCursor {
NSCursor* retval = [self pluginInterpose_currentCursor];
if (!retval) {
retval = currentCursorFromCache();
@ -981,20 +883,17 @@ static void popCursorInCache()
return retval;
}
+ (void)pluginInterpose_hide
{
+ (void)pluginInterpose_hide {
OnHideCursor();
[self pluginInterpose_hide];
}
+ (void)pluginInterpose_unhide
{
+ (void)pluginInterpose_unhide {
OnUnhideCursor();
[self pluginInterpose_unhide];
}
+ (void)pluginInterpose_pop
{
+ (void)pluginInterpose_pop {
OnPopCursor();
popCursorInCache();
[self pluginInterpose_pop];
@ -1002,10 +901,7 @@ static void popCursorInCache()
@end
static void ExchangeMethods(Class target_class,
BOOL class_method,
SEL original,
SEL replacement) {
static void ExchangeMethods(Class target_class, BOOL class_method, SEL original, SEL replacement) {
Method m1;
Method m2;
if (class_method) {
@ -1016,8 +912,7 @@ static void ExchangeMethods(Class target_class,
m2 = class_getInstanceMethod(target_class, replacement);
}
if (m1 == m2)
return;
if (m1 == m2) return;
if (m1 && m2)
method_exchangeImplementations(m1, m2);
@ -1030,8 +925,7 @@ namespace child {
void SetUpCocoaInterposing() {
Class nswindow_class = [NSWindow class];
ExchangeMethods(nswindow_class, NO, @selector(orderOut:),
@selector(pluginInterpose_orderOut:));
ExchangeMethods(nswindow_class, NO, @selector(orderOut:), @selector(pluginInterpose_orderOut:));
ExchangeMethods(nswindow_class, NO, @selector(orderFront:),
@selector(pluginInterpose_orderFront:));
ExchangeMethods(nswindow_class, NO, @selector(makeKeyAndOrderFront:),
@ -1043,20 +937,14 @@ void SetUpCocoaInterposing() {
@selector(pluginInterpose_runModalForWindow:));
Class nscursor_class = [NSCursor class];
ExchangeMethods(nscursor_class, NO, @selector(set),
@selector(pluginInterpose_set));
ExchangeMethods(nscursor_class, NO, @selector(push),
@selector(pluginInterpose_push));
ExchangeMethods(nscursor_class, NO, @selector(pop),
@selector(pluginInterpose_pop));
ExchangeMethods(nscursor_class, NO, @selector(set), @selector(pluginInterpose_set));
ExchangeMethods(nscursor_class, NO, @selector(push), @selector(pluginInterpose_push));
ExchangeMethods(nscursor_class, NO, @selector(pop), @selector(pluginInterpose_pop));
ExchangeMethods(nscursor_class, YES, @selector(currentCursor),
@selector(pluginInterpose_currentCursor));
ExchangeMethods(nscursor_class, YES, @selector(hide),
@selector(pluginInterpose_hide));
ExchangeMethods(nscursor_class, YES, @selector(unhide),
@selector(pluginInterpose_unhide));
ExchangeMethods(nscursor_class, YES, @selector(pop),
@selector(pluginInterpose_pop));
ExchangeMethods(nscursor_class, YES, @selector(hide), @selector(pluginInterpose_hide));
ExchangeMethods(nscursor_class, YES, @selector(unhide), @selector(pluginInterpose_unhide));
ExchangeMethods(nscursor_class, YES, @selector(pop), @selector(pluginInterpose_pop));
}
} // namespace child
@ -1065,8 +953,7 @@ void SetUpCocoaInterposing() {
// Called from plugin_child_interpose.mm, which hooks calls to
// SetCursor() (the QuickDraw call) from the plugin child process.
extern "C" NS_VISIBILITY_DEFAULT BOOL
mac_plugin_interposing_child_OnSetCursor(const Cursor* cursor)
{
mac_plugin_interposing_child_OnSetCursor(const Cursor* cursor) {
NSCursorInfo info(cursor);
return OnSetCursor(info);
}
@ -1075,8 +962,7 @@ mac_plugin_interposing_child_OnSetCursor(const Cursor* cursor)
// SetThemeCursor() (the Appearance Manager call) from the plugin child
// process.
extern "C" NS_VISIBILITY_DEFAULT BOOL
mac_plugin_interposing_child_OnSetThemeCursor(ThemeCursor cursor)
{
mac_plugin_interposing_child_OnSetThemeCursor(ThemeCursor cursor) {
NSCursorInfo info;
switch (cursor) {
case kThemeArrowCursor:
@ -1145,14 +1031,10 @@ mac_plugin_interposing_child_OnSetThemeCursor(ThemeCursor cursor)
return OnSetCursor(info);
}
extern "C" NS_VISIBILITY_DEFAULT BOOL
mac_plugin_interposing_child_OnHideCursor()
{
extern "C" NS_VISIBILITY_DEFAULT BOOL mac_plugin_interposing_child_OnHideCursor() {
return OnHideCursor();
}
extern "C" NS_VISIBILITY_DEFAULT BOOL
mac_plugin_interposing_child_OnShowCursor()
{
extern "C" NS_VISIBILITY_DEFAULT BOOL mac_plugin_interposing_child_OnShowCursor() {
return OnUnhideCursor();
}

View File

@ -26,11 +26,10 @@ using namespace mozilla::plugins::PluginUtilsOSX;
@interface CGBridgeLayer : CALayer {
DrawPluginFunc mDrawFunc;
void* mPluginInstance;
void *mPluginInstance;
nsIntRect mUpdateRect;
}
- (void)setDrawFunc:(DrawPluginFunc)aFunc
pluginInstance:(void*)aPluginInstance;
- (void)setDrawFunc:(DrawPluginFunc)aFunc pluginInstance:(void *)aPluginInstance;
- (void)updateRect:(nsIntRect)aRect;
@end
@ -40,35 +39,25 @@ using namespace mozilla::plugins::PluginUtilsOSX;
// it's used to replace the "data" in a bitmap context that was
// originally specified in a call to CGBitmapContextCreate() or
// CGBitmapContextCreateWithData().
typedef void (*CGBitmapContextSetDataFunc) (CGContextRef c,
size_t x,
size_t y,
size_t width,
size_t height,
void* data,
size_t bitsPerComponent,
size_t bitsPerPixel,
size_t bytesPerRow);
typedef void (*CGBitmapContextSetDataFunc)(CGContextRef c, size_t x, size_t y, size_t width,
size_t height, void *data, size_t bitsPerComponent,
size_t bitsPerPixel, size_t bytesPerRow);
CGBitmapContextSetDataFunc CGBitmapContextSetDataPtr = NULL;
@implementation CGBridgeLayer
- (void) updateRect:(nsIntRect)aRect
{
mUpdateRect.UnionRect(mUpdateRect, aRect);
- (void)updateRect:(nsIntRect)aRect {
mUpdateRect.UnionRect(mUpdateRect, aRect);
}
- (void) setDrawFunc:(DrawPluginFunc)aFunc
pluginInstance:(void*)aPluginInstance
{
- (void)setDrawFunc:(DrawPluginFunc)aFunc pluginInstance:(void *)aPluginInstance {
mDrawFunc = aFunc;
mPluginInstance = aPluginInstance;
}
- (void)drawInContext:(CGContextRef)aCGContext
{
::CGContextSaveGState(aCGContext);
- (void)drawInContext:(CGContextRef)aCGContext {
::CGContextSaveGState(aCGContext);
::CGContextTranslateCTM(aCGContext, 0, self.bounds.size.height);
::CGContextScaleCTM(aCGContext, (CGFloat) 1, (CGFloat) -1);
::CGContextScaleCTM(aCGContext, (CGFloat)1, (CGFloat)-1);
mUpdateRect = nsIntRect::Truncate(0, 0, self.bounds.size.width, self.bounds.size.height);
@ -81,8 +70,7 @@ CGBitmapContextSetDataFunc CGBitmapContextSetDataPtr = NULL;
@end
void* mozilla::plugins::PluginUtilsOSX::GetCGLayer(DrawPluginFunc aFunc,
void* aPluginInstance,
void *mozilla::plugins::PluginUtilsOSX::GetCGLayer(DrawPluginFunc aFunc, void *aPluginInstance,
double aContentsScaleFactor) {
CGBridgeLayer *bridgeLayer = [[CGBridgeLayer alloc] init];
@ -91,12 +79,9 @@ void* mozilla::plugins::PluginUtilsOSX::GetCGLayer(DrawPluginFunc aFunc,
bridgeLayer.autoresizingMask = kCALayerWidthSizable | kCALayerHeightSizable;
bridgeLayer.needsDisplayOnBoundsChange = YES;
NSNull *nullValue = [NSNull null];
NSDictionary *actions = [NSDictionary dictionaryWithObjectsAndKeys:
nullValue, @"bounds",
nullValue, @"contents",
nullValue, @"contentsRect",
nullValue, @"position",
nil];
NSDictionary *actions = [NSDictionary
dictionaryWithObjectsAndKeys:nullValue, @"bounds", nullValue, @"contents", nullValue,
@"contentsRect", nullValue, @"position", nil];
[bridgeLayer setStyle:[NSDictionary dictionaryWithObject:actions forKey:@"actions"]];
// For reasons that aren't clear (perhaps one or more OS bugs), we can only
@ -105,25 +90,23 @@ void* mozilla::plugins::PluginUtilsOSX::GetCGLayer(DrawPluginFunc aFunc,
// of bridgeLayer (even to the same value) causes it to stop working (go
// blank). This doesn't happen with objects that are members of the CALayer
// class (as opposed to one of its subclasses).
#if defined(MAC_OS_X_VERSION_10_7) && \
MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
#if defined(MAC_OS_X_VERSION_10_7) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
if ([bridgeLayer respondsToSelector:@selector(setContentsScale:)]) {
bridgeLayer.contentsScale = aContentsScaleFactor;
}
#endif
[bridgeLayer setDrawFunc:aFunc
pluginInstance:aPluginInstance];
[bridgeLayer setDrawFunc:aFunc pluginInstance:aPluginInstance];
return bridgeLayer;
}
void mozilla::plugins::PluginUtilsOSX::ReleaseCGLayer(void *cgLayer) {
CGBridgeLayer *bridgeLayer = (CGBridgeLayer*)cgLayer;
CGBridgeLayer *bridgeLayer = (CGBridgeLayer *)cgLayer;
[bridgeLayer release];
}
void mozilla::plugins::PluginUtilsOSX::Repaint(void *caLayer, nsIntRect aRect) {
CGBridgeLayer *bridgeLayer = (CGBridgeLayer*)caLayer;
CGBridgeLayer *bridgeLayer = (CGBridgeLayer *)caLayer;
[CATransaction begin];
[bridgeLayer updateRect:aRect];
[bridgeLayer setNeedsDisplay];
@ -132,30 +115,29 @@ void mozilla::plugins::PluginUtilsOSX::Repaint(void *caLayer, nsIntRect aRect) {
}
@interface EventProcessor : NSObject {
RemoteProcessEvents aRemoteEvents;
void *aPluginModule;
RemoteProcessEvents aRemoteEvents;
void *aPluginModule;
}
- (void)setRemoteEvents:(RemoteProcessEvents) remoteEvents pluginModule:(void*) pluginModule;
- (void)setRemoteEvents:(RemoteProcessEvents)remoteEvents pluginModule:(void *)pluginModule;
- (void)onTick;
@end
@implementation EventProcessor
- (void) onTick
{
aRemoteEvents(aPluginModule);
- (void)onTick {
aRemoteEvents(aPluginModule);
}
- (void)setRemoteEvents:(RemoteProcessEvents) remoteEvents pluginModule:(void*) pluginModule
{
aRemoteEvents = remoteEvents;
aPluginModule = pluginModule;
- (void)setRemoteEvents:(RemoteProcessEvents)remoteEvents pluginModule:(void *)pluginModule {
aRemoteEvents = remoteEvents;
aPluginModule = pluginModule;
}
@end
#define EVENT_PROCESS_DELAY 0.05 // 50 ms
#define EVENT_PROCESS_DELAY 0.05 // 50 ms
NPError mozilla::plugins::PluginUtilsOSX::ShowCocoaContextMenu(void* aMenu, int aX, int aY, void* pluginModule, RemoteProcessEvents remoteEvent)
{
NPError mozilla::plugins::PluginUtilsOSX::ShowCocoaContextMenu(void *aMenu, int aX, int aY,
void *pluginModule,
RemoteProcessEvents remoteEvent) {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
// Set the native cursor to the OS default (an arrow) before displaying the
@ -166,7 +148,7 @@ NPError mozilla::plugins::PluginUtilsOSX::ShowCocoaContextMenu(void* aMenu, int
// change to an arrow cursor automatically -- as it does in Chrome.
[[NSCursor arrowCursor] set];
EventProcessor* eventProcessor = nullptr;
EventProcessor *eventProcessor = nullptr;
NSTimer *eventTimer = nullptr;
if (pluginModule) {
// Create a timer to process browser events while waiting
@ -175,15 +157,16 @@ NPError mozilla::plugins::PluginUtilsOSX::ShowCocoaContextMenu(void* aMenu, int
eventProcessor = [[EventProcessor alloc] init];
[eventProcessor setRemoteEvents:remoteEvent pluginModule:pluginModule];
eventTimer = [NSTimer timerWithTimeInterval:EVENT_PROCESS_DELAY
target:eventProcessor selector:@selector(onTick)
userInfo:nil repeats:TRUE];
target:eventProcessor
selector:@selector(onTick)
userInfo:nil
repeats:TRUE];
// Use NSEventTrackingRunLoopMode otherwise the timer will
// not fire during the right click menu.
[[NSRunLoop currentRunLoop] addTimer:eventTimer
forMode:NSEventTrackingRunLoopMode];
[[NSRunLoop currentRunLoop] addTimer:eventTimer forMode:NSEventTrackingRunLoopMode];
}
NSMenu* nsmenu = reinterpret_cast<NSMenu*>(aMenu);
NSMenu *nsmenu = reinterpret_cast<NSMenu *>(aMenu);
NSPoint screen_point = ::NSMakePoint(aX, aY);
[nsmenu popUpMenuPositioningItem:nil atLocation:screen_point inView:nil];
@ -198,25 +181,23 @@ NPError mozilla::plugins::PluginUtilsOSX::ShowCocoaContextMenu(void* aMenu, int
NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(NPERR_GENERIC_ERROR);
}
void mozilla::plugins::PluginUtilsOSX::InvokeNativeEventLoop()
{
void mozilla::plugins::PluginUtilsOSX::InvokeNativeEventLoop() {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
::CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.0, true);
NS_OBJC_END_TRY_ABORT_BLOCK;
}
#define UNDOCUMENTED_SESSION_CONSTANT ((int)-2)
namespace mozilla {
namespace plugins {
namespace PluginUtilsOSX {
static void *sApplicationASN = NULL;
static void *sApplicationInfoItem = NULL;
} // namespace PluginUtilsOSX
} // namespace plugins
} // namespace mozilla
static void *sApplicationASN = NULL;
static void *sApplicationInfoItem = NULL;
} // namespace PluginUtilsOSX
} // namespace plugins
} // namespace mozilla
bool mozilla::plugins::PluginUtilsOSX::SetProcessName(const char* aProcessName) {
bool mozilla::plugins::PluginUtilsOSX::SetProcessName(const char *aProcessName) {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
nsAutoreleasePool localPool;
@ -224,8 +205,8 @@ bool mozilla::plugins::PluginUtilsOSX::SetProcessName(const char* aProcessName)
return false;
}
NSString *currentName = [[[NSBundle mainBundle] localizedInfoDictionary]
objectForKey:(NSString *)kCFBundleNameKey];
NSString *currentName =
[[[NSBundle mainBundle] localizedInfoDictionary] objectForKey:(NSString *)kCFBundleNameKey];
char formattedName[1024];
SprintfLiteral(formattedName, "%s %s", [currentName UTF8String], aProcessName);
@ -234,21 +215,18 @@ bool mozilla::plugins::PluginUtilsOSX::SetProcessName(const char* aProcessName)
// This function is based on Chrome/Webkit's and relies on potentially dangerous SPI.
typedef CFTypeRef (*LSGetASNType)();
typedef OSStatus (*LSSetInformationItemType)(int, CFTypeRef,
CFStringRef,
CFStringRef,
CFDictionaryRef*);
typedef OSStatus (*LSSetInformationItemType)(int, CFTypeRef, CFStringRef, CFStringRef,
CFDictionaryRef *);
CFBundleRef launchServices = ::CFBundleGetBundleWithIdentifier(
CFSTR("com.apple.LaunchServices"));
CFBundleRef launchServices = ::CFBundleGetBundleWithIdentifier(CFSTR("com.apple.LaunchServices"));
if (!launchServices) {
NS_WARNING("Failed to set process name: Could not open LaunchServices bundle");
return false;
}
if (!sApplicationASN) {
sApplicationASN = ::CFBundleGetFunctionPointerForName(launchServices,
CFSTR("_LSGetCurrentApplicationASN"));
sApplicationASN =
::CFBundleGetFunctionPointerForName(launchServices, CFSTR("_LSGetCurrentApplicationASN"));
if (!sApplicationASN) {
NS_WARNING("Failed to set process name: Could not get function pointer "
"for LaunchServices");
@ -256,24 +234,22 @@ bool mozilla::plugins::PluginUtilsOSX::SetProcessName(const char* aProcessName)
}
}
LSGetASNType getASNFunc = reinterpret_cast<LSGetASNType>
(sApplicationASN);
LSGetASNType getASNFunc = reinterpret_cast<LSGetASNType>(sApplicationASN);
if (!sApplicationInfoItem) {
sApplicationInfoItem = ::CFBundleGetFunctionPointerForName(launchServices,
CFSTR("_LSSetApplicationInformationItem"));
sApplicationInfoItem = ::CFBundleGetFunctionPointerForName(
launchServices, CFSTR("_LSSetApplicationInformationItem"));
}
LSSetInformationItemType setInformationItemFunc
= reinterpret_cast<LSSetInformationItemType>
(sApplicationInfoItem);
LSSetInformationItemType setInformationItemFunc =
reinterpret_cast<LSSetInformationItemType>(sApplicationInfoItem);
void * displayNameKeyAddr = ::CFBundleGetDataPointerForName(launchServices,
CFSTR("_kLSDisplayNameKey"));
void *displayNameKeyAddr =
::CFBundleGetDataPointerForName(launchServices, CFSTR("_kLSDisplayNameKey"));
CFStringRef displayNameKey = nil;
if (displayNameKeyAddr) {
displayNameKey = reinterpret_cast<CFStringRef>(*(CFStringRef*)displayNameKeyAddr);
displayNameKey = reinterpret_cast<CFStringRef>(*(CFStringRef *)displayNameKeyAddr);
}
// Rename will fail without this
@ -284,23 +260,20 @@ bool mozilla::plugins::PluginUtilsOSX::SetProcessName(const char* aProcessName)
CFTypeRef currentAsn = getASNFunc ? getASNFunc() : nullptr;
if (!getASNFunc || !setInformationItemFunc ||
!displayNameKey || !currentAsn) {
if (!getASNFunc || !setInformationItemFunc || !displayNameKey || !currentAsn) {
NS_WARNING("Failed to set process name: Accessing launchServices failed");
return false;
}
CFStringRef processName = ::CFStringCreateWithCString(nil,
aProcessName,
kCFStringEncodingASCII);
CFStringRef processName = ::CFStringCreateWithCString(nil, aProcessName, kCFStringEncodingASCII);
if (!processName) {
NS_WARNING("Failed to set process name: Could not create CFStringRef");
return false;
}
OSErr err = setInformationItemFunc(UNDOCUMENTED_SESSION_CONSTANT, currentAsn,
displayNameKey, processName,
nil); // Optional out param
OSErr err =
setInformationItemFunc(UNDOCUMENTED_SESSION_CONSTANT, currentAsn, displayNameKey, processName,
nil); // Optional out param
::CFRelease(processName);
if (err != noErr) {
NS_WARNING("Failed to set process name: LSSetInformationItemType err");
@ -371,21 +344,13 @@ IOSurfaceID nsDoubleBufferCARenderer::GetFrontSurfaceID() {
return mFrontSurface->GetIOSurfaceID();
}
bool nsDoubleBufferCARenderer::HasBackSurface() {
return !!mBackSurface;
}
bool nsDoubleBufferCARenderer::HasBackSurface() { return !!mBackSurface; }
bool nsDoubleBufferCARenderer::HasFrontSurface() {
return !!mFrontSurface;
}
bool nsDoubleBufferCARenderer::HasFrontSurface() { return !!mFrontSurface; }
bool nsDoubleBufferCARenderer::HasCALayer() {
return !!mCALayer;
}
bool nsDoubleBufferCARenderer::HasCALayer() { return !!mCALayer; }
void nsDoubleBufferCARenderer::SetCALayer(void *aCALayer) {
mCALayer = aCALayer;
}
void nsDoubleBufferCARenderer::SetCALayer(void *aCALayer) { mCALayer = aCALayer; }
bool nsDoubleBufferCARenderer::InitFrontSurface(size_t aWidth, size_t aHeight,
double aContentsScaleFactor,
@ -410,11 +375,9 @@ bool nsDoubleBufferCARenderer::InitFrontSurface(size_t aWidth, size_t aHeight,
mCARenderer->AttachIOSurface(mFrontSurface);
nsresult result = mCARenderer->SetupRenderer(mCALayer,
mFrontSurface->GetWidth(),
mFrontSurface->GetHeight(),
mContentsScaleFactor,
aAllowOfflineRenderer);
nsresult result =
mCARenderer->SetupRenderer(mCALayer, mFrontSurface->GetWidth(), mFrontSurface->GetHeight(),
mContentsScaleFactor, aAllowOfflineRenderer);
if (result != NS_OK) {
mCARenderer = nullptr;
@ -433,8 +396,8 @@ void nsDoubleBufferCARenderer::Render() {
return;
}
mCARenderer->Render(GetFrontSurfaceWidth(), GetFrontSurfaceHeight(),
mContentsScaleFactor, nullptr);
mCARenderer->Render(GetFrontSurfaceWidth(), GetFrontSurfaceHeight(), mContentsScaleFactor,
nullptr);
}
void nsDoubleBufferCARenderer::SwapSurfaces() {
@ -461,7 +424,6 @@ void nsDoubleBufferCARenderer::ClearBackSurface() {
}
}
} // namespace PluginUtilsOSX
} // namespace plugins
} // namespace mozilla
} // namespace PluginUtilsOSX
} // namespace plugins
} // namespace mozilla

View File

@ -27,63 +27,58 @@
#if !defined(__LP64__)
#include <dlfcn.h>
#import <Carbon/Carbon.h>
# include <dlfcn.h>
# import <Carbon/Carbon.h>
// The header file QuickdrawAPI.h is missing on OS X 10.7 and up (though the
// QuickDraw APIs defined in it are still present) -- so we need to supply the
// relevant parts of its contents here. It's likely that Apple will eventually
// remove the APIs themselves (probably in OS X 10.8), so we need to make them
// weak imports, and test for their presence before using them.
#if !defined(__QUICKDRAWAPI__)
# if !defined(__QUICKDRAWAPI__)
struct Cursor;
extern "C" void SetCursor(const Cursor * crsr) __attribute__((weak_import));
extern "C" void SetCursor(const Cursor* crsr) __attribute__((weak_import));
#endif /* __QUICKDRAWAPI__ */
# endif /* __QUICKDRAWAPI__ */
BOOL (*OnSetThemeCursorPtr) (ThemeCursor) = NULL;
BOOL (*OnSetCursorPtr) (const Cursor*) = NULL;
BOOL (*OnHideCursorPtr) () = NULL;
BOOL (*OnShowCursorPtr) () = NULL;
BOOL (*OnSetThemeCursorPtr)(ThemeCursor) = NULL;
BOOL (*OnSetCursorPtr)(const Cursor*) = NULL;
BOOL (*OnHideCursorPtr)() = NULL;
BOOL (*OnShowCursorPtr)() = NULL;
static BOOL loadXULPtrs()
{
static BOOL loadXULPtrs() {
if (!OnSetThemeCursorPtr) {
// mac_plugin_interposing_child_OnSetThemeCursor(ThemeCursor cursor) is in
// PluginInterposeOSX.mm
OnSetThemeCursorPtr = (BOOL(*)(ThemeCursor))
dlsym(RTLD_DEFAULT, "mac_plugin_interposing_child_OnSetThemeCursor");
OnSetThemeCursorPtr =
(BOOL(*)(ThemeCursor))dlsym(RTLD_DEFAULT, "mac_plugin_interposing_child_OnSetThemeCursor");
}
if (!OnSetCursorPtr) {
// mac_plugin_interposing_child_OnSetCursor(const Cursor* cursor) is in
// PluginInterposeOSX.mm
OnSetCursorPtr = (BOOL(*)(const Cursor*))
dlsym(RTLD_DEFAULT, "mac_plugin_interposing_child_OnSetCursor");
OnSetCursorPtr =
(BOOL(*)(const Cursor*))dlsym(RTLD_DEFAULT, "mac_plugin_interposing_child_OnSetCursor");
}
if (!OnHideCursorPtr) {
// mac_plugin_interposing_child_OnHideCursor() is in PluginInterposeOSX.mm
OnHideCursorPtr = (BOOL(*)())
dlsym(RTLD_DEFAULT, "mac_plugin_interposing_child_OnHideCursor");
OnHideCursorPtr = (BOOL(*)())dlsym(RTLD_DEFAULT, "mac_plugin_interposing_child_OnHideCursor");
}
if (!OnShowCursorPtr) {
// mac_plugin_interposing_child_OnShowCursor() is in PluginInterposeOSX.mm
OnShowCursorPtr = (BOOL(*)())
dlsym(RTLD_DEFAULT, "mac_plugin_interposing_child_OnShowCursor");
OnShowCursorPtr = (BOOL(*)())dlsym(RTLD_DEFAULT, "mac_plugin_interposing_child_OnShowCursor");
}
return (OnSetCursorPtr && OnSetThemeCursorPtr && OnHideCursorPtr && OnShowCursorPtr);
}
static OSStatus MacPluginChildSetThemeCursor(ThemeCursor cursor)
{
static OSStatus MacPluginChildSetThemeCursor(ThemeCursor cursor) {
if (loadXULPtrs()) {
OnSetThemeCursorPtr(cursor);
}
return ::SetThemeCursor(cursor);
}
static void MacPluginChildSetCursor(const Cursor* cursor)
{
static void MacPluginChildSetCursor(const Cursor* cursor) {
if (::SetCursor) {
if (loadXULPtrs()) {
OnSetCursorPtr(cursor);
@ -92,43 +87,43 @@ static void MacPluginChildSetCursor(const Cursor* cursor)
}
}
static CGError MacPluginChildCGDisplayHideCursor(CGDirectDisplayID display)
{
static CGError MacPluginChildCGDisplayHideCursor(CGDirectDisplayID display) {
if (loadXULPtrs()) {
OnHideCursorPtr();
}
return ::CGDisplayHideCursor(display);
}
static CGError MacPluginChildCGDisplayShowCursor(CGDirectDisplayID display)
{
static CGError MacPluginChildCGDisplayShowCursor(CGDirectDisplayID display) {
if (loadXULPtrs()) {
OnShowCursorPtr();
}
return ::CGDisplayShowCursor(display);
}
#pragma mark -
# pragma mark -
struct interpose_substitution {
const void* replacement;
const void* original;
};
#define INTERPOSE_FUNCTION(function) \
{ reinterpret_cast<const void*>(MacPluginChild##function), \
reinterpret_cast<const void*>(function) }
# define INTERPOSE_FUNCTION(function) \
{ \
reinterpret_cast<const void*>(MacPluginChild##function), \
reinterpret_cast<const void*>(function) \
}
__attribute__((used)) static const interpose_substitution substitutions[]
__attribute__((section("__DATA, __interpose"))) = {
INTERPOSE_FUNCTION(SetThemeCursor),
INTERPOSE_FUNCTION(CGDisplayHideCursor),
INTERPOSE_FUNCTION(CGDisplayShowCursor),
// SetCursor() and other QuickDraw APIs will probably be removed in OS X
// 10.8. But this will make 'SetCursor' NULL, which will just stop the OS
// from interposing it (tested using an INTERPOSE_FUNCTION_BROKEN macro
// that just sets the second address of each tuple to NULL).
INTERPOSE_FUNCTION(SetCursor),
INTERPOSE_FUNCTION(SetThemeCursor),
INTERPOSE_FUNCTION(CGDisplayHideCursor),
INTERPOSE_FUNCTION(CGDisplayShowCursor),
// SetCursor() and other QuickDraw APIs will probably be removed in OS X
// 10.8. But this will make 'SetCursor' NULL, which will just stop the OS
// from interposing it (tested using an INTERPOSE_FUNCTION_BROKEN macro
// that just sets the second address of each tuple to NULL).
INTERPOSE_FUNCTION(SetCursor),
};
#endif // !__LP64__

View File

@ -1,11 +1,11 @@
/* ***** BEGIN LICENSE BLOCK *****
*
*
* Copyright (c) 2008, Mozilla Corporation
* All rights reserved.
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
@ -14,7 +14,7 @@
* * Neither the name of the Mozilla Corporation nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
@ -25,10 +25,10 @@
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
* Contributor(s):
* Josh Aas <josh@mozilla.com>
*
*
* ***** END LICENSE BLOCK ***** */
#include "nptest_platform.h"
@ -38,21 +38,11 @@
using namespace std;
bool
pluginSupportsWindowMode()
{
return false;
}
bool pluginSupportsWindowMode() { return false; }
bool
pluginSupportsWindowlessMode()
{
return true;
}
bool pluginSupportsWindowlessMode() { return true; }
NPError
pluginInstanceInit(InstanceData* instanceData)
{
NPError pluginInstanceInit(InstanceData* instanceData) {
NPP npp = instanceData->npp;
NPBool supportsCoreGraphics = false;
@ -77,28 +67,19 @@ pluginInstanceInit(InstanceData* instanceData)
return NPERR_NO_ERROR;
}
void
pluginInstanceShutdown(InstanceData* instanceData)
{
void pluginInstanceShutdown(InstanceData* instanceData) {}
static bool RectEquals(const NPRect& r1, const NPRect& r2) {
return r1.left == r2.left && r1.top == r2.top && r1.right == r2.right && r1.bottom == r2.bottom;
}
static bool
RectEquals(const NPRect& r1, const NPRect& r2)
{
return r1.left == r2.left && r1.top == r2.top &&
r1.right == r2.right && r1.bottom == r2.bottom;
}
void
pluginDoSetWindow(InstanceData* instanceData, NPWindow* newWindow)
{
void pluginDoSetWindow(InstanceData* instanceData, NPWindow* newWindow) {
// Ugh. Due to a terrible Gecko bug, we have to ignore position changes
// when the clip rect doesn't change; the position can be wrong
// when set by a path other than nsPluginFrame::FixUpPluginWindow.
int32_t oldX = instanceData->window.x;
int32_t oldY = instanceData->window.y;
bool clipChanged =
!RectEquals(instanceData->window.clipRect, newWindow->clipRect);
bool clipChanged = !RectEquals(instanceData->window.clipRect, newWindow->clipRect);
instanceData->window = *newWindow;
if (!clipChanged) {
instanceData->window.x = oldX;
@ -106,36 +87,27 @@ pluginDoSetWindow(InstanceData* instanceData, NPWindow* newWindow)
}
}
void
pluginWidgetInit(InstanceData* instanceData, void* oldWindow)
{
void pluginWidgetInit(InstanceData* instanceData, void* oldWindow) {
// Should never be called since we don't support window mode
}
static void
GetColorsFromRGBA(uint32_t rgba, float* r, float* g, float* b, float* a)
{
static void GetColorsFromRGBA(uint32_t rgba, float* r, float* g, float* b, float* a) {
*b = (rgba & 0xFF) / 255.0;
*g = ((rgba & 0xFF00) >> 8) / 255.0;
*r = ((rgba & 0xFF0000) >> 16) / 255.0;
*a = ((rgba & 0xFF000000) >> 24) / 255.0;
}
static void
pluginDraw(InstanceData* instanceData, NPCocoaEvent* event)
{
if (!instanceData)
return;
static void pluginDraw(InstanceData* instanceData, NPCocoaEvent* event) {
if (!instanceData) return;
notifyDidPaint(instanceData);
NPP npp = instanceData->npp;
if (!npp)
return;
if (!npp) return;
const char* uaString = NPN_UserAgent(npp);
if (!uaString)
return;
if (!uaString) return;
NPWindow window = instanceData->window;
@ -144,92 +116,92 @@ pluginDraw(InstanceData* instanceData, NPCocoaEvent* event)
float windowWidth = window.width;
float windowHeight = window.height;
switch(instanceData->scriptableObject->drawMode) {
case DM_DEFAULT: {
CFStringRef uaCFString = CFStringCreateWithCString(kCFAllocatorDefault, uaString, kCFStringEncodingASCII);
// save the cgcontext gstate
CGContextSaveGState(cgContext);
switch (instanceData->scriptableObject->drawMode) {
case DM_DEFAULT: {
CFStringRef uaCFString =
CFStringCreateWithCString(kCFAllocatorDefault, uaString, kCFStringEncodingASCII);
// save the cgcontext gstate
CGContextSaveGState(cgContext);
// we get a flipped context
CGContextTranslateCTM(cgContext, 0.0, windowHeight);
CGContextScaleCTM(cgContext, 1.0, -1.0);
// we get a flipped context
CGContextTranslateCTM(cgContext, 0.0, windowHeight);
CGContextScaleCTM(cgContext, 1.0, -1.0);
// draw a gray background for the plugin
CGContextAddRect(cgContext, CGRectMake(0, 0, windowWidth, windowHeight));
CGContextSetGrayFillColor(cgContext, 0.5, 1.0);
CGContextDrawPath(cgContext, kCGPathFill);
// draw a gray background for the plugin
CGContextAddRect(cgContext, CGRectMake(0, 0, windowWidth, windowHeight));
CGContextSetGrayFillColor(cgContext, 0.5, 1.0);
CGContextDrawPath(cgContext, kCGPathFill);
// draw a black frame around the plugin
CGContextAddRect(cgContext, CGRectMake(0, 0, windowWidth, windowHeight));
CGContextSetGrayStrokeColor(cgContext, 0.0, 1.0);
CGContextSetLineWidth(cgContext, 6.0);
CGContextStrokePath(cgContext);
// draw a black frame around the plugin
CGContextAddRect(cgContext, CGRectMake(0, 0, windowWidth, windowHeight));
CGContextSetGrayStrokeColor(cgContext, 0.0, 1.0);
CGContextSetLineWidth(cgContext, 6.0);
CGContextStrokePath(cgContext);
// draw the UA string using Core Text
CGContextSetTextMatrix(cgContext, CGAffineTransformIdentity);
// draw the UA string using Core Text
CGContextSetTextMatrix(cgContext, CGAffineTransformIdentity);
// Initialize a rectangular path.
CGMutablePathRef path = CGPathCreateMutable();
CGRect bounds = CGRectMake(10.0, 10.0, std::max(0.0, windowWidth - 20.0),
std::max(0.0, windowHeight - 20.0));
CGPathAddRect(path, NULL, bounds);
// Initialize a rectangular path.
CGMutablePathRef path = CGPathCreateMutable();
CGRect bounds = CGRectMake(10.0, 10.0, std::max(0.0, windowWidth - 20.0),
std::max(0.0, windowHeight - 20.0));
CGPathAddRect(path, NULL, bounds);
// Initialize an attributed string.
CFMutableAttributedStringRef attrString = CFAttributedStringCreateMutable(kCFAllocatorDefault, 0);
CFAttributedStringReplaceString(attrString, CFRangeMake(0, 0), uaCFString);
// Initialize an attributed string.
CFMutableAttributedStringRef attrString =
CFAttributedStringCreateMutable(kCFAllocatorDefault, 0);
CFAttributedStringReplaceString(attrString, CFRangeMake(0, 0), uaCFString);
// Create a color and add it as an attribute to the string.
CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB();
CGFloat components[] = { 0.0, 0.0, 0.0, 1.0 };
CGColorRef red = CGColorCreate(rgbColorSpace, components);
CGColorSpaceRelease(rgbColorSpace);
CFAttributedStringSetAttribute(attrString, CFRangeMake(0, 50), kCTForegroundColorAttributeName, red);
// Create a color and add it as an attribute to the string.
CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB();
CGFloat components[] = {0.0, 0.0, 0.0, 1.0};
CGColorRef red = CGColorCreate(rgbColorSpace, components);
CGColorSpaceRelease(rgbColorSpace);
CFAttributedStringSetAttribute(attrString, CFRangeMake(0, 50),
kCTForegroundColorAttributeName, red);
// Create the framesetter with the attributed string.
CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString(attrString);
CFRelease(attrString);
// Create the framesetter with the attributed string.
CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString(attrString);
CFRelease(attrString);
// Create the frame and draw it into the graphics context
CTFrameRef frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, 0), path, NULL);
CFRelease(framesetter);
if (frame) {
CTFrameDraw(frame, cgContext);
CFRelease(frame);
// Create the frame and draw it into the graphics context
CTFrameRef frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, 0), path, NULL);
CFRelease(framesetter);
if (frame) {
CTFrameDraw(frame, cgContext);
CFRelease(frame);
}
// restore the cgcontext gstate
CGContextRestoreGState(cgContext);
break;
}
case DM_SOLID_COLOR: {
// save the cgcontext gstate
CGContextSaveGState(cgContext);
// restore the cgcontext gstate
CGContextRestoreGState(cgContext);
break;
}
case DM_SOLID_COLOR: {
// save the cgcontext gstate
CGContextSaveGState(cgContext);
// we get a flipped context
CGContextTranslateCTM(cgContext, 0.0, windowHeight);
CGContextScaleCTM(cgContext, 1.0, -1.0);
// we get a flipped context
CGContextTranslateCTM(cgContext, 0.0, windowHeight);
CGContextScaleCTM(cgContext, 1.0, -1.0);
// draw a solid background for the plugin
CGContextAddRect(cgContext, CGRectMake(0, 0, windowWidth, windowHeight));
// draw a solid background for the plugin
CGContextAddRect(cgContext, CGRectMake(0, 0, windowWidth, windowHeight));
float r, g, b, a;
GetColorsFromRGBA(instanceData->scriptableObject->drawColor, &r, &g, &b, &a);
CGContextSetRGBFillColor(cgContext, r, g, b, a);
CGContextDrawPath(cgContext, kCGPathFill);
float r,g,b,a;
GetColorsFromRGBA(instanceData->scriptableObject->drawColor, &r, &g, &b, &a);
CGContextSetRGBFillColor(cgContext, r, g, b, a);
CGContextDrawPath(cgContext, kCGPathFill);
// restore the cgcontext gstate
CGContextRestoreGState(cgContext);
break;
}
// restore the cgcontext gstate
CGContextRestoreGState(cgContext);
break;
}
}
}
int16_t
pluginHandleEvent(InstanceData* instanceData, void* event)
{
int16_t pluginHandleEvent(InstanceData* instanceData, void* event) {
NPCocoaEvent* cocoaEvent = (NPCocoaEvent*)event;
if (!cocoaEvent)
return kNPEventNotHandled;
if (!cocoaEvent) return kNPEventNotHandled;
switch (cocoaEvent->type) {
case NPCocoaEventDrawRect:
@ -246,13 +218,15 @@ pluginHandleEvent(InstanceData* instanceData, void* event)
}
break;
case NPCocoaEventWindowFocusChanged:
instanceData->topLevelWindowActivationState = cocoaEvent->data.focus.hasFocus ?
ACTIVATION_STATE_ACTIVATED : ACTIVATION_STATE_DEACTIVATED;
instanceData->topLevelWindowActivationEventCount = instanceData->topLevelWindowActivationEventCount + 1;
instanceData->topLevelWindowActivationState = cocoaEvent->data.focus.hasFocus
? ACTIVATION_STATE_ACTIVATED
: ACTIVATION_STATE_DEACTIVATED;
instanceData->topLevelWindowActivationEventCount =
instanceData->topLevelWindowActivationEventCount + 1;
break;
case NPCocoaEventFocusChanged:
instanceData->focusState = cocoaEvent->data.focus.hasFocus ?
ACTIVATION_STATE_ACTIVATED : ACTIVATION_STATE_DEACTIVATED;
instanceData->focusState = cocoaEvent->data.focus.hasFocus ? ACTIVATION_STATE_ACTIVATED
: ACTIVATION_STATE_DEACTIVATED;
instanceData->focusEventCount = instanceData->focusEventCount + 1;
break;
default:
@ -262,32 +236,25 @@ pluginHandleEvent(InstanceData* instanceData, void* event)
return kNPEventHandled;
}
int32_t pluginGetEdge(InstanceData* instanceData, RectEdge edge)
{
int32_t pluginGetEdge(InstanceData* instanceData, RectEdge edge) {
NPWindow* w = &instanceData->window;
switch (edge) {
case EDGE_LEFT:
return w->x;
case EDGE_TOP:
return w->y;
case EDGE_RIGHT:
return w->x + w->width;
case EDGE_BOTTOM:
return w->y + w->height;
case EDGE_LEFT:
return w->x;
case EDGE_TOP:
return w->y;
case EDGE_RIGHT:
return w->x + w->width;
case EDGE_BOTTOM:
return w->y + w->height;
}
MOZ_CRASH("Unexpected RectEdge?!");
}
int32_t pluginGetClipRegionRectCount(InstanceData* instanceData)
{
return 1;
}
int32_t pluginGetClipRegionRectCount(InstanceData* instanceData) { return 1; }
int32_t pluginGetClipRegionRectEdge(InstanceData* instanceData,
int32_t rectIndex, RectEdge edge)
{
if (rectIndex != 0)
return NPTEST_INT32_ERROR;
int32_t pluginGetClipRegionRectEdge(InstanceData* instanceData, int32_t rectIndex, RectEdge edge) {
if (rectIndex != 0) return NPTEST_INT32_ERROR;
// We have to add the Cocoa titlebar height here since the clip rect
// is being returned relative to that
@ -295,18 +262,16 @@ int32_t pluginGetClipRegionRectEdge(InstanceData* instanceData,
NPWindow* w = &instanceData->window;
switch (edge) {
case EDGE_LEFT:
return w->clipRect.left;
case EDGE_TOP:
return w->clipRect.top + COCOA_TITLEBAR_HEIGHT;
case EDGE_RIGHT:
return w->clipRect.right;
case EDGE_BOTTOM:
return w->clipRect.bottom + COCOA_TITLEBAR_HEIGHT;
case EDGE_LEFT:
return w->clipRect.left;
case EDGE_TOP:
return w->clipRect.top + COCOA_TITLEBAR_HEIGHT;
case EDGE_RIGHT:
return w->clipRect.right;
case EDGE_BOTTOM:
return w->clipRect.bottom + COCOA_TITLEBAR_HEIGHT;
}
MOZ_CRASH("Unexpected RectEdge?!");
}
void pluginDoInternalConsistencyCheck(InstanceData* instanceData, string& error)
{
}
void pluginDoInternalConsistencyCheck(InstanceData* instanceData, string& error) {}

View File

@ -32,21 +32,18 @@ using namespace mozilla;
static const CLLocationAccuracy kHIGH_ACCURACY = kCLLocationAccuracyBest;
static const CLLocationAccuracy kDEFAULT_ACCURACY = kCLLocationAccuracyNearestTenMeters;
@interface LocationDelegate : NSObject <CLLocationManagerDelegate>
{
@interface LocationDelegate : NSObject <CLLocationManagerDelegate> {
CoreLocationLocationProvider* mProvider;
}
- (id)init:(CoreLocationLocationProvider*)aProvider;
- (void)locationManager:(CLLocationManager*)aManager
didFailWithError:(NSError *)aError;
- (void)locationManager:(CLLocationManager*)aManager didFailWithError:(NSError*)aError;
- (void)locationManager:(CLLocationManager*)aManager didUpdateLocations:(NSArray*)locations;
@end
@implementation LocationDelegate
- (id) init:(CoreLocationLocationProvider*) aProvider
{
- (id)init:(CoreLocationLocationProvider*)aProvider {
if ((self = [super init])) {
mProvider = aProvider;
}
@ -54,16 +51,13 @@ static const CLLocationAccuracy kDEFAULT_ACCURACY = kCLLocationAccuracyNearestTe
return self;
}
- (void)locationManager:(CLLocationManager*)aManager
didFailWithError:(NSError *)aError
{
nsCOMPtr<nsIConsoleService> console =
do_GetService(NS_CONSOLESERVICE_CONTRACTID);
- (void)locationManager:(CLLocationManager*)aManager didFailWithError:(NSError*)aError {
nsCOMPtr<nsIConsoleService> console = do_GetService(NS_CONSOLESERVICE_CONTRACTID);
NS_ENSURE_TRUE_VOID(console);
NSString* message =
[@"Failed to acquire position: " stringByAppendingString: [aError localizedDescription]];
[@"Failed to acquire position: " stringByAppendingString:[aError localizedDescription]];
console->LogStringMessage(NS_ConvertUTF8toUTF16([message UTF8String]).get());
@ -78,8 +72,7 @@ static const CLLocationAccuracy kDEFAULT_ACCURACY = kCLLocationAccuracyNearestTe
mProvider->CreateMLSFallbackProvider();
}
- (void)locationManager:(CLLocationManager*)aManager didUpdateLocations:(NSArray*)aLocations
{
- (void)locationManager:(CLLocationManager*)aManager didUpdateLocations:(NSArray*)aLocations {
if (aLocations.count < 1) {
return;
}
@ -100,25 +93,15 @@ static const CLLocationAccuracy kDEFAULT_ACCURACY = kCLLocationAccuracyNearestTe
altitudeAccuracy = UnspecifiedNaN<double>();
}
double speed = location.speed >= 0
? location.speed
: UnspecifiedNaN<double>();
double speed = location.speed >= 0 ? location.speed : UnspecifiedNaN<double>();
double heading = location.course >= 0
? location.course
: UnspecifiedNaN<double>();
double heading = location.course >= 0 ? location.course : UnspecifiedNaN<double>();
// nsGeoPositionCoords will convert NaNs to null for optional properties of
// the JavaScript Coordinates object.
nsCOMPtr<nsIDOMGeoPosition> geoPosition =
new nsGeoPosition(location.coordinate.latitude,
location.coordinate.longitude,
altitude,
location.horizontalAccuracy,
altitudeAccuracy,
heading,
speed,
PR_Now() / PR_USEC_PER_MSEC);
nsCOMPtr<nsIDOMGeoPosition> geoPosition = new nsGeoPosition(
location.coordinate.latitude, location.coordinate.longitude, altitude,
location.horizontalAccuracy, altitudeAccuracy, heading, speed, PR_Now() / PR_USEC_PER_MSEC);
mProvider->Update(geoPosition);
Telemetry::Accumulate(Telemetry::GEOLOCATION_OSX_SOURCE_IS_MLS, false);
@ -128,13 +111,10 @@ static const CLLocationAccuracy kDEFAULT_ACCURACY = kCLLocationAccuracyNearestTe
NS_IMPL_ISUPPORTS(CoreLocationLocationProvider::MLSUpdate, nsIGeolocationUpdate);
CoreLocationLocationProvider::MLSUpdate::MLSUpdate(CoreLocationLocationProvider& parentProvider)
: mParentLocationProvider(parentProvider)
{
}
: mParentLocationProvider(parentProvider) {}
NS_IMETHODIMP
CoreLocationLocationProvider::MLSUpdate::Update(nsIDOMGeoPosition *position)
{
CoreLocationLocationProvider::MLSUpdate::Update(nsIDOMGeoPosition* position) {
nsCOMPtr<nsIDOMGeoPositionCoords> coords;
position->GetCoords(getter_AddRefs(coords));
if (!coords) {
@ -146,14 +126,13 @@ CoreLocationLocationProvider::MLSUpdate::Update(nsIDOMGeoPosition *position)
}
NS_IMETHODIMP
CoreLocationLocationProvider::MLSUpdate::NotifyError(uint16_t error)
{
CoreLocationLocationProvider::MLSUpdate::NotifyError(uint16_t error) {
mParentLocationProvider.NotifyError(error);
return NS_OK;
}
class CoreLocationObjects {
public:
public:
nsresult Init(CoreLocationLocationProvider* aProvider) {
mLocationManager = [[CLLocationManager alloc] init];
NS_ENSURE_TRUE(mLocationManager, NS_ERROR_NOT_AVAILABLE);
@ -184,13 +163,10 @@ public:
NS_IMPL_ISUPPORTS(CoreLocationLocationProvider, nsIGeolocationProvider)
CoreLocationLocationProvider::CoreLocationLocationProvider()
: mCLObjects(nullptr), mMLSFallbackProvider(nullptr)
{
}
: mCLObjects(nullptr), mMLSFallbackProvider(nullptr) {}
NS_IMETHODIMP
CoreLocationLocationProvider::Startup()
{
CoreLocationLocationProvider::Startup() {
if (!mCLObjects) {
nsAutoPtr<CoreLocationObjects> clObjs(new CoreLocationObjects());
@ -207,8 +183,7 @@ CoreLocationLocationProvider::Startup()
}
NS_IMETHODIMP
CoreLocationLocationProvider::Watch(nsIGeolocationUpdate* aCallback)
{
CoreLocationLocationProvider::Watch(nsIGeolocationUpdate* aCallback) {
if (mCallback) {
return NS_OK;
}
@ -218,8 +193,7 @@ CoreLocationLocationProvider::Watch(nsIGeolocationUpdate* aCallback)
}
NS_IMETHODIMP
CoreLocationLocationProvider::Shutdown()
{
CoreLocationLocationProvider::Shutdown() {
NS_ENSURE_STATE(mCLObjects);
[mCLObjects->mLocationManager stopUpdatingLocation];
@ -236,31 +210,23 @@ CoreLocationLocationProvider::Shutdown()
}
NS_IMETHODIMP
CoreLocationLocationProvider::SetHighAccuracy(bool aEnable)
{
CoreLocationLocationProvider::SetHighAccuracy(bool aEnable) {
NS_ENSURE_STATE(mCLObjects);
mCLObjects->mLocationManager.desiredAccuracy =
(aEnable ? kHIGH_ACCURACY : kDEFAULT_ACCURACY);
mCLObjects->mLocationManager.desiredAccuracy = (aEnable ? kHIGH_ACCURACY : kDEFAULT_ACCURACY);
return NS_OK;
}
void
CoreLocationLocationProvider::Update(nsIDOMGeoPosition* aSomewhere)
{
void CoreLocationLocationProvider::Update(nsIDOMGeoPosition* aSomewhere) {
if (aSomewhere && mCallback) {
mCallback->Update(aSomewhere);
}
}
void
CoreLocationLocationProvider::NotifyError(uint16_t aErrorCode)
{
void CoreLocationLocationProvider::NotifyError(uint16_t aErrorCode) {
mCallback->NotifyError(aErrorCode);
}
void
CoreLocationLocationProvider::CreateMLSFallbackProvider()
{
void CoreLocationLocationProvider::CreateMLSFallbackProvider() {
if (mMLSFallbackProvider) {
return;
}
@ -269,9 +235,7 @@ CoreLocationLocationProvider::CreateMLSFallbackProvider()
mMLSFallbackProvider->Startup(new MLSUpdate(*this));
}
void
CoreLocationLocationProvider::CancelMLSFallbackProvider()
{
void CoreLocationLocationProvider::CancelMLSFallbackProvider() {
if (!mMLSFallbackProvider) {
return;
}

View File

@ -15,8 +15,7 @@ using namespace mozilla;
using mozilla::dom::Promise;
NS_IMETHODIMP
nsOSPermissionRequest::GetAudioCapturePermissionState(uint16_t* aAudio)
{
nsOSPermissionRequest::GetAudioCapturePermissionState(uint16_t* aAudio) {
MOZ_ASSERT(aAudio);
if (!nsCocoaFeatures::OnMojaveOrLater()) {
@ -27,8 +26,7 @@ nsOSPermissionRequest::GetAudioCapturePermissionState(uint16_t* aAudio)
}
NS_IMETHODIMP
nsOSPermissionRequest::GetVideoCapturePermissionState(uint16_t* aVideo)
{
nsOSPermissionRequest::GetVideoCapturePermissionState(uint16_t* aVideo) {
MOZ_ASSERT(aVideo);
if (!nsCocoaFeatures::OnMojaveOrLater()) {
@ -39,9 +37,7 @@ nsOSPermissionRequest::GetVideoCapturePermissionState(uint16_t* aVideo)
}
NS_IMETHODIMP
nsOSPermissionRequest::RequestVideoCapturePermission(JSContext* aCx,
Promise** aPromiseOut)
{
nsOSPermissionRequest::RequestVideoCapturePermission(JSContext* aCx, Promise** aPromiseOut) {
if (!nsCocoaFeatures::OnMojaveOrLater()) {
return nsOSPermissionRequestBase::RequestVideoCapturePermission(aCx, aPromiseOut);
}
@ -58,9 +54,7 @@ nsOSPermissionRequest::RequestVideoCapturePermission(JSContext* aCx,
}
NS_IMETHODIMP
nsOSPermissionRequest::RequestAudioCapturePermission(JSContext* aCx,
Promise** aPromiseOut)
{
nsOSPermissionRequest::RequestAudioCapturePermission(JSContext* aCx, Promise** aPromiseOut) {
if (!nsCocoaFeatures::OnMojaveOrLater()) {
return nsOSPermissionRequestBase::RequestAudioCapturePermission(aCx, aPromiseOut);
}

View File

@ -19,24 +19,22 @@
#include "nsIPrefService.h"
#include "nsServiceManagerUtils.h"
static const nsXREAppData sAppData = {
sizeof(nsXREAppData),
nullptr, // directory
"Mozilla",
"Browser",
nullptr,
"38.0a1",
"201502090123",
"browser@mozilla.org",
nullptr, // copyright
0,
nullptr, // xreDirectory
"38.0a1",
"*",
"https://crash-reports.mozilla.com/submit",
nullptr,
"Firefox"
};
static const nsXREAppData sAppData = {sizeof(nsXREAppData),
nullptr, // directory
"Mozilla",
"Browser",
nullptr,
"38.0a1",
"201502090123",
"browser@mozilla.org",
nullptr, // copyright
0,
nullptr, // xreDirectory
"38.0a1",
"*",
"https://crash-reports.mozilla.com/submit",
nullptr,
"Firefox"};
XRE_GetFileFromPathType XRE_GetFileFromPath;
XRE_CreateAppDataType XRE_CreateAppData;
@ -44,17 +42,16 @@ XRE_FreeAppDataType XRE_FreeAppData;
XRE_mainType XRE_main;
static const nsDynamicFunctionLoad kXULFuncs[] = {
{ "XRE_GetFileFromPath", (NSFuncPtr*) &XRE_GetFileFromPath },
{ "XRE_CreateAppData", (NSFuncPtr*) &XRE_CreateAppData },
{ "XRE_FreeAppData", (NSFuncPtr*) &XRE_FreeAppData },
{ "XRE_main", (NSFuncPtr*) &XRE_main },
{ nullptr, nullptr }
};
{"XRE_GetFileFromPath", (NSFuncPtr*)&XRE_GetFileFromPath},
{"XRE_CreateAppData", (NSFuncPtr*)&XRE_CreateAppData},
{"XRE_FreeAppData", (NSFuncPtr*)&XRE_FreeAppData},
{"XRE_main", (NSFuncPtr*)&XRE_main},
{nullptr, nullptr}};
const int MAXPATHLEN = 1024;
const char* XPCOM_DLL = "XUL";
int main(int argc, char * argv[]) {
int main(int argc, char* argv[]) {
char exeDir[MAXPATHLEN];
NSString* bundlePath = [[NSBundle mainBundle] bundlePath];
strncpy(exeDir, [bundlePath UTF8String], MAXPATHLEN);
@ -82,7 +79,7 @@ int main(int argc, char * argv[]) {
printf("Couldn't find the application directory.\n");
return 255;
}
nsCOMPtr<nsIFile> appSubdir;
greDir->Clone(getter_AddRefs(appSubdir));
greDir->Append(NS_LITERAL_STRING("Frameworks"));

View File

@ -14,19 +14,17 @@
#include <dlfcn.h>
#include "GLDefs.h"
#define IOSURFACE_FRAMEWORK_PATH \
"/System/Library/Frameworks/IOSurface.framework/IOSurface"
#define OPENGL_FRAMEWORK_PATH \
"/System/Library/Frameworks/OpenGL.framework/OpenGL"
#define COREGRAPHICS_FRAMEWORK_PATH \
"/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreGraphics.framework/CoreGraphics"
#define IOSURFACE_FRAMEWORK_PATH "/System/Library/Frameworks/IOSurface.framework/IOSurface"
#define OPENGL_FRAMEWORK_PATH "/System/Library/Frameworks/OpenGL.framework/OpenGL"
#define COREGRAPHICS_FRAMEWORK_PATH \
"/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreGraphics.framework/" \
"CoreGraphics"
@interface CALayer (ContentsScale)
- (double)contentsScale;
- (void)setContentsScale:(double)scale;
@end
CGColorSpaceRef CreateSystemColorSpace() {
CGColorSpaceRef cspace = ::CGDisplayCopyColorSpace(::CGMainDisplayID());
if (!cspace) {
@ -35,11 +33,9 @@ CGColorSpaceRef CreateSystemColorSpace() {
return cspace;
}
nsCARenderer::~nsCARenderer() {
Destroy();
}
nsCARenderer::~nsCARenderer() { Destroy(); }
void cgdata_release_callback(void *aCGData, const void *data, size_t size) {
void cgdata_release_callback(void* aCGData, const void* data, size_t size) {
if (aCGData) {
free(aCGData);
}
@ -75,8 +71,7 @@ void nsCARenderer::Destroy() {
::glDeleteFramebuffersEXT(1, &mFBO);
}
if (oldContext)
::CGLSetCurrentContext(oldContext);
if (oldContext) ::CGLSetCurrentContext(oldContext);
}
::CGLDestroyContext((CGLContextObj)mOpenGLContext);
}
@ -95,25 +90,20 @@ void nsCARenderer::Destroy() {
mIOTexture = 0;
}
nsresult nsCARenderer::SetupRenderer(void *aCALayer, int aWidth, int aHeight,
nsresult nsCARenderer::SetupRenderer(void* aCALayer, int aWidth, int aHeight,
double aContentsScaleFactor,
AllowOfflineRendererEnum aAllowOfflineRenderer) {
mAllowOfflineRenderer = aAllowOfflineRenderer;
if (aWidth == 0 || aHeight == 0 || aContentsScaleFactor <= 0)
return NS_ERROR_FAILURE;
if (aWidth == 0 || aHeight == 0 || aContentsScaleFactor <= 0) return NS_ERROR_FAILURE;
if (aWidth == mUnsupportedWidth &&
aHeight == mUnsupportedHeight) {
if (aWidth == mUnsupportedWidth && aHeight == mUnsupportedHeight) {
return NS_ERROR_FAILURE;
}
CGLPixelFormatAttribute attributes[] = {
kCGLPFAAccelerated,
kCGLPFADepthSize, (CGLPixelFormatAttribute)24,
kCGLPFAAllowOfflineRenderers,
(CGLPixelFormatAttribute)0
};
CGLPixelFormatAttribute attributes[] = {kCGLPFAAccelerated, kCGLPFADepthSize,
(CGLPixelFormatAttribute)24, kCGLPFAAllowOfflineRenderers,
(CGLPixelFormatAttribute)0};
if (mAllowOfflineRenderer == DISALLOW_OFFLINE_RENDERER) {
attributes[3] = (CGLPixelFormatAttribute)0;
@ -136,8 +126,7 @@ nsresult nsCARenderer::SetupRenderer(void *aCALayer, int aWidth, int aHeight,
}
::CGLDestroyPixelFormat(format);
CARenderer* caRenderer = [[CARenderer rendererWithCGLContext:mOpenGLContext
options:nil] retain];
CARenderer* caRenderer = [[CARenderer rendererWithCGLContext:mOpenGLContext options:nil] retain];
if (caRenderer == nil) {
mUnsupportedWidth = aWidth;
mUnsupportedHeight = aHeight;
@ -163,22 +152,22 @@ nsresult nsCARenderer::SetupRenderer(void *aCALayer, int aWidth, int aHeight,
// We target rendering to a CGImage if no shared IOSurface are given.
if (!mIOSurface) {
mCGData = malloc(aWidth*intScaleFactor*aHeight*4*intScaleFactor);
mCGData = malloc(aWidth * intScaleFactor * aHeight * 4 * intScaleFactor);
if (!mCGData) {
mUnsupportedWidth = aWidth;
mUnsupportedHeight = aHeight;
Destroy();
return NS_ERROR_FAILURE;
}
memset(mCGData, 0, aWidth*intScaleFactor*aHeight*4*intScaleFactor);
memset(mCGData, 0, aWidth * intScaleFactor * aHeight * 4 * intScaleFactor);
CGDataProviderRef dataProvider = nullptr;
dataProvider = ::CGDataProviderCreateWithData(mCGData,
mCGData, aHeight*intScaleFactor*aWidth*4*intScaleFactor,
cgdata_release_callback);
dataProvider = ::CGDataProviderCreateWithData(
mCGData, mCGData, aHeight * intScaleFactor * aWidth * 4 * intScaleFactor,
cgdata_release_callback);
if (!dataProvider) {
cgdata_release_callback(mCGData, mCGData,
aHeight*intScaleFactor*aWidth*4*intScaleFactor);
aHeight * intScaleFactor * aWidth * 4 * intScaleFactor);
mUnsupportedWidth = aWidth;
mUnsupportedHeight = aHeight;
Destroy();
@ -187,10 +176,10 @@ nsresult nsCARenderer::SetupRenderer(void *aCALayer, int aWidth, int aHeight,
CGColorSpaceRef colorSpace = CreateSystemColorSpace();
mCGImage = ::CGImageCreate(aWidth * intScaleFactor, aHeight * intScaleFactor,
8, 32, aWidth * intScaleFactor * 4, colorSpace,
kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host,
dataProvider, nullptr, true, kCGRenderingIntentDefault);
mCGImage = ::CGImageCreate(aWidth * intScaleFactor, aHeight * intScaleFactor, 8, 32,
aWidth * intScaleFactor * 4, colorSpace,
kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host,
dataProvider, nullptr, true, kCGRenderingIntentDefault);
::CGDataProviderRelease(dataProvider);
::CGColorSpaceRelease(colorSpace);
@ -211,11 +200,10 @@ nsresult nsCARenderer::SetupRenderer(void *aCALayer, int aWidth, int aHeight,
::glBindTexture(GL_TEXTURE_RECTANGLE_ARB, mIOTexture);
::glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
::glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
MacIOSurfaceLib::CGLTexImageIOSurface2D(mOpenGLContext, GL_TEXTURE_RECTANGLE_ARB,
GL_RGBA, aWidth * intScaleFactor,
aHeight * intScaleFactor,
GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
mIOSurface->mIOSurfacePtr, 0);
MacIOSurfaceLib::CGLTexImageIOSurface2D(mOpenGLContext, GL_TEXTURE_RECTANGLE_ARB, GL_RGBA,
aWidth * intScaleFactor, aHeight * intScaleFactor,
GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
mIOSurface->mIOSurfacePtr, 0);
::glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
} else {
::glGenTextures(1, &mFBOTexture);
@ -229,21 +217,19 @@ nsresult nsCARenderer::SetupRenderer(void *aCALayer, int aWidth, int aHeight,
::glGenFramebuffersEXT(1, &mFBO);
::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFBO);
if (mIOSurface) {
::glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
::glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
GL_TEXTURE_RECTANGLE_ARB, mIOTexture, 0);
} else {
::glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
GL_TEXTURE_RECTANGLE_ARB, mFBOTexture, 0);
}
// Make sure that the Framebuffer configuration is supported on the client machine
GLenum fboStatus;
fboStatus = ::glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
if (fboStatus != GL_FRAMEBUFFER_COMPLETE_EXT) {
NS_ERROR("FBO not supported");
if (oldContext)
::CGLSetCurrentContext(oldContext);
if (oldContext) ::CGLSetCurrentContext(oldContext);
mUnsupportedWidth = aWidth;
mUnsupportedHeight = aHeight;
Destroy();
@ -258,13 +244,11 @@ nsresult nsCARenderer::SetupRenderer(void *aCALayer, int aWidth, int aHeight,
mUnsupportedWidth = aWidth;
mUnsupportedHeight = aHeight;
Destroy();
if (oldContext)
::CGLSetCurrentContext(oldContext);
if (oldContext) ::CGLSetCurrentContext(oldContext);
return NS_ERROR_FAILURE;
}
if (oldContext)
::CGLSetCurrentContext(oldContext);
if (oldContext) ::CGLSetCurrentContext(oldContext);
return NS_OK;
}
@ -273,20 +257,15 @@ void nsCARenderer::SetBounds(int aWidth, int aHeight) {
CARenderer* caRenderer = (CARenderer*)mCARenderer;
CALayer* wrapperLayer = (CALayer*)mWrapperCALayer;
NSArray* sublayers = [wrapperLayer sublayers];
CALayer* pluginLayer = (CALayer*) [sublayers objectAtIndex:0];
CALayer* pluginLayer = (CALayer*)[sublayers objectAtIndex:0];
// Create a transaction and disable animations
// to make the position update instant.
[CATransaction begin];
NSMutableDictionary *newActions =
[[NSMutableDictionary alloc] initWithObjectsAndKeys:
[NSNull null], @"onOrderIn",
[NSNull null], @"onOrderOut",
[NSNull null], @"sublayers",
[NSNull null], @"contents",
[NSNull null], @"position",
[NSNull null], @"bounds",
nil];
NSMutableDictionary* newActions = [[NSMutableDictionary alloc]
initWithObjectsAndKeys:[NSNull null], @"onOrderIn", [NSNull null], @"onOrderOut",
[NSNull null], @"sublayers", [NSNull null], @"contents", [NSNull null],
@"position", [NSNull null], @"bounds", nil];
wrapperLayer.actions = newActions;
[newActions release];
@ -298,10 +277,10 @@ void nsCARenderer::SetBounds(int aWidth, int aHeight) {
// making pluginLayer (usually the CALayer* provided by the plugin) a
// sublayer of our own wrapperLayer (see bug 829284).
size_t intScaleFactor = ceil(mContentsScaleFactor);
[CATransaction setValue: [NSNumber numberWithFloat:0.0f] forKey: kCATransactionAnimationDuration];
[CATransaction setValue: (id) kCFBooleanTrue forKey: kCATransactionDisableActions];
[CATransaction setValue:[NSNumber numberWithFloat:0.0f] forKey:kCATransactionAnimationDuration];
[CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions];
[wrapperLayer setBounds:CGRectMake(0, 0, aWidth, aHeight)];
[wrapperLayer setPosition:CGPointMake(aWidth/2.0, aHeight/2.0)];
[wrapperLayer setPosition:CGPointMake(aWidth / 2.0, aHeight / 2.0)];
[pluginLayer setBounds:CGRectMake(0, 0, aWidth, aHeight)];
[pluginLayer setFrame:CGRectMake(0, 0, aWidth, aHeight)];
caRenderer.bounds = CGRectMake(0, 0, aWidth * intScaleFactor, aHeight * intScaleFactor);
@ -309,8 +288,8 @@ void nsCARenderer::SetBounds(int aWidth, int aHeight) {
CGAffineTransform affineTransform = [wrapperLayer affineTransform];
affineTransform.a = mContentsScaleFactor;
affineTransform.d = mContentsScaleFactor;
affineTransform.tx = ((double)aWidth)/mContentsScaleFactor;
affineTransform.ty = ((double)aHeight)/mContentsScaleFactor;
affineTransform.tx = ((double)aWidth) / mContentsScaleFactor;
affineTransform.ty = ((double)aHeight) / mContentsScaleFactor;
[wrapperLayer setAffineTransform:affineTransform];
} else {
// These settings are the default values. But they might have been
@ -329,16 +308,15 @@ void nsCARenderer::SetViewport(int aWidth, int aHeight) {
::glViewport(0.0, 0.0, aWidth, aHeight);
::glMatrixMode(GL_PROJECTION);
::glLoadIdentity();
::glOrtho (0.0, aWidth, 0.0, aHeight, -1, 1);
::glOrtho(0.0, aWidth, 0.0, aHeight, -1, 1);
// Render upside down to speed up CGContextDrawImage
::glTranslatef(0.0f, aHeight, 0.0);
::glScalef(1.0, -1.0, 1.0);
}
void nsCARenderer::AttachIOSurface(MacIOSurface *aSurface) {
if (mIOSurface &&
aSurface->GetIOSurfaceID() == mIOSurface->GetIOSurfaceID()) {
void nsCARenderer::AttachIOSurface(MacIOSurface* aSurface) {
if (mIOSurface && aSurface->GetIOSurfaceID() == mIOSurface->GetIOSurfaceID()) {
return;
}
@ -354,11 +332,10 @@ void nsCARenderer::AttachIOSurface(MacIOSurface *aSurface) {
CGLContextObj oldContext = ::CGLGetCurrentContext();
::CGLSetCurrentContext(mOpenGLContext);
::glBindTexture(GL_TEXTURE_RECTANGLE_ARB, mIOTexture);
MacIOSurfaceLib::CGLTexImageIOSurface2D(mOpenGLContext, GL_TEXTURE_RECTANGLE_ARB,
GL_RGBA, mIOSurface->GetDevicePixelWidth(),
mIOSurface->GetDevicePixelHeight(),
GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
mIOSurface->mIOSurfacePtr, 0);
MacIOSurfaceLib::CGLTexImageIOSurface2D(
mOpenGLContext, GL_TEXTURE_RECTANGLE_ARB, GL_RGBA, mIOSurface->GetDevicePixelWidth(),
mIOSurface->GetDevicePixelHeight(), GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
mIOSurface->mIOSurfacePtr, 0);
::glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
// Rebind the FBO to make it live
@ -386,9 +363,8 @@ IOSurfaceID nsCARenderer::GetIOSurfaceID() {
return mIOSurface->GetIOSurfaceID();
}
nsresult nsCARenderer::Render(int aWidth, int aHeight,
double aContentsScaleFactor,
CGImageRef *aOutCGImage) {
nsresult nsCARenderer::Render(int aWidth, int aHeight, double aContentsScaleFactor,
CGImageRef* aOutCGImage) {
if (!aOutCGImage && !mIOSurface) {
NS_ERROR("No target destination for rendering");
} else if (aOutCGImage) {
@ -397,8 +373,7 @@ nsresult nsCARenderer::Render(int aWidth, int aHeight,
*aOutCGImage = nullptr;
}
if (aWidth == 0 || aHeight == 0 || aContentsScaleFactor <= 0)
return NS_OK;
if (aWidth == 0 || aHeight == 0 || aContentsScaleFactor <= 0) return NS_OK;
if (!mCARenderer || !mWrapperCALayer) {
return NS_ERROR_FAILURE;
@ -417,15 +392,15 @@ nsresult nsCARenderer::Render(int aWidth, int aHeight,
// caLayer may be the CALayer* provided by the plugin, so we need to
// preserve it across the call to Destroy().
NSArray* sublayers = [wrapperLayer sublayers];
CALayer* caLayer = (CALayer*) [sublayers objectAtIndex:0];
CALayer* caLayer = (CALayer*)[sublayers objectAtIndex:0];
// mIOSurface is set by AttachIOSurface(), not by SetupRenderer(). So
// since it may have been set by a prior call to AttachIOSurface(), we
// need to preserve it across the call to Destroy().
RefPtr<MacIOSurface> ioSurface = mIOSurface;
Destroy();
mIOSurface = ioSurface;
if (SetupRenderer(caLayer, aWidth, aHeight, aContentsScaleFactor,
mAllowOfflineRenderer) != NS_OK) {
if (SetupRenderer(caLayer, aWidth, aHeight, aContentsScaleFactor, mAllowOfflineRenderer) !=
NS_OK) {
return NS_ERROR_FAILURE;
}
@ -444,8 +419,7 @@ nsresult nsCARenderer::Render(int aWidth, int aHeight,
if (result != GL_NO_ERROR) {
NS_ERROR("Unexpected OpenGL Error");
Destroy();
if (oldContext)
::CGLSetCurrentContext(oldContext);
if (oldContext) ::CGLSetCurrentContext(oldContext);
return NS_ERROR_FAILURE;
}
@ -455,8 +429,7 @@ nsresult nsCARenderer::Render(int aWidth, int aHeight,
[CATransaction commit];
double caTime = ::CACurrentMediaTime();
[caRenderer beginFrameAtTime:caTime timeStamp:nullptr];
[caRenderer addUpdateRect:CGRectMake(0,0, aWidth * intScaleFactor,
aHeight * intScaleFactor)];
[caRenderer addUpdateRect:CGRectMake(0, 0, aWidth * intScaleFactor, aHeight * intScaleFactor)];
[caRenderer render];
[caRenderer endFrame];
@ -469,10 +442,8 @@ nsresult nsCARenderer::Render(int aWidth, int aHeight,
::glPixelStorei(GL_PACK_SKIP_ROWS, 0);
::glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
::glReadPixels(0.0f, 0.0f, aWidth * intScaleFactor,
aHeight * intScaleFactor,
GL_BGRA, GL_UNSIGNED_BYTE,
mCGData);
::glReadPixels(0.0f, 0.0f, aWidth * intScaleFactor, aHeight * intScaleFactor, GL_BGRA,
GL_UNSIGNED_BYTE, mCGData);
*aOutCGImage = mCGImage;
}
@ -484,10 +455,8 @@ nsresult nsCARenderer::Render(int aWidth, int aHeight,
return NS_OK;
}
nsresult nsCARenderer::DrawSurfaceToCGContext(CGContextRef aContext,
MacIOSurface *surf,
CGColorSpaceRef aColorSpace,
int aX, int aY,
nsresult nsCARenderer::DrawSurfaceToCGContext(CGContextRef aContext, MacIOSurface* surf,
CGColorSpaceRef aColorSpace, int aX, int aY,
size_t aWidth, size_t aHeight) {
surf->Lock();
size_t bytesPerRow = surf->GetBytesPerRow();
@ -496,13 +465,11 @@ nsresult nsCARenderer::DrawSurfaceToCGContext(CGContextRef aContext,
// We get rendering glitches if we use a width/height that falls
// outside of the IOSurface.
if (aWidth + aX > ioWidth)
aWidth = ioWidth - aX;
if (aHeight + aY > ioHeight)
aHeight = ioHeight - aY;
if (aWidth + aX > ioWidth) aWidth = ioWidth - aX;
if (aHeight + aY > ioHeight) aHeight = ioHeight - aY;
if (aX < 0 || static_cast<size_t>(aX) >= ioWidth ||
aY < 0 || static_cast<size_t>(aY) >= ioHeight) {
if (aX < 0 || static_cast<size_t>(aX) >= ioWidth || aY < 0 ||
static_cast<size_t>(aY) >= ioHeight) {
surf->Unlock();
return NS_ERROR_FAILURE;
}
@ -510,28 +477,26 @@ nsresult nsCARenderer::DrawSurfaceToCGContext(CGContextRef aContext,
void* ioData = surf->GetBaseAddress();
double scaleFactor = surf->GetContentsScaleFactor();
size_t intScaleFactor = ceil(surf->GetContentsScaleFactor());
CGDataProviderRef dataProvider = ::CGDataProviderCreateWithData(ioData,
ioData, ioHeight*intScaleFactor*(bytesPerRow)*4,
nullptr); //No release callback
CGDataProviderRef dataProvider =
::CGDataProviderCreateWithData(ioData, ioData, ioHeight * intScaleFactor * (bytesPerRow)*4,
nullptr); // No release callback
if (!dataProvider) {
surf->Unlock();
return NS_ERROR_FAILURE;
}
CGImageRef cgImage = ::CGImageCreate(ioWidth * intScaleFactor,
ioHeight * intScaleFactor, 8, 32, bytesPerRow, aColorSpace,
kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host,
dataProvider, nullptr, true, kCGRenderingIntentDefault);
CGImageRef cgImage =
::CGImageCreate(ioWidth * intScaleFactor, ioHeight * intScaleFactor, 8, 32, bytesPerRow,
aColorSpace, kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host,
dataProvider, nullptr, true, kCGRenderingIntentDefault);
::CGDataProviderRelease(dataProvider);
if (!cgImage) {
surf->Unlock();
return NS_ERROR_FAILURE;
}
CGImageRef subImage = ::CGImageCreateWithImageInRect(cgImage,
::CGRectMake(aX * scaleFactor,
aY * scaleFactor,
aWidth * scaleFactor,
aHeight * scaleFactor));
CGImageRef subImage = ::CGImageCreateWithImageInRect(
cgImage, ::CGRectMake(aX * scaleFactor, aY * scaleFactor, aWidth * scaleFactor,
aHeight * scaleFactor));
if (!subImage) {
::CGImageRelease(cgImage);
surf->Unlock();
@ -539,11 +504,9 @@ nsresult nsCARenderer::DrawSurfaceToCGContext(CGContextRef aContext,
}
::CGContextScaleCTM(aContext, 1.0f, -1.0f);
::CGContextDrawImage(aContext,
CGRectMake(aX * scaleFactor,
(-(CGFloat)aY - (CGFloat)aHeight) * scaleFactor,
aWidth * scaleFactor,
aHeight * scaleFactor),
::CGContextDrawImage(aContext,
CGRectMake(aX * scaleFactor, (-(CGFloat)aY - (CGFloat)aHeight) * scaleFactor,
aWidth * scaleFactor, aHeight * scaleFactor),
subImage);
::CGImageRelease(subImage);
@ -555,14 +518,14 @@ nsresult nsCARenderer::DrawSurfaceToCGContext(CGContextRef aContext,
void nsCARenderer::DetachCALayer() {
CALayer* wrapperLayer = (CALayer*)mWrapperCALayer;
NSArray* sublayers = [wrapperLayer sublayers];
CALayer* oldLayer = (CALayer*) [sublayers objectAtIndex:0];
CALayer* oldLayer = (CALayer*)[sublayers objectAtIndex:0];
[oldLayer removeFromSuperlayer];
}
void nsCARenderer::AttachCALayer(void *aCALayer) {
void nsCARenderer::AttachCALayer(void* aCALayer) {
CALayer* wrapperLayer = (CALayer*)mWrapperCALayer;
NSArray* sublayers = [wrapperLayer sublayers];
CALayer* oldLayer = (CALayer*) [sublayers objectAtIndex:0];
CALayer* oldLayer = (CALayer*)[sublayers objectAtIndex:0];
[oldLayer removeFromSuperlayer];
[wrapperLayer addSublayer:(CALayer*)aCALayer];
}
@ -570,24 +533,24 @@ void nsCARenderer::AttachCALayer(void *aCALayer) {
#ifdef DEBUG
int sSaveToDiskSequence = 0;
void nsCARenderer::SaveToDisk(MacIOSurface *surf) {
void nsCARenderer::SaveToDisk(MacIOSurface* surf) {
surf->Lock();
size_t bytesPerRow = surf->GetBytesPerRow();
size_t ioWidth = surf->GetWidth();
size_t ioHeight = surf->GetHeight();
void* ioData = surf->GetBaseAddress();
CGDataProviderRef dataProvider = ::CGDataProviderCreateWithData(ioData,
ioData, ioHeight*(bytesPerRow)*4,
nullptr); //No release callback
CGDataProviderRef dataProvider =
::CGDataProviderCreateWithData(ioData, ioData, ioHeight * (bytesPerRow)*4,
nullptr); // No release callback
if (!dataProvider) {
surf->Unlock();
return;
}
CGColorSpaceRef colorSpace = CreateSystemColorSpace();
CGImageRef cgImage = ::CGImageCreate(ioWidth, ioHeight, 8, 32, bytesPerRow,
colorSpace, kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host,
dataProvider, nullptr, true, kCGRenderingIntentDefault);
CGImageRef cgImage = ::CGImageCreate(ioWidth, ioHeight, 8, 32, bytesPerRow, colorSpace,
kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host,
dataProvider, nullptr, true, kCGRenderingIntentDefault);
::CGDataProviderRelease(dataProvider);
::CGColorSpaceRelease(colorSpace);
if (!cgImage) {
@ -598,10 +561,11 @@ void nsCARenderer::SaveToDisk(MacIOSurface *surf) {
char cstr[1000];
SprintfLiteral(cstr, "file:///Users/benoitgirard/debug/iosurface_%i.png", ++sSaveToDiskSequence);
CFStringRef cfStr = ::CFStringCreateWithCString(kCFAllocatorDefault, cstr, kCFStringEncodingMacRoman);
CFStringRef cfStr =
::CFStringCreateWithCString(kCFAllocatorDefault, cstr, kCFStringEncodingMacRoman);
printf("Exporting: %s\n", cstr);
CFURLRef url = ::CFURLCreateWithString( nullptr, cfStr, nullptr);
CFURLRef url = ::CFURLCreateWithString(nullptr, cfStr, nullptr);
::CFRelease(cfStr);
CFStringRef type = kUTTypePNG;
@ -619,7 +583,6 @@ void nsCARenderer::SaveToDisk(MacIOSurface *surf) {
surf->Unlock();
return;
}
#endif

View File

@ -28,167 +28,118 @@ namespace gl {
using namespace mozilla::gfx;
using namespace mozilla::widget;
class CGLLibrary
{
public:
bool EnsureInitialized()
{
if (mInitialized) {
return true;
}
if (!mOGLLibrary) {
mOGLLibrary = PR_LoadLibrary("/System/Library/Frameworks/OpenGL.framework/OpenGL");
if (!mOGLLibrary) {
NS_WARNING("Couldn't load OpenGL Framework.");
return false;
}
}
const char* db = PR_GetEnv("MOZ_CGL_DB");
if (db) {
mUseDoubleBufferedWindows = *db != '0';
}
mInitialized = true;
return true;
class CGLLibrary {
public:
bool EnsureInitialized() {
if (mInitialized) {
return true;
}
if (!mOGLLibrary) {
mOGLLibrary = PR_LoadLibrary("/System/Library/Frameworks/OpenGL.framework/OpenGL");
if (!mOGLLibrary) {
NS_WARNING("Couldn't load OpenGL Framework.");
return false;
}
}
bool UseDoubleBufferedWindows() const {
MOZ_ASSERT(mInitialized);
return mUseDoubleBufferedWindows;
const char* db = PR_GetEnv("MOZ_CGL_DB");
if (db) {
mUseDoubleBufferedWindows = *db != '0';
}
private:
bool mInitialized = false;
bool mUseDoubleBufferedWindows = true;
PRLibrary* mOGLLibrary = nullptr;
mInitialized = true;
return true;
}
bool UseDoubleBufferedWindows() const {
MOZ_ASSERT(mInitialized);
return mUseDoubleBufferedWindows;
}
private:
bool mInitialized = false;
bool mUseDoubleBufferedWindows = true;
PRLibrary* mOGLLibrary = nullptr;
};
CGLLibrary sCGLLibrary;
GLContextCGL::GLContextCGL(CreateContextFlags flags, const SurfaceCaps& caps,
NSOpenGLContext* context, bool isOffscreen)
: GLContext(flags, caps, nullptr, isOffscreen)
, mContext(context)
{
}
: GLContext(flags, caps, nullptr, isOffscreen), mContext(context) {}
GLContextCGL::~GLContextCGL()
{
MarkDestroyed();
GLContextCGL::~GLContextCGL() {
MarkDestroyed();
if (mContext) {
if ([NSOpenGLContext currentContext] == mContext) {
// Clear the current context before releasing. If we don't do
// this, the next time we call [NSOpenGLContext currentContext],
// "invalid context" will be printed to the console.
[NSOpenGLContext clearCurrentContext];
}
[mContext release];
if (mContext) {
if ([NSOpenGLContext currentContext] == mContext) {
// Clear the current context before releasing. If we don't do
// this, the next time we call [NSOpenGLContext currentContext],
// "invalid context" will be printed to the console.
[NSOpenGLContext clearCurrentContext];
}
[mContext release];
}
}
bool
GLContextCGL::Init()
{
if (!InitWithPrefix("gl", true))
return false;
bool GLContextCGL::Init() {
if (!InitWithPrefix("gl", true)) return false;
return true;
return true;
}
CGLContextObj
GLContextCGL::GetCGLContext() const
{
return static_cast<CGLContextObj>([mContext CGLContextObj]);
CGLContextObj GLContextCGL::GetCGLContext() const {
return static_cast<CGLContextObj>([mContext CGLContextObj]);
}
bool
GLContextCGL::MakeCurrentImpl() const
{
if (mContext) {
[mContext makeCurrentContext];
MOZ_ASSERT(IsCurrentImpl());
// Use non-blocking swap in "ASAP mode".
// ASAP mode means that rendering is iterated as fast as possible.
// ASAP mode is entered when layout.frame_rate=0 (requires restart).
// If swapInt is 1, then glSwapBuffers will block and wait for a vblank signal.
// When we're iterating as fast as possible, however, we want a non-blocking
// glSwapBuffers, which will happen when swapInt==0.
GLint swapInt = gfxPrefs::LayoutFrameRate() == 0 ? 0 : 1;
[mContext setValues:&swapInt forParameter:NSOpenGLCPSwapInterval];
}
return true;
bool GLContextCGL::MakeCurrentImpl() const {
if (mContext) {
[mContext makeCurrentContext];
MOZ_ASSERT(IsCurrentImpl());
// Use non-blocking swap in "ASAP mode".
// ASAP mode means that rendering is iterated as fast as possible.
// ASAP mode is entered when layout.frame_rate=0 (requires restart).
// If swapInt is 1, then glSwapBuffers will block and wait for a vblank signal.
// When we're iterating as fast as possible, however, we want a non-blocking
// glSwapBuffers, which will happen when swapInt==0.
GLint swapInt = gfxPrefs::LayoutFrameRate() == 0 ? 0 : 1;
[mContext setValues:&swapInt forParameter:NSOpenGLCPSwapInterval];
}
return true;
}
bool
GLContextCGL::IsCurrentImpl() const
{
return [NSOpenGLContext currentContext] == mContext;
}
bool GLContextCGL::IsCurrentImpl() const { return [NSOpenGLContext currentContext] == mContext; }
GLenum
GLContextCGL::GetPreferredARGB32Format() const
{
return LOCAL_GL_BGRA;
}
GLenum GLContextCGL::GetPreferredARGB32Format() const { return LOCAL_GL_BGRA; }
bool
GLContextCGL::SetupLookupFunction()
{
return false;
}
bool GLContextCGL::SetupLookupFunction() { return false; }
bool
GLContextCGL::IsDoubleBuffered() const
{
return sCGLLibrary.UseDoubleBufferedWindows();
}
bool GLContextCGL::IsDoubleBuffered() const { return sCGLLibrary.UseDoubleBufferedWindows(); }
bool
GLContextCGL::SwapBuffers()
{
bool GLContextCGL::SwapBuffers() {
AUTO_PROFILER_LABEL("GLContextCGL::SwapBuffers", GRAPHICS);
[mContext flushBuffer];
return true;
}
void
GLContextCGL::GetWSIInfo(nsCString* const out) const
{
out->AppendLiteral("CGL");
}
void GLContextCGL::GetWSIInfo(nsCString* const out) const { out->AppendLiteral("CGL"); }
already_AddRefed<GLContext>
GLContextProviderCGL::CreateWrappingExisting(void*, void*)
{
return nullptr;
already_AddRefed<GLContext> GLContextProviderCGL::CreateWrappingExisting(void*, void*) {
return nullptr;
}
static const NSOpenGLPixelFormatAttribute kAttribs_singleBuffered[] = {
NSOpenGLPFAAllowOfflineRenderers,
0
};
NSOpenGLPFAAllowOfflineRenderers, 0};
static const NSOpenGLPixelFormatAttribute kAttribs_singleBuffered_accel[] = {
NSOpenGLPFAAccelerated,
NSOpenGLPFAAllowOfflineRenderers,
0
};
NSOpenGLPFAAccelerated, NSOpenGLPFAAllowOfflineRenderers, 0};
static const NSOpenGLPixelFormatAttribute kAttribs_doubleBuffered[] = {
NSOpenGLPFAAllowOfflineRenderers,
NSOpenGLPFADoubleBuffer,
0
};
NSOpenGLPFAAllowOfflineRenderers, NSOpenGLPFADoubleBuffer, 0};
static const NSOpenGLPixelFormatAttribute kAttribs_doubleBuffered_accel[] = {
NSOpenGLPFAAccelerated,
NSOpenGLPFAAllowOfflineRenderers,
NSOpenGLPFADoubleBuffer,
0
};
NSOpenGLPFAAccelerated, NSOpenGLPFAAllowOfflineRenderers, NSOpenGLPFADoubleBuffer, 0};
static const NSOpenGLPixelFormatAttribute kAttribs_doubleBuffered_accel_webrender[] = {
NSOpenGLPFAAccelerated,
@ -196,199 +147,177 @@ static const NSOpenGLPixelFormatAttribute kAttribs_doubleBuffered_accel_webrende
NSOpenGLPFADoubleBuffer,
NSOpenGLPFAOpenGLProfile,
NSOpenGLProfileVersion3_2Core,
NSOpenGLPFADepthSize, 24,
0
};
NSOpenGLPFADepthSize,
24,
0};
static NSOpenGLContext*
CreateWithFormat(const NSOpenGLPixelFormatAttribute* attribs)
{
NSOpenGLPixelFormat* format = [[NSOpenGLPixelFormat alloc]
initWithAttributes:attribs];
if (!format) {
NS_WARNING("Failed to create NSOpenGLPixelFormat.");
return nullptr;
}
static NSOpenGLContext* CreateWithFormat(const NSOpenGLPixelFormatAttribute* attribs) {
NSOpenGLPixelFormat* format = [[NSOpenGLPixelFormat alloc] initWithAttributes:attribs];
if (!format) {
NS_WARNING("Failed to create NSOpenGLPixelFormat.");
return nullptr;
}
NSOpenGLContext* context = [[NSOpenGLContext alloc] initWithFormat:format
shareContext:nullptr];
NSOpenGLContext* context = [[NSOpenGLContext alloc] initWithFormat:format shareContext:nullptr];
[format release];
[format release];
return context;
return context;
}
already_AddRefed<GLContext>
GLContextProviderCGL::CreateForCompositorWidget(CompositorWidget* aCompositorWidget, bool aForceAccelerated)
{
return CreateForWindow(aCompositorWidget->RealWidget(),
aCompositorWidget->GetCompositorOptions().UseWebRender(),
aForceAccelerated);
already_AddRefed<GLContext> GLContextProviderCGL::CreateForCompositorWidget(
CompositorWidget* aCompositorWidget, bool aForceAccelerated) {
return CreateForWindow(aCompositorWidget->RealWidget(),
aCompositorWidget->GetCompositorOptions().UseWebRender(),
aForceAccelerated);
}
already_AddRefed<GLContext>
GLContextProviderCGL::CreateForWindow(nsIWidget* aWidget,
bool aWebRender,
bool aForceAccelerated)
{
if (!sCGLLibrary.EnsureInitialized()) {
return nullptr;
}
already_AddRefed<GLContext> GLContextProviderCGL::CreateForWindow(nsIWidget* aWidget,
bool aWebRender,
bool aForceAccelerated) {
if (!sCGLLibrary.EnsureInitialized()) {
return nullptr;
}
#ifdef EMULATE_VM
if (aForceAccelerated) {
return nullptr;
}
if (aForceAccelerated) {
return nullptr;
}
#endif
const NSOpenGLPixelFormatAttribute* attribs;
if (sCGLLibrary.UseDoubleBufferedWindows()) {
if (aWebRender) {
attribs = aForceAccelerated ? kAttribs_doubleBuffered_accel_webrender : kAttribs_doubleBuffered;
} else {
attribs = aForceAccelerated ? kAttribs_doubleBuffered_accel : kAttribs_doubleBuffered;
}
const NSOpenGLPixelFormatAttribute* attribs;
if (sCGLLibrary.UseDoubleBufferedWindows()) {
if (aWebRender) {
attribs =
aForceAccelerated ? kAttribs_doubleBuffered_accel_webrender : kAttribs_doubleBuffered;
} else {
attribs = aForceAccelerated ? kAttribs_singleBuffered_accel : kAttribs_singleBuffered;
}
NSOpenGLContext* context = CreateWithFormat(attribs);
if (!context) {
return nullptr;
attribs = aForceAccelerated ? kAttribs_doubleBuffered_accel : kAttribs_doubleBuffered;
}
} else {
attribs = aForceAccelerated ? kAttribs_singleBuffered_accel : kAttribs_singleBuffered;
}
NSOpenGLContext* context = CreateWithFormat(attribs);
if (!context) {
return nullptr;
}
GLint opaque = gfxPrefs::CompositorGLContextOpaque();
[context setValues:&opaque forParameter:NSOpenGLCPSurfaceOpacity];
GLint opaque = gfxPrefs::CompositorGLContextOpaque();
[context setValues:&opaque forParameter:NSOpenGLCPSurfaceOpacity];
RefPtr<GLContextCGL> glContext = new GLContextCGL(CreateContextFlags::NONE,
SurfaceCaps::ForRGBA(), context,
false);
RefPtr<GLContextCGL> glContext =
new GLContextCGL(CreateContextFlags::NONE, SurfaceCaps::ForRGBA(), context, false);
if (!glContext->Init()) {
glContext = nullptr;
[context release];
return nullptr;
}
if (!glContext->Init()) {
glContext = nullptr;
[context release];
return nullptr;
}
return glContext.forget();
return glContext.forget();
}
static already_AddRefed<GLContextCGL>
CreateOffscreenFBOContext(CreateContextFlags flags)
{
if (!sCGLLibrary.EnsureInitialized()) {
return nullptr;
}
static already_AddRefed<GLContextCGL> CreateOffscreenFBOContext(CreateContextFlags flags) {
if (!sCGLLibrary.EnsureInitialized()) {
return nullptr;
}
NSOpenGLContext* context = nullptr;
NSOpenGLContext* context = nullptr;
std::vector<NSOpenGLPixelFormatAttribute> attribs;
std::vector<NSOpenGLPixelFormatAttribute> attribs;
if (flags & CreateContextFlags::ALLOW_OFFLINE_RENDERER ||
!(flags & CreateContextFlags::HIGH_POWER))
{
// This is really poorly named on Apple's part, but "AllowOfflineRenderers" means
// that we want to allow running on the iGPU instead of requiring the dGPU.
attribs.push_back(NSOpenGLPFAAllowOfflineRenderers);
}
if (flags & CreateContextFlags::ALLOW_OFFLINE_RENDERER ||
!(flags & CreateContextFlags::HIGH_POWER)) {
// This is really poorly named on Apple's part, but "AllowOfflineRenderers" means
// that we want to allow running on the iGPU instead of requiring the dGPU.
attribs.push_back(NSOpenGLPFAAllowOfflineRenderers);
}
if (gfxPrefs::RequireHardwareGL()) {
attribs.push_back(NSOpenGLPFAAccelerated);
}
if (gfxPrefs::RequireHardwareGL()) {
attribs.push_back(NSOpenGLPFAAccelerated);
}
if (!(flags & CreateContextFlags::REQUIRE_COMPAT_PROFILE)) {
auto coreAttribs = attribs;
coreAttribs.push_back(NSOpenGLPFAOpenGLProfile);
coreAttribs.push_back(NSOpenGLProfileVersion3_2Core);
coreAttribs.push_back(0);
context = CreateWithFormat(coreAttribs.data());
}
if (!(flags & CreateContextFlags::REQUIRE_COMPAT_PROFILE)) {
auto coreAttribs = attribs;
coreAttribs.push_back(NSOpenGLPFAOpenGLProfile);
coreAttribs.push_back(NSOpenGLProfileVersion3_2Core);
coreAttribs.push_back(0);
context = CreateWithFormat(coreAttribs.data());
}
if (!context) {
attribs.push_back(0);
context = CreateWithFormat(attribs.data());
}
if (!context) {
attribs.push_back(0);
context = CreateWithFormat(attribs.data());
}
if (!context) {
NS_WARNING("Failed to create NSOpenGLContext.");
return nullptr;
}
if (!context) {
NS_WARNING("Failed to create NSOpenGLContext.");
return nullptr;
}
RefPtr<GLContextCGL> glContext = new GLContextCGL(flags, SurfaceCaps::Any(), context,
true);
RefPtr<GLContextCGL> glContext = new GLContextCGL(flags, SurfaceCaps::Any(), context, true);
if (gfxPrefs::GLMultithreaded()) {
CGLEnable(glContext->GetCGLContext(), kCGLCEMPEngine);
}
return glContext.forget();
if (gfxPrefs::GLMultithreaded()) {
CGLEnable(glContext->GetCGLContext(), kCGLCEMPEngine);
}
return glContext.forget();
}
already_AddRefed<GLContext>
GLContextProviderCGL::CreateHeadless(CreateContextFlags flags,
nsACString* const out_failureId)
{
RefPtr<GLContextCGL> gl;
gl = CreateOffscreenFBOContext(flags);
if (!gl) {
*out_failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_CGL_FBO");
return nullptr;
}
already_AddRefed<GLContext> GLContextProviderCGL::CreateHeadless(CreateContextFlags flags,
nsACString* const out_failureId) {
RefPtr<GLContextCGL> gl;
gl = CreateOffscreenFBOContext(flags);
if (!gl) {
*out_failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_CGL_FBO");
return nullptr;
}
if (!gl->Init()) {
*out_failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_CGL_INIT");
NS_WARNING("Failed during Init.");
return nullptr;
}
if (!gl->Init()) {
*out_failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_CGL_INIT");
NS_WARNING("Failed during Init.");
return nullptr;
}
return gl.forget();
return gl.forget();
}
already_AddRefed<GLContext>
GLContextProviderCGL::CreateOffscreen(const IntSize& size,
const SurfaceCaps& minCaps,
CreateContextFlags flags,
nsACString* const out_failureId)
{
RefPtr<GLContext> gl = CreateHeadless(flags, out_failureId);
if (!gl) {
return nullptr;
}
already_AddRefed<GLContext> GLContextProviderCGL::CreateOffscreen(const IntSize& size,
const SurfaceCaps& minCaps,
CreateContextFlags flags,
nsACString* const out_failureId) {
RefPtr<GLContext> gl = CreateHeadless(flags, out_failureId);
if (!gl) {
return nullptr;
}
if (!gl->InitOffscreen(size, minCaps)) {
*out_failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_CGL_INIT");
return nullptr;
}
if (!gl->InitOffscreen(size, minCaps)) {
*out_failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_CGL_INIT");
return nullptr;
}
return gl.forget();
return gl.forget();
}
static RefPtr<GLContext> gGlobalContext;
GLContext*
GLContextProviderCGL::GetGlobalContext()
{
static bool triedToCreateContext = false;
if (!triedToCreateContext) {
triedToCreateContext = true;
GLContext* GLContextProviderCGL::GetGlobalContext() {
static bool triedToCreateContext = false;
if (!triedToCreateContext) {
triedToCreateContext = true;
MOZ_RELEASE_ASSERT(!gGlobalContext);
nsCString discardFailureId;
RefPtr<GLContext> temp = CreateHeadless(CreateContextFlags::NONE,
&discardFailureId);
gGlobalContext = temp;
MOZ_RELEASE_ASSERT(!gGlobalContext);
nsCString discardFailureId;
RefPtr<GLContext> temp = CreateHeadless(CreateContextFlags::NONE, &discardFailureId);
gGlobalContext = temp;
if (!gGlobalContext) {
NS_WARNING("Couldn't init gGlobalContext.");
}
if (!gGlobalContext) {
NS_WARNING("Couldn't init gGlobalContext.");
}
}
return gGlobalContext;
return gGlobalContext;
}
void
GLContextProviderCGL::Shutdown()
{
gGlobalContext = nullptr;
}
void GLContextProviderCGL::Shutdown() { gGlobalContext = nullptr; }
} /* namespace gl */
} /* namespace mozilla */

View File

@ -23,256 +23,202 @@ namespace gl {
using namespace mozilla::widget;
GLContextEAGL::GLContextEAGL(CreateContextFlags flags, const SurfaceCaps& caps,
EAGLContext* context, GLContext* sharedContext,
bool isOffscreen)
: GLContext(flags, caps, sharedContext, isOffscreen)
, mContext(context)
{
EAGLContext* context, GLContext* sharedContext, bool isOffscreen)
: GLContext(flags, caps, sharedContext, isOffscreen), mContext(context) {}
GLContextEAGL::~GLContextEAGL() {
MakeCurrent();
if (mBackbufferFB) {
fDeleteFramebuffers(1, &mBackbufferFB);
}
if (mBackbufferRB) {
fDeleteRenderbuffers(1, &mBackbufferRB);
}
MarkDestroyed();
if (mLayer) {
mLayer = nil;
}
if (mContext) {
[EAGLContext setCurrentContext:nil];
[mContext release];
}
}
GLContextEAGL::~GLContextEAGL()
{
MakeCurrent();
bool GLContextEAGL::Init() {
if (!InitWithPrefix("gl", true)) return false;
if (mBackbufferFB) {
fDeleteFramebuffers(1, &mBackbufferFB);
}
if (mBackbufferRB) {
fDeleteRenderbuffers(1, &mBackbufferRB);
}
MarkDestroyed();
if (mLayer) {
mLayer = nil;
}
if (mContext) {
[EAGLContext setCurrentContext:nil];
[mContext release];
return true;
}
bool GLContextEAGL::AttachToWindow(nsIWidget* aWidget) {
// This should only be called once
MOZ_ASSERT(!mBackbufferFB && !mBackbufferRB);
UIView* view = reinterpret_cast<UIView*>(aWidget->GetNativeData(NS_NATIVE_WIDGET));
if (!view) {
MOZ_CRASH("no view!");
}
mLayer = [view layer];
fGenFramebuffers(1, &mBackbufferFB);
return RecreateRB();
}
bool GLContextEAGL::RecreateRB() {
MakeCurrent();
CAEAGLLayer* layer = (CAEAGLLayer*)mLayer;
if (mBackbufferRB) {
// It doesn't seem to be enough to just call renderbufferStorage: below,
// we apparently have to recreate the RB.
fDeleteRenderbuffers(1, &mBackbufferRB);
mBackbufferRB = 0;
}
fGenRenderbuffers(1, &mBackbufferRB);
fBindRenderbuffer(LOCAL_GL_RENDERBUFFER, mBackbufferRB);
[mContext renderbufferStorage:LOCAL_GL_RENDERBUFFER fromDrawable:layer];
fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, mBackbufferFB);
fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_COLOR_ATTACHMENT0, LOCAL_GL_RENDERBUFFER,
mBackbufferRB);
return LOCAL_GL_FRAMEBUFFER_COMPLETE == fCheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER);
}
bool GLContextEAGL::MakeCurrentImpl() const {
if (mContext) {
if (![EAGLContext setCurrentContext:mContext]) {
return false;
}
}
return true;
}
bool
GLContextEAGL::Init()
{
if (!InitWithPrefix("gl", true))
return false;
bool GLContextEAGL::IsCurrentImpl() const { return [EAGLContext currentContext] == mContext; }
return true;
}
bool GLContextEAGL::SetupLookupFunction() { return false; }
bool
GLContextEAGL::AttachToWindow(nsIWidget* aWidget)
{
// This should only be called once
MOZ_ASSERT(!mBackbufferFB && !mBackbufferRB);
bool GLContextEAGL::IsDoubleBuffered() const { return true; }
UIView* view =
reinterpret_cast<UIView*>(aWidget->GetNativeData(NS_NATIVE_WIDGET));
if (!view) {
MOZ_CRASH("no view!");
}
mLayer = [view layer];
fGenFramebuffers(1, &mBackbufferFB);
return RecreateRB();
}
bool
GLContextEAGL::RecreateRB()
{
MakeCurrent();
CAEAGLLayer* layer = (CAEAGLLayer*)mLayer;
if (mBackbufferRB) {
// It doesn't seem to be enough to just call renderbufferStorage: below,
// we apparently have to recreate the RB.
fDeleteRenderbuffers(1, &mBackbufferRB);
mBackbufferRB = 0;
}
fGenRenderbuffers(1, &mBackbufferRB);
fBindRenderbuffer(LOCAL_GL_RENDERBUFFER, mBackbufferRB);
[mContext renderbufferStorage:LOCAL_GL_RENDERBUFFER
fromDrawable:layer];
fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, mBackbufferFB);
fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_COLOR_ATTACHMENT0,
LOCAL_GL_RENDERBUFFER, mBackbufferRB);
return LOCAL_GL_FRAMEBUFFER_COMPLETE == fCheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER);
}
bool
GLContextEAGL::MakeCurrentImpl() const
{
if (mContext) {
if(![EAGLContext setCurrentContext:mContext]) {
return false;
}
}
return true;
}
bool
GLContextEAGL::IsCurrentImpl() const
{
return [EAGLContext currentContext] == mContext;
}
bool
GLContextEAGL::SetupLookupFunction()
{
return false;
}
bool
GLContextEAGL::IsDoubleBuffered() const
{
return true;
}
bool
GLContextEAGL::SwapBuffers()
{
bool GLContextEAGL::SwapBuffers() {
AUTO_PROFILER_LABEL("GLContextEAGL::SwapBuffers", GRAPHICS);
[mContext presentRenderbuffer:LOCAL_GL_RENDERBUFFER];
return true;
}
void
GLContextEAGL::GetWSIInfo(nsCString* const out) const
{
out->AppendLiteral("EAGL");
void GLContextEAGL::GetWSIInfo(nsCString* const out) const { out->AppendLiteral("EAGL"); }
already_AddRefed<GLContext> GLContextProviderEAGL::CreateWrappingExisting(void*, void*) {
return nullptr;
}
already_AddRefed<GLContext>
GLContextProviderEAGL::CreateWrappingExisting(void*, void*)
{
static GLContextEAGL* GetGlobalContextEAGL() {
return static_cast<GLContextEAGL*>(GLContextProviderEAGL::GetGlobalContext());
}
static already_AddRefed<GLContext> CreateEAGLContext(CreateContextFlags flags, bool aOffscreen,
GLContextEAGL* sharedContext) {
EAGLRenderingAPI apis[] = {kEAGLRenderingAPIOpenGLES3, kEAGLRenderingAPIOpenGLES2};
// Try to create a GLES3 context if we can, otherwise fall back to GLES2
EAGLContext* context = nullptr;
for (EAGLRenderingAPI api : apis) {
if (sharedContext) {
context = [[EAGLContext alloc] initWithAPI:api
sharegroup:sharedContext->GetEAGLContext().sharegroup];
} else {
context = [[EAGLContext alloc] initWithAPI:api];
}
if (context) {
break;
}
}
if (!context) {
return nullptr;
}
RefPtr<GLContextEAGL> glContext =
new GLContextEAGL(flags, SurfaceCaps::ForRGBA(), context, sharedContext, aOffscreen);
if (!glContext->Init()) {
glContext = nullptr;
return nullptr;
}
return glContext.forget();
}
static GLContextEAGL*
GetGlobalContextEAGL()
{
return static_cast<GLContextEAGL*>(GLContextProviderEAGL::GetGlobalContext());
already_AddRefed<GLContext> GLContextProviderEAGL::CreateForCompositorWidget(
CompositorWidget* aCompositorWidget, bool aForceAccelerated) {
return CreateForWindow(aCompositorWidget->RealWidget(),
aCompositorWidget->GetCompositorOptions().UseWebRender(),
aForceAccelerated);
}
static already_AddRefed<GLContext>
CreateEAGLContext(CreateContextFlags flags, bool aOffscreen, GLContextEAGL* sharedContext)
{
EAGLRenderingAPI apis[] = { kEAGLRenderingAPIOpenGLES3, kEAGLRenderingAPIOpenGLES2 };
already_AddRefed<GLContext> GLContextProviderEAGL::CreateForWindow(nsIWidget* aWidget,
bool aWebRender,
bool aForceAccelerated) {
RefPtr<GLContext> glContext =
CreateEAGLContext(CreateContextFlags::NONE, false, GetGlobalContextEAGL());
if (!glContext) {
return nullptr;
}
// Try to create a GLES3 context if we can, otherwise fall back to GLES2
EAGLContext* context = nullptr;
for (EAGLRenderingAPI api : apis) {
if (sharedContext) {
context = [[EAGLContext alloc] initWithAPI:api
sharegroup:sharedContext->GetEAGLContext().sharegroup];
} else {
context = [[EAGLContext alloc] initWithAPI:api];
}
if (!GLContextEAGL::Cast(glContext)->AttachToWindow(aWidget)) {
return nullptr;
}
if (context) {
break;
}
}
if (!context) {
return nullptr;
}
RefPtr<GLContextEAGL> glContext = new GLContextEAGL(flags, SurfaceCaps::ForRGBA(),
context, sharedContext,
aOffscreen);
if (!glContext->Init()) {
glContext = nullptr;
return nullptr;
}
return glContext.forget();
return glContext.forget();
}
already_AddRefed<GLContext>
GLContextProviderEAGL::CreateForCompositorWidget(CompositorWidget* aCompositorWidget, bool aForceAccelerated)
{
return CreateForWindow(aCompositorWidget->RealWidget(),
aCompositorWidget->GetCompositorOptions().UseWebRender(),
aForceAccelerated);
already_AddRefed<GLContext> GLContextProviderEAGL::CreateHeadless(CreateContextFlags flags,
nsACString* const out_failureId) {
return CreateEAGLContext(flags, true, GetGlobalContextEAGL());
}
already_AddRefed<GLContext>
GLContextProviderEAGL::CreateForWindow(nsIWidget* aWidget,
bool aWebRender,
bool aForceAccelerated)
{
RefPtr<GLContext> glContext = CreateEAGLContext(CreateContextFlags::NONE, false,
GetGlobalContextEAGL());
if (!glContext) {
return nullptr;
}
already_AddRefed<GLContext> GLContextProviderEAGL::CreateOffscreen(
const mozilla::gfx::IntSize& size, const SurfaceCaps& caps, CreateContextFlags flags,
nsACString* const out_failureId) {
RefPtr<GLContext> glContext = CreateHeadless(flags, out_failureId);
if (!glContext->InitOffscreen(size, caps)) {
return nullptr;
}
if (!GLContextEAGL::Cast(glContext)->AttachToWindow(aWidget)) {
return nullptr;
}
return glContext.forget();
}
already_AddRefed<GLContext>
GLContextProviderEAGL::CreateHeadless(CreateContextFlags flags,
nsACString* const out_failureId)
{
return CreateEAGLContext(flags, true, GetGlobalContextEAGL());
}
already_AddRefed<GLContext>
GLContextProviderEAGL::CreateOffscreen(const mozilla::gfx::IntSize& size,
const SurfaceCaps& caps,
CreateContextFlags flags,
nsACString* const out_failureId)
{
RefPtr<GLContext> glContext = CreateHeadless(flags, out_failureId);
if (!glContext->InitOffscreen(size, caps)) {
return nullptr;
}
return glContext.forget();
return glContext.forget();
}
static RefPtr<GLContext> gGlobalContext;
GLContext*
GLContextProviderEAGL::GetGlobalContext()
{
static bool triedToCreateContext = false;
if (!triedToCreateContext) {
triedToCreateContext = true;
GLContext* GLContextProviderEAGL::GetGlobalContext() {
static bool triedToCreateContext = false;
if (!triedToCreateContext) {
triedToCreateContext = true;
MOZ_RELEASE_ASSERT(!gGlobalContext, "GFX: Global GL context already initialized.");
RefPtr<GLContext> temp = CreateHeadless(CreateContextFlags::NONE);
gGlobalContext = temp;
MOZ_RELEASE_ASSERT(!gGlobalContext, "GFX: Global GL context already initialized.");
RefPtr<GLContext> temp = CreateHeadless(CreateContextFlags::NONE);
gGlobalContext = temp;
if (!gGlobalContext) {
MOZ_CRASH("Failed to create global context");
}
if (!gGlobalContext) {
MOZ_CRASH("Failed to create global context");
}
}
return gGlobalContext;
return gGlobalContext;
}
void
GLContextProviderEAGL::Shutdown()
{
gGlobalContext = nullptr;
}
void GLContextProviderEAGL::Shutdown() { gGlobalContext = nullptr; }
} /* namespace gl */
} /* namespace mozilla */

View File

@ -13,60 +13,46 @@
namespace mozilla {
namespace gfx {
PrintTargetCG::PrintTargetCG(PMPrintSession aPrintSession,
PMPageFormat aPageFormat,
PMPrintSettings aPrintSettings,
const IntSize& aSize)
: PrintTarget(/* aCairoSurface */ nullptr, aSize)
, mPrintSession(aPrintSession)
, mPageFormat(aPageFormat)
, mPrintSettings(aPrintSettings)
{
PrintTargetCG::PrintTargetCG(PMPrintSession aPrintSession, PMPageFormat aPageFormat,
PMPrintSettings aPrintSettings, const IntSize& aSize)
: PrintTarget(/* aCairoSurface */ nullptr, aSize),
mPrintSession(aPrintSession),
mPageFormat(aPageFormat),
mPrintSettings(aPrintSettings) {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
::PMRetain(mPrintSession);
// TODO: Add memory reporting like gfxQuartzSurface.
//RecordMemoryUsed(mSize.height * 4 + sizeof(gfxQuartzSurface));
// RecordMemoryUsed(mSize.height * 4 + sizeof(gfxQuartzSurface));
NS_OBJC_END_TRY_ABORT_BLOCK;
}
PrintTargetCG::~PrintTargetCG()
{
PrintTargetCG::~PrintTargetCG() {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
if (mPrintSession)
::PMRelease(mPrintSession);
if (mPrintSession) ::PMRelease(mPrintSession);
NS_OBJC_END_TRY_ABORT_BLOCK;
}
/* static */ already_AddRefed<PrintTargetCG>
PrintTargetCG::CreateOrNull(PMPrintSession aPrintSession,
PMPageFormat aPageFormat,
PMPrintSettings aPrintSettings,
const IntSize& aSize)
{
/* static */ already_AddRefed<PrintTargetCG> PrintTargetCG::CreateOrNull(
PMPrintSession aPrintSession, PMPageFormat aPageFormat, PMPrintSettings aPrintSettings,
const IntSize& aSize) {
if (!Factory::CheckSurfaceSize(aSize)) {
return nullptr;
}
RefPtr<PrintTargetCG> target = new PrintTargetCG(aPrintSession, aPageFormat,
aPrintSettings, aSize);
RefPtr<PrintTargetCG> target =
new PrintTargetCG(aPrintSession, aPageFormat, aPrintSettings, aSize);
return target.forget();
}
static size_t
PutBytesNull(void* info, const void* buffer, size_t count)
{
return count;
}
static size_t PutBytesNull(void* info, const void* buffer, size_t count) { return count; }
already_AddRefed<DrawTarget>
PrintTargetCG::GetReferenceDrawTarget()
{
already_AddRefed<DrawTarget> PrintTargetCG::GetReferenceDrawTarget() {
if (!mRefDT) {
const IntSize size(1, 1);
@ -76,8 +62,7 @@ PrintTargetCG::GetReferenceDrawTarget()
CGDataConsumerRelease(consumer);
cairo_surface_t* similar =
cairo_quartz_surface_create_for_cg_context(
pdfContext, size.width, size.height);
cairo_quartz_surface_create_for_cg_context(pdfContext, size.width, size.height);
CGContextRelease(pdfContext);
@ -85,8 +70,7 @@ PrintTargetCG::GetReferenceDrawTarget()
return nullptr;
}
RefPtr<DrawTarget> dt =
Factory::CreateDrawTargetForCairoSurface(similar, size);
RefPtr<DrawTarget> dt = Factory::CreateDrawTargetForCairoSurface(similar, size);
// The DT addrefs the surface, so we need drop our own reference to it:
cairo_surface_destroy(similar);
@ -100,12 +84,8 @@ PrintTargetCG::GetReferenceDrawTarget()
return do_AddRef(mRefDT);
}
nsresult
PrintTargetCG::BeginPrinting(const nsAString& aTitle,
const nsAString& aPrintToFileName,
int32_t aStartPage,
int32_t aEndPage)
{
nsresult PrintTargetCG::BeginPrinting(const nsAString& aTitle, const nsAString& aPrintToFileName,
int32_t aStartPage, int32_t aEndPage) {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
OSStatus status;
@ -121,9 +101,7 @@ PrintTargetCG::BeginPrinting(const nsAString& aTitle,
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
}
nsresult
PrintTargetCG::EndPrinting()
{
nsresult PrintTargetCG::EndPrinting() {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
::PMSessionEndDocumentNoDialog(mPrintSession);
@ -132,18 +110,14 @@ PrintTargetCG::EndPrinting()
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
}
nsresult
PrintTargetCG::AbortPrinting()
{
nsresult PrintTargetCG::AbortPrinting() {
#ifdef DEBUG
mHasActivePage = false;
#endif
return EndPrinting();
}
nsresult
PrintTargetCG::BeginPage()
{
nsresult PrintTargetCG::BeginPage() {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
PMSessionError(mPrintSession);
@ -169,8 +143,7 @@ PrintTargetCG::BeginPage()
CGContextTranslateCTM(context, 0, height);
CGContextScaleCTM(context, 1.0, -1.0);
cairo_surface_t* surface =
cairo_quartz_surface_create_for_cg_context(context, width, height);
cairo_surface_t* surface = cairo_quartz_surface_create_for_cg_context(context, width, height);
if (cairo_surface_status(surface)) {
return NS_ERROR_FAILURE;
@ -183,9 +156,7 @@ PrintTargetCG::BeginPage()
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
}
nsresult
PrintTargetCG::EndPage()
{
nsresult PrintTargetCG::EndPage() {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
cairo_surface_finish(mCairoSurface);
@ -201,5 +172,5 @@ PrintTargetCG::EndPage()
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
}
} // namespace gfx
} // namespace mozilla
} // namespace gfx
} // namespace mozilla

File diff suppressed because it is too large Load Diff

View File

@ -15,31 +15,27 @@
using namespace mozilla::hal;
namespace mozilla {
namespace hal_impl {
static nsITimer* sUpdateTimer = nullptr;
static nsITimer *sUpdateTimer = nullptr;
static bool sActiveSensors[NUM_SENSOR_TYPE];
static io_connect_t sDataPort = IO_OBJECT_NULL;
static uint64_t sLastMean = -1;
static float
LMUvalueToLux(uint64_t aValue)
{
//Conversion formula from regression. See Bug 793728.
static float LMUvalueToLux(uint64_t aValue) {
// Conversion formula from regression. See Bug 793728.
// -3*(10^-27)*x^4 + 2.6*(10^-19)*x^3 + -3.4*(10^-12)*x^2 + 3.9*(10^-5)*x - 0.19
long double powerC4 = 1/pow((long double)10,27);
long double powerC3 = 1/pow((long double)10,19);
long double powerC2 = 1/pow((long double)10,12);
long double powerC1 = 1/pow((long double)10,5);
long double powerC4 = 1 / pow((long double)10, 27);
long double powerC3 = 1 / pow((long double)10, 19);
long double powerC2 = 1 / pow((long double)10, 12);
long double powerC1 = 1 / pow((long double)10, 5);
long double term4 = -3.0 * powerC4 * pow(aValue,4);
long double term3 = 2.6 * powerC3 * pow(aValue,3);
long double term2 = -3.4 * powerC2 * pow(aValue,2);
long double term1 = 3.9 * powerC1 * aValue;
long double term4 = -3.0 * powerC4 * pow(aValue, 4);
long double term3 = 2.6 * powerC3 * pow(aValue, 3);
long double term2 = -3.4 * powerC2 * pow(aValue, 2);
long double term1 = 3.9 * powerC1 * aValue;
float lux = ceil(static_cast<float>(term4 + term3 + term2 + term1 - 0.19));
return lux > 0 ? lux : 0;
}
void
UpdateHandler(nsITimer *aTimer, void *aClosure)
{
void UpdateHandler(nsITimer *aTimer, void *aClosure) {
for (int i = 0; i < NUM_SENSOR_TYPE; i++) {
if (!sActiveSensors[i]) {
continue;
@ -71,15 +67,11 @@ UpdateHandler(nsITimer *aTimer, void *aClosure)
}
}
hal::SensorData sdata(sensor,
PR_Now(),
values);
hal::SensorData sdata(sensor, PR_Now(), values);
hal::NotifySensorChange(sdata);
}
}
void
EnableSensorNotifications(SensorType aSensor)
{
void EnableSensorNotifications(SensorType aSensor) {
if (aSensor == SENSOR_ACCELERATION) {
int result = smsStartup(nil, nil);
@ -92,8 +84,8 @@ EnableSensorNotifications(SensorType aSensor)
}
} else if (aSensor == SENSOR_LIGHT) {
io_service_t serviceObject;
serviceObject = IOServiceGetMatchingService(kIOMasterPortDefault,
IOServiceMatching("AppleLMUController"));
serviceObject =
IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("AppleLMUController"));
if (!serviceObject) {
return;
}
@ -112,17 +104,13 @@ EnableSensorNotifications(SensorType aSensor)
if (!sUpdateTimer) {
CallCreateInstance("@mozilla.org/timer;1", &sUpdateTimer);
if (sUpdateTimer) {
sUpdateTimer->InitWithNamedFuncCallback(UpdateHandler,
nullptr,
DEFAULT_SENSOR_POLL,
nsITimer::TYPE_REPEATING_SLACK,
"hal_impl::UpdateHandler");
sUpdateTimer->InitWithNamedFuncCallback(UpdateHandler, nullptr, DEFAULT_SENSOR_POLL,
nsITimer::TYPE_REPEATING_SLACK,
"hal_impl::UpdateHandler");
}
}
}
void
DisableSensorNotifications(SensorType aSensor)
{
void DisableSensorNotifications(SensorType aSensor) {
if (!sActiveSensors[aSensor] || (aSensor != SENSOR_ACCELERATION && aSensor != SENSOR_LIGHT)) {
return;
}
@ -145,5 +133,5 @@ DisableSensorNotifications(SensorType aSensor)
NS_RELEASE(sUpdateTimer);
}
}
} // namespace hal_impl
} // namespace mozilla
} // namespace hal_impl
} // namespace mozilla

File diff suppressed because it is too large Load Diff

View File

@ -32,27 +32,17 @@
#include <Cocoa/Cocoa.h>
// nsIconChannel methods
nsIconChannel::nsIconChannel()
{
}
nsIconChannel::nsIconChannel() {}
nsIconChannel::~nsIconChannel()
{
nsIconChannel::~nsIconChannel() {
if (mLoadInfo) {
NS_ReleaseOnMainThreadSystemGroup(
"nsIconChannel::mLoadInfo", mLoadInfo.forget());
NS_ReleaseOnMainThreadSystemGroup("nsIconChannel::mLoadInfo", mLoadInfo.forget());
}
}
NS_IMPL_ISUPPORTS(nsIconChannel,
nsIChannel,
nsIRequest,
nsIRequestObserver,
nsIStreamListener)
NS_IMPL_ISUPPORTS(nsIconChannel, nsIChannel, nsIRequest, nsIRequestObserver, nsIStreamListener)
nsresult
nsIconChannel::Init(nsIURI* uri)
{
nsresult nsIconChannel::Init(nsIURI* uri) {
NS_ASSERTION(uri, "no uri");
mUrl = uri;
mOriginalURI = uri;
@ -65,46 +55,26 @@ nsIconChannel::Init(nsIURI* uri)
// nsIRequest methods:
NS_IMETHODIMP
nsIconChannel::GetName(nsACString& result)
{
return mUrl->GetSpec(result);
}
nsIconChannel::GetName(nsACString& result) { return mUrl->GetSpec(result); }
NS_IMETHODIMP
nsIconChannel::IsPending(bool* result)
{
return mPump->IsPending(result);
}
nsIconChannel::IsPending(bool* result) { return mPump->IsPending(result); }
NS_IMETHODIMP
nsIconChannel::GetStatus(nsresult* status)
{
return mPump->GetStatus(status);
}
nsIconChannel::GetStatus(nsresult* status) { return mPump->GetStatus(status); }
NS_IMETHODIMP
nsIconChannel::Cancel(nsresult status)
{
return mPump->Cancel(status);
}
nsIconChannel::Cancel(nsresult status) { return mPump->Cancel(status); }
NS_IMETHODIMP
nsIconChannel::Suspend(void)
{
return mPump->Suspend();
}
nsIconChannel::Suspend(void) { return mPump->Suspend(); }
NS_IMETHODIMP
nsIconChannel::Resume(void)
{
return mPump->Resume();
}
nsIconChannel::Resume(void) { return mPump->Resume(); }
// nsIRequestObserver methods
NS_IMETHODIMP
nsIconChannel::OnStartRequest(nsIRequest* aRequest,
nsISupports* aContext)
{
nsIconChannel::OnStartRequest(nsIRequest* aRequest, nsISupports* aContext) {
if (mListener) {
return mListener->OnStartRequest(this, aContext);
}
@ -112,10 +82,7 @@ nsIconChannel::OnStartRequest(nsIRequest* aRequest,
}
NS_IMETHODIMP
nsIconChannel::OnStopRequest(nsIRequest* aRequest,
nsISupports* aContext,
nsresult aStatus)
{
nsIconChannel::OnStopRequest(nsIRequest* aRequest, nsISupports* aContext, nsresult aStatus) {
if (mListener) {
mListener->OnStopRequest(this, aContext, aStatus);
mListener = nullptr;
@ -131,12 +98,8 @@ nsIconChannel::OnStopRequest(nsIRequest* aRequest,
// nsIStreamListener methods
NS_IMETHODIMP
nsIconChannel::OnDataAvailable(nsIRequest* aRequest,
nsISupports* aContext,
nsIInputStream* aStream,
uint64_t aOffset,
uint32_t aCount)
{
nsIconChannel::OnDataAvailable(nsIRequest* aRequest, nsISupports* aContext, nsIInputStream* aStream,
uint64_t aOffset, uint32_t aCount) {
if (mListener) {
return mListener->OnDataAvailable(this, aContext, aStream, aOffset, aCount);
}
@ -147,52 +110,42 @@ nsIconChannel::OnDataAvailable(nsIRequest* aRequest,
// nsIChannel methods:
NS_IMETHODIMP
nsIconChannel::GetOriginalURI(nsIURI** aURI)
{
nsIconChannel::GetOriginalURI(nsIURI** aURI) {
*aURI = mOriginalURI;
NS_ADDREF(*aURI);
return NS_OK;
}
NS_IMETHODIMP
nsIconChannel::SetOriginalURI(nsIURI* aURI)
{
nsIconChannel::SetOriginalURI(nsIURI* aURI) {
NS_ENSURE_ARG_POINTER(aURI);
mOriginalURI = aURI;
return NS_OK;
}
NS_IMETHODIMP
nsIconChannel::GetURI(nsIURI** aURI)
{
nsIconChannel::GetURI(nsIURI** aURI) {
*aURI = mUrl;
NS_IF_ADDREF(*aURI);
return NS_OK;
}
NS_IMETHODIMP
nsIconChannel::Open(nsIInputStream** _retval)
{
return MakeInputStream(_retval, false);
}
nsIconChannel::Open(nsIInputStream** _retval) { return MakeInputStream(_retval, false); }
NS_IMETHODIMP
nsIconChannel::Open2(nsIInputStream** aStream)
{
nsIconChannel::Open2(nsIInputStream** aStream) {
nsCOMPtr<nsIStreamListener> listener;
nsresult rv = nsContentSecurityManager::doContentSecurityCheck(this, listener);
NS_ENSURE_SUCCESS(rv, rv);
return Open(aStream);
}
nsresult
nsIconChannel::ExtractIconInfoFromUrl(nsIFile** aLocalFile,
uint32_t* aDesiredImageSize,
nsresult nsIconChannel::ExtractIconInfoFromUrl(nsIFile** aLocalFile, uint32_t* aDesiredImageSize,
nsACString& aContentType,
nsACString& aFileExtension)
{
nsACString& aFileExtension) {
nsresult rv = NS_OK;
nsCOMPtr<nsIMozIconURI> iconURI (do_QueryInterface(mUrl, &rv));
nsCOMPtr<nsIMozIconURI> iconURI(do_QueryInterface(mUrl, &rv));
NS_ENSURE_SUCCESS(rv, rv);
iconURI->GetImageSize(aDesiredImageSize);
@ -210,7 +163,7 @@ nsIconChannel::ExtractIconInfoFromUrl(nsIFile** aLocalFile,
rv = fileURL->GetFile(getter_AddRefs(file));
if (NS_FAILED(rv) || !file) return NS_OK;
nsCOMPtr<nsILocalFileMac> localFileMac (do_QueryInterface(file, &rv));
nsCOMPtr<nsILocalFileMac> localFileMac(do_QueryInterface(file, &rv));
if (NS_FAILED(rv) || !localFileMac) return NS_OK;
*aLocalFile = file;
@ -220,31 +173,27 @@ nsIconChannel::ExtractIconInfoFromUrl(nsIFile** aLocalFile,
}
NS_IMETHODIMP
nsIconChannel::AsyncOpen(nsIStreamListener* aListener,
nsISupports* ctxt)
{
MOZ_ASSERT(!mLoadInfo ||
mLoadInfo->GetSecurityMode() == 0 ||
mLoadInfo->GetInitialSecurityCheckDone() ||
(mLoadInfo->GetSecurityMode() == nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL &&
nsContentUtils::IsSystemPrincipal(mLoadInfo->LoadingPrincipal())),
"security flags in loadInfo but asyncOpen2() not called");
nsIconChannel::AsyncOpen(nsIStreamListener* aListener, nsISupports* ctxt) {
MOZ_ASSERT(
!mLoadInfo || mLoadInfo->GetSecurityMode() == 0 || mLoadInfo->GetInitialSecurityCheckDone() ||
(mLoadInfo->GetSecurityMode() == nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL &&
nsContentUtils::IsSystemPrincipal(mLoadInfo->LoadingPrincipal())),
"security flags in loadInfo but asyncOpen2() not called");
nsCOMPtr<nsIInputStream> inStream;
nsresult rv = MakeInputStream(getter_AddRefs(inStream), true);
if (NS_FAILED(rv)) {
mCallbacks = nullptr;
return rv;
mCallbacks = nullptr;
return rv;
}
// Init our stream pump
nsCOMPtr<nsIEventTarget> target =
nsContentUtils::GetEventTargetByLoadInfo(mLoadInfo,
mozilla::TaskCategory::Other);
nsContentUtils::GetEventTargetByLoadInfo(mLoadInfo, mozilla::TaskCategory::Other);
rv = mPump->Init(inStream, 0, 0, false, target);
if (NS_FAILED(rv)) {
mCallbacks = nullptr;
return rv;
mCallbacks = nullptr;
return rv;
}
rv = mPump->AsyncRead(this, ctxt);
@ -256,36 +205,32 @@ nsIconChannel::AsyncOpen(nsIStreamListener* aListener,
mLoadGroup->AddRequest(this, nullptr);
}
} else {
mCallbacks = nullptr;
mCallbacks = nullptr;
}
return rv;
}
NS_IMETHODIMP
nsIconChannel::AsyncOpen2(nsIStreamListener* aListener)
{
nsIconChannel::AsyncOpen2(nsIStreamListener* aListener) {
nsCOMPtr<nsIStreamListener> listener = aListener;
nsresult rv = nsContentSecurityManager::doContentSecurityCheck(this, listener);
if (NS_FAILED(rv)) {
mCallbacks = nullptr;
return rv;
mCallbacks = nullptr;
return rv;
}
return AsyncOpen(listener, nullptr);
}
nsresult
nsIconChannel::MakeInputStream(nsIInputStream** _retval,
bool aNonBlocking)
{
nsresult nsIconChannel::MakeInputStream(nsIInputStream** _retval, bool aNonBlocking) {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
nsCString contentType;
nsAutoCString fileExt;
nsCOMPtr<nsIFile> fileloc; // file we want an icon for
nsCOMPtr<nsIFile> fileloc; // file we want an icon for
uint32_t desiredImageSize;
nsresult rv = ExtractIconInfoFromUrl(getter_AddRefs(fileloc),
&desiredImageSize, contentType, fileExt);
nsresult rv =
ExtractIconInfoFromUrl(getter_AddRefs(fileloc), &desiredImageSize, contentType, fileExt);
NS_ENSURE_SUCCESS(rv, rv);
bool fileExists = false;
@ -304,8 +249,7 @@ nsIconChannel::MakeInputStream(nsIInputStream** _retval,
CFURLRef macURL;
if (NS_SUCCEEDED(localFileMac->GetCFURL(&macURL))) {
iconImage = [[NSWorkspace sharedWorkspace]
iconForFile:[(NSURL*)macURL path]];
iconImage = [[NSWorkspace sharedWorkspace] iconForFile:[(NSURL*)macURL path]];
::CFRelease(macURL);
}
}
@ -318,8 +262,7 @@ nsIconChannel::MakeInputStream(nsIInputStream** _retval,
// If we still don't have an icon, get the generic document icon.
if (!iconImage) {
iconImage = [[NSWorkspace sharedWorkspace]
iconForFileType:NSFileTypeUnknown];
iconImage = [[NSWorkspace sharedWorkspace] iconForFileType:NSFileTypeUnknown];
}
if (!iconImage) {
@ -331,20 +274,18 @@ nsIconChannel::MakeInputStream(nsIInputStream** _retval,
[iconImage setSize:desiredSizeRect.size];
[iconImage lockFocus];
NSBitmapImageRep* bitmapRep = [[[NSBitmapImageRep alloc]
initWithFocusedViewRect:desiredSizeRect]
autorelease];
NSBitmapImageRep* bitmapRep =
[[[NSBitmapImageRep alloc] initWithFocusedViewRect:desiredSizeRect] autorelease];
[iconImage unlockFocus];
// we expect the following things to be true about our bitmapRep
NS_ENSURE_TRUE(![bitmapRep isPlanar] &&
// Not necessarily: on a HiDPI-capable system, we'll get
// a 2x bitmap
// (unsigned int)[bitmapRep bytesPerPlane] ==
// desiredImageSize * desiredImageSize * 4 &&
[bitmapRep bitsPerPixel] == 32 &&
[bitmapRep samplesPerPixel] == 4 &&
[bitmapRep hasAlpha] == YES,
// Not necessarily: on a HiDPI-capable system, we'll get
// a 2x bitmap
// (unsigned int)[bitmapRep bytesPerPlane] ==
// desiredImageSize * desiredImageSize * 4 &&
[bitmapRep bitsPerPixel] == 32 && [bitmapRep samplesPerPixel] == 4 &&
[bitmapRep hasAlpha] == YES,
NS_ERROR_UNEXPECTED);
// check what size we actually got, and ensure it isn't too big to return
@ -352,8 +293,7 @@ nsIconChannel::MakeInputStream(nsIInputStream** _retval,
NS_ENSURE_TRUE(actualImageSize < 256, NS_ERROR_UNEXPECTED);
// now we can validate the amount of data
NS_ENSURE_TRUE((unsigned int)[bitmapRep bytesPerPlane] ==
actualImageSize * actualImageSize * 4,
NS_ENSURE_TRUE((unsigned int)[bitmapRep bytesPerPlane] == actualImageSize * actualImageSize * 4,
NS_ERROR_UNEXPECTED);
// rgba, pre-multiplied data
@ -361,8 +301,8 @@ nsIconChannel::MakeInputStream(nsIInputStream** _retval,
// create our buffer
int32_t bufferCapacity = 2 + [bitmapRep bytesPerPlane];
AutoTArray<uint8_t, 3 + 16 * 16 * 5> iconBuffer; // initial size is for
// 16x16
AutoTArray<uint8_t, 3 + 16 * 16 * 5> iconBuffer; // initial size is for
// 16x16
iconBuffer.SetLength(bufferCapacity);
uint8_t* iconBufferPtr = iconBuffer.Elements();
@ -402,13 +342,12 @@ nsIconChannel::MakeInputStream(nsIInputStream** _retval,
// Now, create a pipe and stuff our data into it
nsCOMPtr<nsIInputStream> inStream;
nsCOMPtr<nsIOutputStream> outStream;
rv = NS_NewPipe(getter_AddRefs(inStream), getter_AddRefs(outStream),
bufferCapacity, bufferCapacity, aNonBlocking);
rv = NS_NewPipe(getter_AddRefs(inStream), getter_AddRefs(outStream), bufferCapacity,
bufferCapacity, aNonBlocking);
if (NS_SUCCEEDED(rv)) {
uint32_t written;
rv = outStream->Write((char*)iconBuffer.Elements(), bufferCapacity,
&written);
rv = outStream->Write((char*)iconBuffer.Elements(), bufferCapacity, &written);
if (NS_SUCCEEDED(rv)) {
NS_IF_ADDREF(*_retval = inStream);
}
@ -423,165 +362,136 @@ nsIconChannel::MakeInputStream(nsIInputStream** _retval,
}
NS_IMETHODIMP
nsIconChannel::GetLoadFlags(uint32_t* aLoadAttributes)
{
nsIconChannel::GetLoadFlags(uint32_t* aLoadAttributes) {
return mPump->GetLoadFlags(aLoadAttributes);
}
NS_IMETHODIMP
nsIconChannel::SetLoadFlags(uint32_t aLoadAttributes)
{
nsIconChannel::SetLoadFlags(uint32_t aLoadAttributes) {
return mPump->SetLoadFlags(aLoadAttributes);
}
NS_IMETHODIMP
nsIconChannel::GetIsDocument(bool *aIsDocument)
{
nsIconChannel::GetIsDocument(bool* aIsDocument) {
return NS_GetIsDocumentChannel(this, aIsDocument);
}
NS_IMETHODIMP
nsIconChannel::GetContentType(nsACString& aContentType)
{
nsIconChannel::GetContentType(nsACString& aContentType) {
aContentType.AssignLiteral(IMAGE_ICON_MS);
return NS_OK;
}
NS_IMETHODIMP
nsIconChannel::SetContentType(const nsACString& aContentType)
{
//It doesn't make sense to set the content-type on this type
nsIconChannel::SetContentType(const nsACString& aContentType) {
// It doesn't make sense to set the content-type on this type
// of channel...
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsIconChannel::GetContentCharset(nsACString& aContentCharset)
{
nsIconChannel::GetContentCharset(nsACString& aContentCharset) {
aContentCharset.AssignLiteral(IMAGE_ICON_MS);
return NS_OK;
}
NS_IMETHODIMP
nsIconChannel::SetContentCharset(const nsACString& aContentCharset)
{
//It doesn't make sense to set the content-type on this type
nsIconChannel::SetContentCharset(const nsACString& aContentCharset) {
// It doesn't make sense to set the content-type on this type
// of channel...
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsIconChannel::GetContentDisposition(uint32_t* aContentDisposition)
{
nsIconChannel::GetContentDisposition(uint32_t* aContentDisposition) {
return NS_ERROR_NOT_AVAILABLE;
}
NS_IMETHODIMP
nsIconChannel::SetContentDisposition(uint32_t aContentDisposition)
{
nsIconChannel::SetContentDisposition(uint32_t aContentDisposition) {
return NS_ERROR_NOT_AVAILABLE;
}
NS_IMETHODIMP
nsIconChannel::
GetContentDispositionFilename(nsAString& aContentDispositionFilename)
{
nsIconChannel::GetContentDispositionFilename(nsAString& aContentDispositionFilename) {
return NS_ERROR_NOT_AVAILABLE;
}
NS_IMETHODIMP
nsIconChannel::
SetContentDispositionFilename(const nsAString& aContentDispositionFilename)
{
nsIconChannel::SetContentDispositionFilename(const nsAString& aContentDispositionFilename) {
return NS_ERROR_NOT_AVAILABLE;
}
NS_IMETHODIMP
nsIconChannel::
GetContentDispositionHeader(nsACString& aContentDispositionHeader)
{
nsIconChannel::GetContentDispositionHeader(nsACString& aContentDispositionHeader) {
return NS_ERROR_NOT_AVAILABLE;
}
NS_IMETHODIMP
nsIconChannel::GetContentLength(int64_t* aContentLength)
{
nsIconChannel::GetContentLength(int64_t* aContentLength) {
*aContentLength = 0;
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsIconChannel::SetContentLength(int64_t aContentLength)
{
nsIconChannel::SetContentLength(int64_t aContentLength) {
MOZ_ASSERT_UNREACHABLE("nsIconChannel::SetContentLength");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsIconChannel::GetLoadGroup(nsILoadGroup** aLoadGroup)
{
nsIconChannel::GetLoadGroup(nsILoadGroup** aLoadGroup) {
*aLoadGroup = mLoadGroup;
NS_IF_ADDREF(*aLoadGroup);
return NS_OK;
}
NS_IMETHODIMP
nsIconChannel::SetLoadGroup(nsILoadGroup* aLoadGroup)
{
nsIconChannel::SetLoadGroup(nsILoadGroup* aLoadGroup) {
mLoadGroup = aLoadGroup;
return NS_OK;
}
NS_IMETHODIMP
nsIconChannel::GetOwner(nsISupports** aOwner)
{
nsIconChannel::GetOwner(nsISupports** aOwner) {
*aOwner = mOwner.get();
NS_IF_ADDREF(*aOwner);
return NS_OK;
}
NS_IMETHODIMP
nsIconChannel::SetOwner(nsISupports* aOwner)
{
nsIconChannel::SetOwner(nsISupports* aOwner) {
mOwner = aOwner;
return NS_OK;
}
NS_IMETHODIMP
nsIconChannel::GetLoadInfo(nsILoadInfo** aLoadInfo)
{
nsIconChannel::GetLoadInfo(nsILoadInfo** aLoadInfo) {
NS_IF_ADDREF(*aLoadInfo = mLoadInfo);
return NS_OK;
}
NS_IMETHODIMP
nsIconChannel::SetLoadInfo(nsILoadInfo* aLoadInfo)
{
nsIconChannel::SetLoadInfo(nsILoadInfo* aLoadInfo) {
mLoadInfo = aLoadInfo;
return NS_OK;
}
NS_IMETHODIMP
nsIconChannel::
GetNotificationCallbacks(nsIInterfaceRequestor** aNotificationCallbacks)
{
nsIconChannel::GetNotificationCallbacks(nsIInterfaceRequestor** aNotificationCallbacks) {
*aNotificationCallbacks = mCallbacks.get();
NS_IF_ADDREF(*aNotificationCallbacks);
return NS_OK;
}
NS_IMETHODIMP
nsIconChannel::
SetNotificationCallbacks(nsIInterfaceRequestor* aNotificationCallbacks)
{
nsIconChannel::SetNotificationCallbacks(nsIInterfaceRequestor* aNotificationCallbacks) {
mCallbacks = aNotificationCallbacks;
return NS_OK;
}
NS_IMETHODIMP
nsIconChannel::GetSecurityInfo(nsISupports** aSecurityInfo)
{
nsIconChannel::GetSecurityInfo(nsISupports** aSecurityInfo) {
*aSecurityInfo = nullptr;
return NS_OK;
}

View File

@ -7,9 +7,7 @@
#include "base/logging.h"
@interface CrApplication ()
@property(readwrite,
getter=isHandlingSendEvent,
nonatomic) BOOL handlingSendEvent;
@property(readwrite, getter=isHandlingSendEvent, nonatomic) BOOL handlingSendEvent;
@end
@implementation CrApplication
@ -21,8 +19,8 @@
+ (NSApplication*)sharedApplication {
NSApplication* app = [super sharedApplication];
if (![NSApp isKindOfClass:self]) {
CHROMIUM_LOG(ERROR) << "NSApp should be of type " << [[self className] UTF8String]
<< ", not " << [[NSApp className] UTF8String];
CHROMIUM_LOG(ERROR) << "NSApp should be of type " << [[self className] UTF8String] << ", not "
<< [[NSApp className] UTF8String];
DCHECK(false) << "NSApp is of wrong type";
}
return app;
@ -61,8 +59,6 @@ ScopedSendingEvent::ScopedSendingEvent()
[app_ setHandlingSendEvent:YES];
}
ScopedSendingEvent::~ScopedSendingEvent() {
[app_ setHandlingSendEvent:handling_];
}
ScopedSendingEvent::~ScopedSendingEvent() { [app_ setHandlingSendEvent:handling_]; }
} // namespace chrome_application_mac

View File

@ -17,19 +17,15 @@ namespace file_util {
bool GetTempDir(FilePath* path) {
base::ScopedNSAutoreleasePool autorelease_pool;
NSString* tmp = NSTemporaryDirectory();
if (tmp == nil)
return false;
if (tmp == nil) return false;
*path = FilePath([tmp fileSystemRepresentation]);
return true;
}
bool GetShmemTempDir(FilePath* path) {
return GetTempDir(path);
}
bool GetShmemTempDir(FilePath* path) { return GetTempDir(path); }
bool CopyFile(const FilePath& from_path, const FilePath& to_path) {
return (copyfile(from_path.value().c_str(),
to_path.value().c_str(), NULL, COPYFILE_ALL) == 0);
return (copyfile(from_path.value().c_str(), to_path.value().c_str(), NULL, COPYFILE_ALL) == 0);
}
} // namespace

View File

@ -19,12 +19,10 @@ bool AmIBundled() {
ProcessSerialNumber psn = {0, kCurrentProcess};
FSRef fsref;
if (GetProcessBundleLocation(&psn, &fsref) != noErr)
return false;
if (GetProcessBundleLocation(&psn, &fsref) != noErr) return false;
FSCatalogInfo info;
if (FSGetCatalogInfo(&fsref, kFSCatInfoNodeFlags, &info,
NULL, NULL, NULL) != noErr) {
if (FSGetCatalogInfo(&fsref, kFSCatInfoNodeFlags, &info, NULL, NULL, NULL) != noErr) {
return false;
}

View File

@ -17,11 +17,9 @@
namespace {
void NoOp(void* info) {
}
void NoOp(void* info) {}
const CFTimeInterval kCFTimeIntervalMax =
std::numeric_limits<CFTimeInterval>::max();
const CFTimeInterval kCFTimeIntervalMax = std::numeric_limits<CFTimeInterval>::max();
} // namespace
@ -32,12 +30,9 @@ namespace base {
// case where an autorelease pool needs to be passed in.
class MessagePumpScopedAutoreleasePool {
public:
explicit MessagePumpScopedAutoreleasePool(MessagePumpCFRunLoopBase* pump) :
pool_(pump->CreateAutoreleasePool()) {
}
~MessagePumpScopedAutoreleasePool() {
[pool_ drain];
}
explicit MessagePumpScopedAutoreleasePool(MessagePumpCFRunLoopBase* pump)
: pool_(pump->CreateAutoreleasePool()) {}
~MessagePumpScopedAutoreleasePool() { [pool_ drain]; }
private:
NSAutoreleasePool* pool_;
@ -67,8 +62,7 @@ MessagePumpCFRunLoopBase::MessagePumpCFRunLoopBase()
kCFTimeIntervalMax, // interval
0, // flags
0, // priority
RunDelayedWorkTimer,
&timer_context);
RunDelayedWorkTimer, &timer_context);
CFRunLoopAddTimer(run_loop_, delayed_work_timer_, kCFRunLoopCommonModes);
CFRunLoopSourceContext source_context = CFRunLoopSourceContext();
@ -95,8 +89,7 @@ MessagePumpCFRunLoopBase::MessagePumpCFRunLoopBase()
nesting_deferred_work_source_ = CFRunLoopSourceCreate(NULL, // allocator
0, // priority
&source_context);
CFRunLoopAddSource(run_loop_, nesting_deferred_work_source_,
kCFRunLoopCommonModes);
CFRunLoopAddSource(run_loop_, nesting_deferred_work_source_, kCFRunLoopCommonModes);
CFRunLoopObserverContext observer_context = CFRunLoopObserverContext();
observer_context.info = this;
@ -104,36 +97,28 @@ MessagePumpCFRunLoopBase::MessagePumpCFRunLoopBase()
kCFRunLoopBeforeWaiting,
true, // repeat
0, // priority
PreWaitObserver,
&observer_context);
PreWaitObserver, &observer_context);
CFRunLoopAddObserver(run_loop_, pre_wait_observer_, kCFRunLoopCommonModes);
pre_source_observer_ = CFRunLoopObserverCreate(NULL, // allocator
kCFRunLoopBeforeSources,
true, // repeat
0, // priority
PreSourceObserver,
&observer_context);
PreSourceObserver, &observer_context);
CFRunLoopAddObserver(run_loop_, pre_source_observer_, kCFRunLoopCommonModes);
enter_exit_observer_ = CFRunLoopObserverCreate(NULL, // allocator
kCFRunLoopEntry |
kCFRunLoopExit,
kCFRunLoopEntry | kCFRunLoopExit,
true, // repeat
0, // priority
EnterExitObserver,
&observer_context);
EnterExitObserver, &observer_context);
CFRunLoopAddObserver(run_loop_, enter_exit_observer_, kCFRunLoopCommonModes);
root_power_domain_ = IORegisterForSystemPower(this,
&power_notification_port_,
PowerStateNotification,
&power_notification_object_);
root_power_domain_ = IORegisterForSystemPower(
this, &power_notification_port_, PowerStateNotification, &power_notification_object_);
if (root_power_domain_ != MACH_PORT_NULL) {
CFRunLoopAddSource(
run_loop_,
IONotificationPortGetRunLoopSource(power_notification_port_),
kCFRunLoopCommonModes);
CFRunLoopAddSource(run_loop_, IONotificationPortGetRunLoopSource(power_notification_port_),
kCFRunLoopCommonModes);
}
}
@ -142,29 +127,23 @@ MessagePumpCFRunLoopBase::MessagePumpCFRunLoopBase()
// same number of run loops must be running when this object is destroyed.
MessagePumpCFRunLoopBase::~MessagePumpCFRunLoopBase() {
if (root_power_domain_ != MACH_PORT_NULL) {
CFRunLoopRemoveSource(
run_loop_,
IONotificationPortGetRunLoopSource(power_notification_port_),
kCFRunLoopCommonModes);
CFRunLoopRemoveSource(run_loop_, IONotificationPortGetRunLoopSource(power_notification_port_),
kCFRunLoopCommonModes);
IODeregisterForSystemPower(&power_notification_object_);
IOServiceClose(root_power_domain_);
IONotificationPortDestroy(power_notification_port_);
}
CFRunLoopRemoveObserver(run_loop_, enter_exit_observer_,
kCFRunLoopCommonModes);
CFRunLoopRemoveObserver(run_loop_, enter_exit_observer_, kCFRunLoopCommonModes);
CFRelease(enter_exit_observer_);
CFRunLoopRemoveObserver(run_loop_, pre_source_observer_,
kCFRunLoopCommonModes);
CFRunLoopRemoveObserver(run_loop_, pre_source_observer_, kCFRunLoopCommonModes);
CFRelease(pre_source_observer_);
CFRunLoopRemoveObserver(run_loop_, pre_wait_observer_,
kCFRunLoopCommonModes);
CFRunLoopRemoveObserver(run_loop_, pre_wait_observer_, kCFRunLoopCommonModes);
CFRelease(pre_wait_observer_);
CFRunLoopRemoveSource(run_loop_, nesting_deferred_work_source_,
kCFRunLoopCommonModes);
CFRunLoopRemoveSource(run_loop_, nesting_deferred_work_source_, kCFRunLoopCommonModes);
CFRelease(nesting_deferred_work_source_);
CFRunLoopRemoveSource(run_loop_, idle_work_source_, kCFRunLoopCommonModes);
@ -224,8 +203,7 @@ void MessagePumpCFRunLoopBase::ScheduleWork() {
}
// Must be called on the run loop thread.
void MessagePumpCFRunLoopBase::ScheduleDelayedWork(
const TimeTicks& delayed_work_time) {
void MessagePumpCFRunLoopBase::ScheduleDelayedWork(const TimeTicks& delayed_work_time) {
TimeDelta delta = delayed_work_time - TimeTicks::Now();
delayed_work_fire_time_ = CFAbsoluteTimeGetCurrent() + delta.InSecondsF();
CFRunLoopTimerSetNextFireDate(delayed_work_timer_, delayed_work_fire_time_);
@ -233,8 +211,7 @@ void MessagePumpCFRunLoopBase::ScheduleDelayedWork(
// Called from the run loop.
// static
void MessagePumpCFRunLoopBase::RunDelayedWorkTimer(CFRunLoopTimerRef timer,
void* info) {
void MessagePumpCFRunLoopBase::RunDelayedWorkTimer(CFRunLoopTimerRef timer, void* info) {
MessagePumpCFRunLoopBase* self = static_cast<MessagePumpCFRunLoopBase*>(info);
// The timer won't fire again until it's reset.
@ -415,8 +392,7 @@ void MessagePumpCFRunLoopBase::MaybeScheduleNestingDeferredWork() {
// Called from the run loop.
// static
void MessagePumpCFRunLoopBase::PreWaitObserver(CFRunLoopObserverRef observer,
CFRunLoopActivity activity,
void* info) {
CFRunLoopActivity activity, void* info) {
MessagePumpCFRunLoopBase* self = static_cast<MessagePumpCFRunLoopBase*>(info);
// Attempt to do some idle work before going to sleep.
@ -432,8 +408,7 @@ void MessagePumpCFRunLoopBase::PreWaitObserver(CFRunLoopObserverRef observer,
// Called from the run loop.
// static
void MessagePumpCFRunLoopBase::PreSourceObserver(CFRunLoopObserverRef observer,
CFRunLoopActivity activity,
void* info) {
CFRunLoopActivity activity, void* info) {
MessagePumpCFRunLoopBase* self = static_cast<MessagePumpCFRunLoopBase*>(info);
// The run loop has reached the top of the loop and is about to begin
@ -447,8 +422,7 @@ void MessagePumpCFRunLoopBase::PreSourceObserver(CFRunLoopObserverRef observer,
// Called from the run loop.
// static
void MessagePumpCFRunLoopBase::EnterExitObserver(CFRunLoopObserverRef observer,
CFRunLoopActivity activity,
void* info) {
CFRunLoopActivity activity, void* info) {
MessagePumpCFRunLoopBase* self = static_cast<MessagePumpCFRunLoopBase*>(info);
switch (activity) {
@ -489,8 +463,7 @@ void MessagePumpCFRunLoopBase::EnterExitObserver(CFRunLoopObserverRef observer,
// Called from the run loop.
// static
void MessagePumpCFRunLoopBase::PowerStateNotification(void* info,
io_service_t service,
void MessagePumpCFRunLoopBase::PowerStateNotification(void* info, io_service_t service,
uint32_t message_type,
void* message_argument) {
// CFRunLoopTimer (NSTimer) is scheduled in terms of CFAbsoluteTime, which
@ -535,8 +508,7 @@ void MessagePumpCFRunLoopBase::PowerStateNotification(void* info,
switch (message_type) {
case kIOMessageSystemWillPowerOn:
if (self->delayed_work_fire_time_ != kCFTimeIntervalMax) {
CFRunLoopTimerSetNextFireDate(self->delayed_work_timer_,
self->delayed_work_fire_time_);
CFRunLoopTimerSetNextFireDate(self->delayed_work_timer_, self->delayed_work_fire_time_);
}
break;
@ -545,8 +517,7 @@ void MessagePumpCFRunLoopBase::PowerStateNotification(void* info,
// The system will wait for 30 seconds before entering sleep if neither
// IOAllowPowerChange nor IOCancelPowerChange are called. That would be
// pretty antisocial.
IOAllowPowerChange(self->root_power_domain_,
reinterpret_cast<long>(message_argument));
IOAllowPowerChange(self->root_power_domain_, reinterpret_cast<long>(message_argument));
break;
default:
@ -556,17 +527,14 @@ void MessagePumpCFRunLoopBase::PowerStateNotification(void* info,
// Called by MessagePumpCFRunLoopBase::EnterExitRunLoop. The default
// implementation is a no-op.
void MessagePumpCFRunLoopBase::EnterExitRunLoop(CFRunLoopActivity activity) {
}
void MessagePumpCFRunLoopBase::EnterExitRunLoop(CFRunLoopActivity activity) {}
// Base version returns a standard NSAutoreleasePool.
NSAutoreleasePool* MessagePumpCFRunLoopBase::CreateAutoreleasePool() {
return [[NSAutoreleasePool alloc] init];
}
MessagePumpCFRunLoop::MessagePumpCFRunLoop()
: quit_pending_(false) {
}
MessagePumpCFRunLoop::MessagePumpCFRunLoop() : quit_pending_(false) {}
// Called by MessagePumpCFRunLoopBase::DoRun. If other CFRunLoopRun loops were
// running lower on the run loop thread's stack when this object was created,
@ -578,9 +546,7 @@ void MessagePumpCFRunLoop::DoRun(Delegate* delegate) {
int result;
do {
MessagePumpScopedAutoreleasePool autorelease_pool(this);
result = CFRunLoopRunInMode(kCFRunLoopDefaultMode,
kCFTimeIntervalMax,
false);
result = CFRunLoopRunInMode(kCFRunLoopDefaultMode, kCFTimeIntervalMax, false);
} while (result != kCFRunLoopRunStopped && result != kCFRunLoopRunFinished);
}
@ -602,9 +568,7 @@ void MessagePumpCFRunLoop::Quit() {
// Called by MessagePumpCFRunLoopBase::EnterExitObserver.
void MessagePumpCFRunLoop::EnterExitRunLoop(CFRunLoopActivity activity) {
if (activity == kCFRunLoopExit &&
nesting_level() == run_nesting_level() &&
quit_pending_) {
if (activity == kCFRunLoopExit && nesting_level() == run_nesting_level() && quit_pending_) {
// Quit was called while loops other than those managed by this object
// were running further inside a run loop managed by this object. Now
// that all unmanaged inner run loops are gone, stop the loop running
@ -614,8 +578,7 @@ void MessagePumpCFRunLoop::EnterExitRunLoop(CFRunLoopActivity activity) {
}
}
MessagePumpNSRunLoop::MessagePumpNSRunLoop()
: keep_running_(true) {
MessagePumpNSRunLoop::MessagePumpNSRunLoop() : keep_running_(true) {
CFRunLoopSourceContext source_context = CFRunLoopSourceContext();
source_context.perform = NoOp;
quit_source_ = CFRunLoopSourceCreate(NULL, // allocator
@ -632,8 +595,7 @@ MessagePumpNSRunLoop::~MessagePumpNSRunLoop() {
void MessagePumpNSRunLoop::DoRun(Delegate* delegate) {
while (keep_running_) {
// NSRunLoop manages autorelease pools itself.
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode
beforeDate:[NSDate distantFuture]];
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
}
keep_running_ = true;
@ -646,9 +608,7 @@ void MessagePumpNSRunLoop::Quit() {
}
MessagePumpNSApplication::MessagePumpNSApplication()
: keep_running_(true),
running_own_loop_(false) {
}
: keep_running_(true), running_own_loop_(false) {}
void MessagePumpNSApplication::DoRun(Delegate* delegate) {
bool last_running_own_loop_ = running_own_loop_;

View File

@ -42,9 +42,7 @@ void InitThreading() {
static BOOL multithreaded = [NSThread isMultiThreaded];
if (!multithreaded) {
[NSThread detachNewThreadSelector:@selector(noOp)
toTarget:[NoOp class]
withObject:nil];
[NSThread detachNewThreadSelector:@selector(noOp) toTarget:[NoOp class] withObject:nil];
multithreaded = YES;
DCHECK([NSThread isMultiThreaded]);
@ -60,8 +58,7 @@ void PlatformThread::SetName(const char* name) {
int (*dynamic_pthread_setname_np)(const char*);
*reinterpret_cast<void**>(&dynamic_pthread_setname_np) =
dlsym(RTLD_DEFAULT, "pthread_setname_np");
if (!dynamic_pthread_setname_np)
return;
if (!dynamic_pthread_setname_np) return;
// Mac OS X does not expose the length limit of the name, so
// hardcode it.
@ -74,4 +71,3 @@ void PlatformThread::SetName(const char* name) {
// Checked against the bionic implementation in bionic/libc/bionic/pthread.c
dynamic_pthread_setname_np(shortened_name.c_str());
}

View File

@ -25,10 +25,8 @@ static mozilla::EnvironmentLog gProcessLog("MOZ_PROCESS_LOG");
namespace base {
bool LaunchApp(const std::vector<std::string>& argv,
const LaunchOptions& options,
ProcessHandle* process_handle)
{
bool LaunchApp(const std::vector<std::string>& argv, const LaunchOptions& options,
ProcessHandle* process_handle) {
bool retval = true;
char* argv_copy[argv.size() + 1];
@ -43,9 +41,8 @@ bool LaunchApp(const std::vector<std::string>& argv,
if (posix_spawn_file_actions_init(&file_actions) != 0) {
return false;
}
auto file_actions_guard = mozilla::MakeScopeExit([&file_actions] {
posix_spawn_file_actions_destroy(&file_actions);
});
auto file_actions_guard =
mozilla::MakeScopeExit([&file_actions] { posix_spawn_file_actions_destroy(&file_actions); });
// Turn fds_to_remap array into a set of dup2 calls.
mozilla::ipc::FileDescriptorShuffle shuffle;
@ -66,9 +63,8 @@ bool LaunchApp(const std::vector<std::string>& argv,
if (posix_spawnattr_init(&spawnattr) != 0) {
return false;
}
auto spawnattr_guard = mozilla::MakeScopeExit([&spawnattr] {
posix_spawnattr_destroy(&spawnattr);
});
auto spawnattr_guard =
mozilla::MakeScopeExit([&spawnattr] { posix_spawnattr_destroy(&spawnattr); });
// Prevent the child process from inheriting any file descriptors
// that aren't named in `file_actions`. (This is an Apple-specific
@ -85,32 +81,23 @@ bool LaunchApp(const std::vector<std::string>& argv,
}
int pid = 0;
int spawn_succeeded = (posix_spawnp(&pid,
argv_copy[0],
&file_actions,
&spawnattr,
argv_copy,
vars.get()) == 0);
int spawn_succeeded =
(posix_spawnp(&pid, argv_copy[0], &file_actions, &spawnattr, argv_copy, vars.get()) == 0);
bool process_handle_valid = pid > 0;
if (!spawn_succeeded || !process_handle_valid) {
retval = false;
} else {
gProcessLog.print("==> process %d launched child process %d\n",
GetCurrentProcId(), pid);
if (options.wait)
HANDLE_EINTR(waitpid(pid, 0, 0));
gProcessLog.print("==> process %d launched child process %d\n", GetCurrentProcId(), pid);
if (options.wait) HANDLE_EINTR(waitpid(pid, 0, 0));
if (process_handle)
*process_handle = pid;
if (process_handle) *process_handle = pid;
}
return retval;
}
bool LaunchApp(const CommandLine& cl,
const LaunchOptions& options,
ProcessHandle* process_handle) {
bool LaunchApp(const CommandLine& cl, const LaunchOptions& options, ProcessHandle* process_handle) {
return LaunchApp(cl.argv(), options, process_handle);
}

View File

@ -15,9 +15,7 @@ ScopedNSAutoreleasePool::ScopedNSAutoreleasePool()
DCHECK(autorelease_pool_);
}
ScopedNSAutoreleasePool::~ScopedNSAutoreleasePool() {
[autorelease_pool_ drain];
}
ScopedNSAutoreleasePool::~ScopedNSAutoreleasePool() { [autorelease_pool_ drain]; }
// Cycle the internal pool, allowing everything there to get cleaned up and
// start anew.

View File

@ -19,25 +19,21 @@ namespace {
// an STL string of the template type. Returns an empty string on failure.
//
// Do not assert in this function since it is used by the asssertion code!
template<typename StringType>
template <typename StringType>
static StringType CFStringToSTLStringWithEncodingT(CFStringRef cfstring,
CFStringEncoding encoding) {
CFIndex length = CFStringGetLength(cfstring);
if (length == 0)
return StringType();
if (length == 0) return StringType();
CFRange whole_string = CFRangeMake(0, length);
CFIndex out_size;
CFIndex converted = CFStringGetBytes(cfstring,
whole_string,
encoding,
CFIndex converted = CFStringGetBytes(cfstring, whole_string, encoding,
0, // lossByte
false, // isExternalRepresentation
NULL, // buffer
0, // maxBufLen
&out_size);
if (converted == 0 || out_size == 0)
return StringType();
if (converted == 0 || out_size == 0) return StringType();
// out_size is the number of UInt8-sized units needed in the destination.
// A buffer allocated as UInt8 units might not be properly aligned to
@ -48,16 +44,12 @@ static StringType CFStringToSTLStringWithEncodingT(CFStringRef cfstring,
out_size * sizeof(UInt8) / sizeof(typename StringType::value_type) + 1;
std::vector<typename StringType::value_type> out_buffer(elements);
converted = CFStringGetBytes(cfstring,
whole_string,
encoding,
converted = CFStringGetBytes(cfstring, whole_string, encoding,
0, // lossByte
false, // isExternalRepresentation
reinterpret_cast<UInt8*>(&out_buffer[0]),
out_size,
reinterpret_cast<UInt8*>(&out_buffer[0]), out_size,
NULL); // usedBufLen
if (converted == 0)
return StringType();
if (converted == 0) return StringType();
out_buffer[elements - 1] = '\0';
return StringType(&out_buffer[0], elements - 1);
@ -68,45 +60,31 @@ static StringType CFStringToSTLStringWithEncodingT(CFStringRef cfstring,
// |OutStringType| template type. Returns an empty string on failure.
//
// Do not assert in this function since it is used by the asssertion code!
template<typename InStringType, typename OutStringType>
static OutStringType STLStringToSTLStringWithEncodingsT(
const InStringType& in,
CFStringEncoding in_encoding,
CFStringEncoding out_encoding) {
template <typename InStringType, typename OutStringType>
static OutStringType STLStringToSTLStringWithEncodingsT(const InStringType& in,
CFStringEncoding in_encoding,
CFStringEncoding out_encoding) {
typename InStringType::size_type in_length = in.length();
if (in_length == 0)
return OutStringType();
if (in_length == 0) return OutStringType();
scoped_cftyperef<CFStringRef> cfstring(
CFStringCreateWithBytesNoCopy(NULL,
reinterpret_cast<const UInt8*>(in.data()),
in_length *
sizeof(typename InStringType::value_type),
in_encoding,
false,
kCFAllocatorNull));
if (!cfstring)
return OutStringType();
scoped_cftyperef<CFStringRef> cfstring(CFStringCreateWithBytesNoCopy(
NULL, reinterpret_cast<const UInt8*>(in.data()),
in_length * sizeof(typename InStringType::value_type), in_encoding, false, kCFAllocatorNull));
if (!cfstring) return OutStringType();
return CFStringToSTLStringWithEncodingT<OutStringType>(cfstring,
out_encoding);
return CFStringToSTLStringWithEncodingT<OutStringType>(cfstring, out_encoding);
}
// Given an STL string |in| with an encoding specified by |in_encoding|,
// return it as a CFStringRef. Returns NULL on failure.
template<typename StringType>
static CFStringRef STLStringToCFStringWithEncodingsT(
const StringType& in,
CFStringEncoding in_encoding) {
template <typename StringType>
static CFStringRef STLStringToCFStringWithEncodingsT(const StringType& in,
CFStringEncoding in_encoding) {
typename StringType::size_type in_length = in.length();
if (in_length == 0)
return CFSTR("");
if (in_length == 0) return CFSTR("");
return CFStringCreateWithBytes(kCFAllocatorDefault,
reinterpret_cast<const UInt8*>(in.data()),
in_length *
sizeof(typename StringType::value_type),
in_encoding,
return CFStringCreateWithBytes(kCFAllocatorDefault, reinterpret_cast<const UInt8*>(in.data()),
in_length * sizeof(typename StringType::value_type), in_encoding,
false);
}
@ -124,22 +102,18 @@ static const CFStringEncoding kWideStringEncoding = kCFStringEncodingUTF32LE;
// Do not assert in this function since it is used by the asssertion code!
std::string SysWideToUTF8(const std::wstring& wide) {
return STLStringToSTLStringWithEncodingsT<std::wstring, std::string>(
wide, kWideStringEncoding, kNarrowStringEncoding);
return STLStringToSTLStringWithEncodingsT<std::wstring, std::string>(wide, kWideStringEncoding,
kNarrowStringEncoding);
}
// Do not assert in this function since it is used by the asssertion code!
std::wstring SysUTF8ToWide(const StringPiece& utf8) {
return STLStringToSTLStringWithEncodingsT<StringPiece, std::wstring>(
utf8, kNarrowStringEncoding, kWideStringEncoding);
return STLStringToSTLStringWithEncodingsT<StringPiece, std::wstring>(utf8, kNarrowStringEncoding,
kWideStringEncoding);
}
std::string SysWideToNativeMB(const std::wstring& wide) {
return SysWideToUTF8(wide);
}
std::string SysWideToNativeMB(const std::wstring& wide) { return SysWideToUTF8(wide); }
std::wstring SysNativeMBToWide(const StringPiece& native_mb) {
return SysUTF8ToWide(native_mb);
}
std::wstring SysNativeMBToWide(const StringPiece& native_mb) { return SysUTF8ToWide(native_mb); }
} // namespace base

View File

@ -10,12 +10,9 @@
#include "base/logging.h"
//==============================================================================
MachSendMessage::MachSendMessage(int32_t message_id) : MachMessage() {
Initialize(message_id);
}
MachSendMessage::MachSendMessage(int32_t message_id) : MachMessage() { Initialize(message_id); }
MachSendMessage::MachSendMessage(void *storage, size_t storage_length,
int32_t message_id)
MachSendMessage::MachSendMessage(void *storage, size_t storage_length, int32_t message_id)
: MachMessage(storage, storage_length) {
Initialize(message_id);
}
@ -31,7 +28,7 @@ void MachSendMessage::Initialize(int32_t message_id) {
SetDescriptorCount(0); // start out with no descriptors
SetMessageID(message_id);
SetData(NULL, 0); // client may add data later
SetData(NULL, 0); // client may add data later
}
//==============================================================================
@ -44,7 +41,7 @@ MachMessage::MachMessage()
//==============================================================================
MachMessage::MachMessage(void *storage, size_t storage_length)
: storage_(static_cast<MachMessageData*>(storage)),
: storage_(static_cast<MachMessageData *>(storage)),
storage_length_bytes_(storage_length),
own_storage_(false) {
DCHECK(storage);
@ -59,25 +56,18 @@ MachMessage::~MachMessage() {
}
}
u_int32_t MachMessage::GetDataLength() { return EndianU32_LtoN(GetDataPacket()->data_length); }
u_int32_t MachMessage::GetDataLength() {
return EndianU32_LtoN(GetDataPacket()->data_length);
}
// The message ID may be used as a code identifying the type of message
// The message ID may be used as a code identifying the type of message
void MachMessage::SetMessageID(int32_t message_id) {
GetDataPacket()->id = EndianU32_NtoL(message_id);
}
int32_t MachMessage::GetMessageID() {
return EndianU32_LtoN(GetDataPacket()->id);
}
int32_t MachMessage::GetMessageID() { return EndianU32_LtoN(GetDataPacket()->id); }
//==============================================================================
// returns true if successful
bool MachMessage::SetData(const void* data,
int32_t data_length) {
bool MachMessage::SetData(const void *data, int32_t data_length) {
// Enforce the fact that it's only safe to call this method once on a
// message.
DCHECK(GetDataPacket()->data_length == 0);
@ -108,7 +98,7 @@ int MachMessage::CalculateSize() {
// add space for MessageDataPacket
int32_t alignedDataLength = (GetDataLength() + 3) & ~0x3;
size += 2*sizeof(int32_t) + alignedDataLength;
size += 2 * sizeof(int32_t) + alignedDataLength;
// add space for descriptors
size += GetDescriptorCount() * sizeof(MachMsgPortDescriptor);
@ -120,18 +110,15 @@ int MachMessage::CalculateSize() {
//==============================================================================
MachMessage::MessageDataPacket *MachMessage::GetDataPacket() {
int desc_size = sizeof(MachMsgPortDescriptor)*GetDescriptorCount();
MessageDataPacket *packet =
reinterpret_cast<MessageDataPacket*>(storage_->padding + desc_size);
int desc_size = sizeof(MachMsgPortDescriptor) * GetDescriptorCount();
MessageDataPacket *packet = reinterpret_cast<MessageDataPacket *>(storage_->padding + desc_size);
return packet;
}
//==============================================================================
void MachMessage::SetDescriptor(int n,
const MachMsgPortDescriptor &desc) {
MachMsgPortDescriptor *desc_array =
reinterpret_cast<MachMsgPortDescriptor*>(storage_->padding);
void MachMessage::SetDescriptor(int n, const MachMsgPortDescriptor &desc) {
MachMsgPortDescriptor *desc_array = reinterpret_cast<MachMsgPortDescriptor *>(storage_->padding);
desc_array[n] = desc;
}
@ -148,8 +135,8 @@ bool MachMessage::AddDescriptor(const MachMsgPortDescriptor &desc) {
// unfortunately, we need to move the data to allow space for the
// new descriptor
u_int8_t *p = reinterpret_cast<u_int8_t*>(GetDataPacket());
bcopy(p, p+sizeof(MachMsgPortDescriptor), GetDataLength()+2*sizeof(int32_t));
u_int8_t *p = reinterpret_cast<u_int8_t *>(GetDataPacket());
bcopy(p, p + sizeof(MachMsgPortDescriptor), GetDataLength() + 2 * sizeof(int32_t));
SetDescriptor(GetDescriptorCount(), desc);
SetDescriptorCount(GetDescriptorCount() + 1);
@ -173,8 +160,7 @@ void MachMessage::SetDescriptorCount(int n) {
//==============================================================================
MachMsgPortDescriptor *MachMessage::GetDescriptor(int n) {
if (n < GetDescriptorCount()) {
MachMsgPortDescriptor *desc =
reinterpret_cast<MachMsgPortDescriptor*>(storage_->padding);
MachMsgPortDescriptor *desc = reinterpret_cast<MachMsgPortDescriptor *>(storage_->padding);
return desc + n;
}
@ -196,20 +182,13 @@ mach_port_t MachMessage::GetTranslatedPort(int n) {
ReceivePort::ReceivePort(const char *receive_port_name) {
mach_port_t current_task = mach_task_self();
init_result_ = mach_port_allocate(current_task,
MACH_PORT_RIGHT_RECEIVE,
&port_);
init_result_ = mach_port_allocate(current_task, MACH_PORT_RIGHT_RECEIVE, &port_);
if (init_result_ != KERN_SUCCESS)
return;
if (init_result_ != KERN_SUCCESS) return;
init_result_ = mach_port_insert_right(current_task,
port_,
port_,
MACH_MSG_TYPE_MAKE_SEND);
init_result_ = mach_port_insert_right(current_task, port_, port_, MACH_MSG_TYPE_MAKE_SEND);
if (init_result_ != KERN_SUCCESS)
return;
if (init_result_ != KERN_SUCCESS) return;
NSPort *ns_port = [NSMachPort portWithMachPort:port_];
NSString *port_name = [NSString stringWithUTF8String:receive_port_name];
@ -221,31 +200,22 @@ ReceivePort::ReceivePort(const char *receive_port_name) {
ReceivePort::ReceivePort() {
mach_port_t current_task = mach_task_self();
init_result_ = mach_port_allocate(current_task,
MACH_PORT_RIGHT_RECEIVE,
&port_);
init_result_ = mach_port_allocate(current_task, MACH_PORT_RIGHT_RECEIVE, &port_);
if (init_result_ != KERN_SUCCESS)
return;
if (init_result_ != KERN_SUCCESS) return;
init_result_ = mach_port_insert_right(current_task,
port_,
port_,
MACH_MSG_TYPE_MAKE_SEND);
init_result_ = mach_port_insert_right(current_task, port_, port_, MACH_MSG_TYPE_MAKE_SEND);
}
//==============================================================================
// Given an already existing mach port, use it. We take ownership of the
// port and deallocate it in our destructor.
ReceivePort::ReceivePort(mach_port_t receive_port)
: port_(receive_port),
init_result_(KERN_SUCCESS) {
}
: port_(receive_port), init_result_(KERN_SUCCESS) {}
//==============================================================================
ReceivePort::~ReceivePort() {
if (init_result_ == KERN_SUCCESS)
mach_port_deallocate(mach_task_self(), port_);
if (init_result_ == KERN_SUCCESS) mach_port_deallocate(mach_task_self(), port_);
}
//==============================================================================
@ -256,8 +226,7 @@ kern_return_t ReceivePort::WaitForMessage(MachReceiveMessage *out_message,
}
// return any error condition encountered in constructor
if (init_result_ != KERN_SUCCESS)
return init_result_;
if (init_result_ != KERN_SUCCESS) return init_result_;
out_message->Head()->msgh_bits = 0;
out_message->Head()->msgh_local_port = port_;
@ -265,45 +234,36 @@ kern_return_t ReceivePort::WaitForMessage(MachReceiveMessage *out_message,
out_message->Head()->msgh_reserved = 0;
out_message->Head()->msgh_id = 0;
kern_return_t result = mach_msg(out_message->Head(),
MACH_RCV_MSG | (timeout == MACH_MSG_TIMEOUT_NONE ? 0 : MACH_RCV_TIMEOUT),
0,
out_message->MaxSize(),
port_,
timeout, // timeout in ms
MACH_PORT_NULL);
kern_return_t result = mach_msg(
out_message->Head(), MACH_RCV_MSG | (timeout == MACH_MSG_TIMEOUT_NONE ? 0 : MACH_RCV_TIMEOUT),
0, out_message->MaxSize(), port_,
timeout, // timeout in ms
MACH_PORT_NULL);
return result;
}
//==============================================================================
// send a message to this port
kern_return_t ReceivePort::SendMessageToSelf(MachSendMessage& message, mach_msg_timeout_t timeout) {
kern_return_t ReceivePort::SendMessageToSelf(MachSendMessage &message, mach_msg_timeout_t timeout) {
if (message.Head()->msgh_size == 0) {
NOTREACHED();
return KERN_INVALID_VALUE; // just for safety -- never should occur
return KERN_INVALID_VALUE; // just for safety -- never should occur
};
if (init_result_ != KERN_SUCCESS)
return init_result_;
if (init_result_ != KERN_SUCCESS) return init_result_;
message.Head()->msgh_remote_port = port_;
message.Head()->msgh_bits
= MACH_MSGH_BITS (MACH_MSG_TYPE_MAKE_SEND,
MACH_MSG_TYPE_MAKE_SEND_ONCE);
kern_return_t result = mach_msg(message.Head(),
MACH_SEND_MSG | (timeout == MACH_MSG_TIMEOUT_NONE ? 0 : MACH_SEND_TIMEOUT),
message.Head()->msgh_size,
0,
MACH_PORT_NULL,
timeout, // timeout in ms
MACH_PORT_NULL);
message.Head()->msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_MAKE_SEND, MACH_MSG_TYPE_MAKE_SEND_ONCE);
kern_return_t result = mach_msg(
message.Head(), MACH_SEND_MSG | (timeout == MACH_MSG_TIMEOUT_NONE ? 0 : MACH_SEND_TIMEOUT),
message.Head()->msgh_size, 0, MACH_PORT_NULL,
timeout, // timeout in ms
MACH_PORT_NULL);
return result;
}
#pragma mark -
//==============================================================================
@ -312,40 +272,32 @@ MachPortSender::MachPortSender(const char *receive_port_name) {
mach_port_t bootstrap_port = 0;
init_result_ = task_get_bootstrap_port(mach_task_self(), &bootstrap_port);
if (init_result_ != KERN_SUCCESS)
return;
if (init_result_ != KERN_SUCCESS) return;
init_result_ = bootstrap_look_up(bootstrap_port,
const_cast<char*>(receive_port_name),
&send_port_);
init_result_ =
bootstrap_look_up(bootstrap_port, const_cast<char *>(receive_port_name), &send_port_);
}
//==============================================================================
MachPortSender::MachPortSender(mach_port_t send_port)
: send_port_(send_port),
init_result_(KERN_SUCCESS) {
}
: send_port_(send_port), init_result_(KERN_SUCCESS) {}
//==============================================================================
kern_return_t MachPortSender::SendMessage(MachSendMessage &message,
mach_msg_timeout_t timeout) {
kern_return_t MachPortSender::SendMessage(MachSendMessage &message, mach_msg_timeout_t timeout) {
if (message.Head()->msgh_size == 0) {
NOTREACHED();
return KERN_INVALID_VALUE; // just for safety -- never should occur
return KERN_INVALID_VALUE; // just for safety -- never should occur
};
if (init_result_ != KERN_SUCCESS)
return init_result_;
if (init_result_ != KERN_SUCCESS) return init_result_;
message.Head()->msgh_remote_port = send_port_;
kern_return_t result = mach_msg(message.Head(),
MACH_SEND_MSG | (timeout == MACH_MSG_TIMEOUT_NONE ? 0 : MACH_SEND_TIMEOUT),
message.Head()->msgh_size,
0,
MACH_PORT_NULL,
timeout, // timeout in ms
MACH_PORT_NULL);
kern_return_t result = mach_msg(
message.Head(), MACH_SEND_MSG | (timeout == MACH_MSG_TIMEOUT_NONE ? 0 : MACH_SEND_TIMEOUT),
message.Head()->msgh_size, 0, MACH_PORT_NULL,
timeout, // timeout in ms
MACH_PORT_NULL);
return result;
}

View File

@ -11,10 +11,9 @@
namespace mozilla {
namespace ipc {
void SetThisProcessName(const char *aName)
{
void SetThisProcessName(const char *aName) {
mozilla::plugins::PluginUtilsOSX::SetProcessName(aName);
}
} // namespace ipc
} // namespace mozilla
} // namespace ipc
} // namespace mozilla

View File

@ -10,14 +10,14 @@
#include <mach/vm_map.h>
#include <mach/mach_port.h>
#if defined(XP_IOS)
#include <mach/vm_map.h>
#define mach_vm_address_t vm_address_t
#define mach_vm_map vm_map
#define mach_vm_read vm_read
#define mach_vm_region_recurse vm_region_recurse_64
#define mach_vm_size_t vm_size_t
# include <mach/vm_map.h>
# define mach_vm_address_t vm_address_t
# define mach_vm_map vm_map
# define mach_vm_read vm_read
# define mach_vm_region_recurse vm_region_recurse_64
# define mach_vm_size_t vm_size_t
#else
#include <mach/mach_vm.h>
# include <mach/mach_vm.h>
#endif
#include <pthread.h>
#include <unistd.h>
@ -29,21 +29,23 @@
#include "mozilla/layers/TextureSync.h"
#ifdef DEBUG
#define LOG_ERROR(str, args...) \
PR_BEGIN_MACRO \
mozilla::SmprintfPointer msg = mozilla::Smprintf(str, ## args); \
NS_WARNING(msg.get()); \
PR_END_MACRO
# define LOG_ERROR(str, args...) \
PR_BEGIN_MACRO \
mozilla::SmprintfPointer msg = mozilla::Smprintf(str, ##args); \
NS_WARNING(msg.get()); \
PR_END_MACRO
#else
#define LOG_ERROR(str, args...) do { /* nothing */ } while(0)
# define LOG_ERROR(str, args...) \
do { /* nothing */ \
} while (0)
#endif
#define CHECK_MACH_ERROR(kr, msg) \
PR_BEGIN_MACRO \
if (kr != KERN_SUCCESS) { \
LOG_ERROR("%s %s (%x)\n", msg, mach_error_string(kr), kr); \
return false; \
} \
#define CHECK_MACH_ERROR(kr, msg) \
PR_BEGIN_MACRO \
if (kr != KERN_SUCCESS) { \
LOG_ERROR("%s %s (%x)\n", msg, mach_error_string(kr), kr); \
return false; \
} \
PR_END_MACRO
/*
@ -95,8 +97,7 @@ struct PIDPair {
pid_t mRequester;
pid_t mRequested;
PIDPair(pid_t requester, pid_t requested)
: mRequester(requester), mRequested(requested) {}
PIDPair(pid_t requester, pid_t requested) : mRequester(requester), mRequested(requested) {}
};
struct ListeningThread {
@ -104,8 +105,7 @@ struct ListeningThread {
MemoryPorts* mPorts;
ListeningThread() = default;
ListeningThread(pthread_t thread, MemoryPorts* ports)
: mThread(thread), mPorts(ports) {}
ListeningThread(pthread_t thread, MemoryPorts* ports) : mThread(thread), mPorts(ports) {}
};
struct SharePortsReply {
@ -115,18 +115,11 @@ struct SharePortsReply {
std::map<pid_t, ListeningThread> gThreads;
static void *
PortServerThread(void *argument);
static void* PortServerThread(void* argument);
static void
SetupMachMemory(pid_t pid,
ReceivePort* listen_port,
MachPortSender* listen_port_ack,
MachPortSender* send_port,
ReceivePort* send_port_ack,
bool pidIsParent)
{
static void SetupMachMemory(pid_t pid, ReceivePort* listen_port, MachPortSender* listen_port_ack,
MachPortSender* send_port, ReceivePort* send_port_ack,
bool pidIsParent) {
if (pidIsParent) {
gParentPid = pid;
}
@ -149,12 +142,8 @@ SetupMachMemory(pid_t pid,
// Send two communication ports to another process along with the pid of the process that is
// listening on them.
bool
SendPortsMessage(MachPortSender* sender,
mach_port_t ports_in_receiver,
mach_port_t ports_out_receiver,
PIDPair pid_pair)
{
bool SendPortsMessage(MachPortSender* sender, mach_port_t ports_in_receiver,
mach_port_t ports_out_receiver, PIDPair pid_pair) {
MachSendMessage getPortsMsg(kGetPortsMsg);
if (!getPortsMsg.AddDescriptor(MachMsgPortDescriptor(ports_in_receiver))) {
LOG_ERROR("Adding descriptor to message failed");
@ -168,20 +157,19 @@ SendPortsMessage(MachPortSender* sender,
getPortsMsg.SetData(&pid_pair, sizeof(PIDPair));
kern_return_t err = sender->SendMessage(getPortsMsg, kTimeout);
if (KERN_SUCCESS != err) {
LOG_ERROR("Error sending get ports message %s (%x)\n", mach_error_string(err), err);
LOG_ERROR("Error sending get ports message %s (%x)\n", mach_error_string(err), err);
return false;
}
return true;
}
// Receive two communication ports from another process
bool
RecvPortsMessage(ReceivePort* receiver, mach_port_t* ports_in_sender, mach_port_t* ports_out_sender)
{
bool RecvPortsMessage(ReceivePort* receiver, mach_port_t* ports_in_sender,
mach_port_t* ports_out_sender) {
MachReceiveMessage rcvPortsMsg;
kern_return_t err = receiver->WaitForMessage(&rcvPortsMsg, kTimeout);
if (KERN_SUCCESS != err) {
LOG_ERROR("Error receiving get ports message %s (%x)\n", mach_error_string(err), err);
LOG_ERROR("Error receiving get ports message %s (%x)\n", mach_error_string(err), err);
}
if (rcvPortsMsg.GetTranslatedPort(0) == MACH_PORT_NULL) {
LOG_ERROR("GetTranslatedPort(0) failed");
@ -198,23 +186,16 @@ RecvPortsMessage(ReceivePort* receiver, mach_port_t* ports_in_sender, mach_port_
}
// Send two communication ports to another process and receive two back
bool
RequestPorts(const MemoryPorts& request_ports,
mach_port_t ports_in_receiver,
mach_port_t* ports_in_sender,
mach_port_t* ports_out_sender,
mach_port_t ports_out_receiver,
PIDPair pid_pair)
{
bool RequestPorts(const MemoryPorts& request_ports, mach_port_t ports_in_receiver,
mach_port_t* ports_in_sender, mach_port_t* ports_out_sender,
mach_port_t ports_out_receiver, PIDPair pid_pair) {
if (!SendPortsMessage(request_ports.mSender, ports_in_receiver, ports_out_receiver, pid_pair)) {
return false;
}
return RecvPortsMessage(request_ports.mReceiver, ports_in_sender, ports_out_sender);
}
MemoryPorts*
GetMemoryPortsForPid(pid_t pid)
{
MemoryPorts* GetMemoryPortsForPid(pid_t pid) {
gMutex.AssertCurrentThreadOwns();
if (gMemoryCommPorts.find(pid) == gMemoryCommPorts.end()) {
@ -233,11 +214,8 @@ GetMemoryPortsForPid(pid_t pid)
auto* ports_in_receiver = new ReceivePort();
auto* ports_out_receiver = new ReceivePort();
mach_port_t raw_ports_in_sender, raw_ports_out_sender;
if (!RequestPorts(parent,
ports_in_receiver->GetPort(),
&raw_ports_in_sender,
&raw_ports_out_sender,
ports_out_receiver->GetPort(),
if (!RequestPorts(parent, ports_in_receiver->GetPort(), &raw_ports_in_sender,
&raw_ports_out_sender, ports_out_receiver->GetPort(),
PIDPair(getpid(), pid))) {
LOG_ERROR("failed to request ports\n");
return nullptr;
@ -246,11 +224,7 @@ GetMemoryPortsForPid(pid_t pid)
// is for replying with the Handle when we receive new memory.
auto* ports_in_sender = new MachPortSender(raw_ports_in_sender);
auto* ports_out_sender = new MachPortSender(raw_ports_out_sender);
SetupMachMemory(pid,
ports_in_receiver,
ports_in_sender,
ports_out_sender,
ports_out_receiver,
SetupMachMemory(pid, ports_in_receiver, ports_in_sender, ports_out_sender, ports_out_receiver,
false);
MOZ_ASSERT(gMemoryCommPorts.find(pid) != gMemoryCommPorts.end());
}
@ -260,9 +234,7 @@ GetMemoryPortsForPid(pid_t pid)
// We just received a port representing a region of shared memory, reply to
// the process that set it with the mach_port_t that represents it in this process.
// That will be the Handle to be shared over normal IPC
void
HandleSharePortsMessage(MachReceiveMessage* rmsg, MemoryPorts* ports)
{
void HandleSharePortsMessage(MachReceiveMessage* rmsg, MemoryPorts* ports) {
mach_port_t port = rmsg->GetTranslatedPort(0);
uint64_t* serial = reinterpret_cast<uint64_t*>(rmsg->GetData());
MachSendMessage msg(kReturnIdMsg);
@ -279,11 +251,8 @@ HandleSharePortsMessage(MachReceiveMessage* rmsg, MemoryPorts* ports)
// We were asked by another process to get communications ports to some process. Return
// those ports via an IPC message.
bool
SendReturnPortsMsg(MachPortSender* sender,
mach_port_t raw_ports_in_sender,
mach_port_t raw_ports_out_sender)
{
bool SendReturnPortsMsg(MachPortSender* sender, mach_port_t raw_ports_in_sender,
mach_port_t raw_ports_out_sender) {
MachSendMessage getPortsMsg(kReturnPortsMsg);
if (!getPortsMsg.AddDescriptor(MachMsgPortDescriptor(raw_ports_in_sender))) {
LOG_ERROR("Adding descriptor to message failed");
@ -296,7 +265,7 @@ SendReturnPortsMsg(MachPortSender* sender,
}
kern_return_t err = sender->SendMessage(getPortsMsg, kTimeout);
if (KERN_SUCCESS != err) {
LOG_ERROR("Error sending get ports message %s (%x)\n", mach_error_string(err), err);
LOG_ERROR("Error sending get ports message %s (%x)\n", mach_error_string(err), err);
return false;
}
return true;
@ -304,9 +273,7 @@ SendReturnPortsMsg(MachPortSender* sender,
// We were asked for communcations ports to a process that isn't us. Assuming that process
// is one of our children, forward that request on.
void
ForwardGetPortsMessage(MachReceiveMessage* rmsg, MemoryPorts* ports, PIDPair* pid_pair)
{
void ForwardGetPortsMessage(MachReceiveMessage* rmsg, MemoryPorts* ports, PIDPair* pid_pair) {
if (rmsg->GetTranslatedPort(0) == MACH_PORT_NULL) {
LOG_ERROR("GetTranslatedPort(0) failed");
return;
@ -330,9 +297,7 @@ ForwardGetPortsMessage(MachReceiveMessage* rmsg, MemoryPorts* ports, PIDPair* pi
}
// We receieved a message asking us to get communications ports for another process
void
HandleGetPortsMessage(MachReceiveMessage* rmsg, MemoryPorts* ports)
{
void HandleGetPortsMessage(MachReceiveMessage* rmsg, MemoryPorts* ports) {
PIDPair* pid_pair;
if (rmsg->GetDataLength() != sizeof(PIDPair)) {
LOG_ERROR("Improperly formatted message\n");
@ -358,20 +323,15 @@ HandleGetPortsMessage(MachReceiveMessage* rmsg, MemoryPorts* ports)
auto* ports_in_receiver = new ReceivePort();
auto* ports_out_receiver = new ReceivePort();
if (SendReturnPortsMsg(ports->mSender, ports_in_receiver->GetPort(), ports_out_receiver->GetPort())) {
SetupMachMemory(pid_pair->mRequester,
ports_out_receiver,
ports_out_sender,
ports_in_sender,
ports_in_receiver,
false);
if (SendReturnPortsMsg(ports->mSender, ports_in_receiver->GetPort(),
ports_out_receiver->GetPort())) {
SetupMachMemory(pid_pair->mRequester, ports_out_receiver, ports_out_sender, ports_in_sender,
ports_in_receiver, false);
}
}
}
static void *
PortServerThread(void *argument)
{
static void* PortServerThread(void* argument) {
MemoryPorts* ports = static_cast<MemoryPorts*>(argument);
MachReceiveMessage child_message;
while (true) {
@ -394,48 +354,42 @@ PortServerThread(void *argument)
} else {
StaticMutexAutoLock smal(gMutex);
switch (rmsg.GetMessageID()) {
case kSharePortsMsg:
HandleSharePortsMessage(&rmsg, ports);
break;
case kGetPortsMsg:
HandleGetPortsMessage(&rmsg, ports);
break;
case kCleanupMsg:
if (gParentPid == 0) {
LOG_ERROR("Cleanup message not valid for parent process");
continue;
}
case kSharePortsMsg:
HandleSharePortsMessage(&rmsg, ports);
break;
case kGetPortsMsg:
HandleGetPortsMessage(&rmsg, ports);
break;
case kCleanupMsg:
if (gParentPid == 0) {
LOG_ERROR("Cleanup message not valid for parent process");
continue;
}
pid_t* pid;
if (rmsg.GetDataLength() != sizeof(pid_t)) {
LOG_ERROR("Improperly formatted message\n");
continue;
}
pid = reinterpret_cast<pid_t*>(rmsg.GetData());
SharedMemoryBasic::CleanupForPid(*pid);
break;
default:
LOG_ERROR("Unknown message\n");
pid_t* pid;
if (rmsg.GetDataLength() != sizeof(pid_t)) {
LOG_ERROR("Improperly formatted message\n");
continue;
}
pid = reinterpret_cast<pid_t*>(rmsg.GetData());
SharedMemoryBasic::CleanupForPid(*pid);
break;
default:
LOG_ERROR("Unknown message\n");
}
}
}
}
void
SharedMemoryBasic::SetupMachMemory(pid_t pid,
ReceivePort* listen_port,
MachPortSender* listen_port_ack,
MachPortSender* send_port,
ReceivePort* send_port_ack,
bool pidIsParent)
{
void SharedMemoryBasic::SetupMachMemory(pid_t pid, ReceivePort* listen_port,
MachPortSender* listen_port_ack, MachPortSender* send_port,
ReceivePort* send_port_ack, bool pidIsParent) {
StaticMutexAutoLock smal(gMutex);
mozilla::ipc::SetupMachMemory(pid, listen_port, listen_port_ack, send_port, send_port_ack, pidIsParent);
mozilla::ipc::SetupMachMemory(pid, listen_port, listen_port_ack, send_port, send_port_ack,
pidIsParent);
}
void
SharedMemoryBasic::Shutdown()
{
void SharedMemoryBasic::Shutdown() {
StaticMutexAutoLock smal(gMutex);
layers::TextureSync::Shutdown();
@ -453,9 +407,7 @@ SharedMemoryBasic::Shutdown()
gMemoryCommPorts.clear();
}
void
SharedMemoryBasic::CleanupForPid(pid_t pid)
{
void SharedMemoryBasic::CleanupForPid(pid_t pid) {
if (gThreads.find(pid) == gThreads.end()) {
return;
}
@ -486,11 +438,8 @@ SharedMemoryBasic::CleanupForPid(pid_t pid)
gMemoryCommPorts.erase(pid);
}
bool
SharedMemoryBasic::SendMachMessage(pid_t pid,
MachSendMessage& message,
MachReceiveMessage* response)
{
bool SharedMemoryBasic::SendMachMessage(pid_t pid, MachSendMessage& message,
MachReceiveMessage* response) {
StaticMutexAutoLock smal(gMutex);
ipc::MemoryPorts* ports = GetMemoryPortsForPid(pid);
if (!ports) {
@ -521,21 +470,14 @@ SharedMemoryBasic::SendMachMessage(pid_t pid,
}
SharedMemoryBasic::SharedMemoryBasic()
: mPort(MACH_PORT_NULL)
, mMemory(nullptr)
, mOpenRights(RightsReadWrite)
{
}
: mPort(MACH_PORT_NULL), mMemory(nullptr), mOpenRights(RightsReadWrite) {}
SharedMemoryBasic::~SharedMemoryBasic()
{
SharedMemoryBasic::~SharedMemoryBasic() {
Unmap();
CloseHandle();
}
bool
SharedMemoryBasic::SetHandle(const Handle& aHandle, OpenRights aRights)
{
bool SharedMemoryBasic::SetHandle(const Handle& aHandle, OpenRights aRights) {
MOZ_ASSERT(mPort == MACH_PORT_NULL, "already initialized");
mPort = aHandle;
@ -543,34 +485,25 @@ SharedMemoryBasic::SetHandle(const Handle& aHandle, OpenRights aRights)
return true;
}
static inline void*
toPointer(mach_vm_address_t address)
{
static inline void* toPointer(mach_vm_address_t address) {
return reinterpret_cast<void*>(static_cast<uintptr_t>(address));
}
static inline mach_vm_address_t
toVMAddress(void* pointer)
{
static inline mach_vm_address_t toVMAddress(void* pointer) {
return static_cast<mach_vm_address_t>(reinterpret_cast<uintptr_t>(pointer));
}
bool
SharedMemoryBasic::Create(size_t size)
{
bool SharedMemoryBasic::Create(size_t size) {
MOZ_ASSERT(mPort == MACH_PORT_NULL, "already initialized");
memory_object_size_t memoryObjectSize = round_page(size);
kern_return_t kr = mach_make_memory_entry_64(mach_task_self(),
&memoryObjectSize,
0,
MAP_MEM_NAMED_CREATE | VM_PROT_DEFAULT,
&mPort,
MACH_PORT_NULL);
kern_return_t kr =
mach_make_memory_entry_64(mach_task_self(), &memoryObjectSize, 0,
MAP_MEM_NAMED_CREATE | VM_PROT_DEFAULT, &mPort, MACH_PORT_NULL);
if (kr != KERN_SUCCESS || memoryObjectSize < round_page(size)) {
LOG_ERROR("Failed to make memory entry (%zu bytes). %s (%x)\n",
size, mach_error_string(kr), kr);
LOG_ERROR("Failed to make memory entry (%zu bytes). %s (%x)\n", size, mach_error_string(kr),
kr);
CloseHandle();
return false;
}
@ -579,9 +512,7 @@ SharedMemoryBasic::Create(size_t size)
return true;
}
bool
SharedMemoryBasic::Map(size_t size)
{
bool SharedMemoryBasic::Map(size_t size) {
MOZ_ASSERT(mMemory == nullptr);
if (MACH_PORT_NULL == mPort) {
@ -596,11 +527,11 @@ SharedMemoryBasic::Map(size_t size)
vmProtection |= VM_PROT_WRITE;
}
kr = mach_vm_map(mach_task_self(), &address, round_page(size), 0, VM_FLAGS_ANYWHERE,
mPort, 0, false, vmProtection, vmProtection, VM_INHERIT_NONE);
kr = mach_vm_map(mach_task_self(), &address, round_page(size), 0, VM_FLAGS_ANYWHERE, mPort, 0,
false, vmProtection, vmProtection, VM_INHERIT_NONE);
if (kr != KERN_SUCCESS) {
LOG_ERROR("Failed to map shared memory (%zu bytes) into %x, port %x. %s (%x)\n",
size, mach_task_self(), mPort, mach_error_string(kr), kr);
LOG_ERROR("Failed to map shared memory (%zu bytes) into %x, port %x. %s (%x)\n", size,
mach_task_self(), mPort, mach_error_string(kr), kr);
return false;
}
@ -609,17 +540,15 @@ SharedMemoryBasic::Map(size_t size)
return true;
}
bool
SharedMemoryBasic::ShareToProcess(base::ProcessId pid,
Handle* aNewHandle)
{
bool SharedMemoryBasic::ShareToProcess(base::ProcessId pid, Handle* aNewHandle) {
if (pid == getpid()) {
*aNewHandle = mPort;
return mach_port_mod_refs(mach_task_self(), *aNewHandle, MACH_PORT_RIGHT_SEND, 1) == KERN_SUCCESS;
return mach_port_mod_refs(mach_task_self(), *aNewHandle, MACH_PORT_RIGHT_SEND, 1) ==
KERN_SUCCESS;
}
StaticMutexAutoLock smal(gMutex);
// Serially number the messages, to check whether
// Serially number the messages, to check whether
// the reply we get was meant for us.
static uint64_t serial = 0;
uint64_t my_serial = serial;
@ -664,24 +593,20 @@ SharedMemoryBasic::ShareToProcess(base::ProcessId pid,
return true;
}
void
SharedMemoryBasic::Unmap()
{
void SharedMemoryBasic::Unmap() {
if (!mMemory) {
return;
}
vm_address_t address = toVMAddress(mMemory);
kern_return_t kr = vm_deallocate(mach_task_self(), address, round_page(mMappedSize));
if (kr != KERN_SUCCESS) {
LOG_ERROR("Failed to deallocate shared memory. %s (%x)\n", mach_error_string(kr), kr);
LOG_ERROR("Failed to deallocate shared memory. %s (%x)\n", mach_error_string(kr), kr);
return;
}
mMemory = nullptr;
}
void
SharedMemoryBasic::CloseHandle()
{
void SharedMemoryBasic::CloseHandle() {
if (mPort != MACH_PORT_NULL) {
mach_port_deallocate(mach_task_self(), mPort);
mPort = MACH_PORT_NULL;
@ -689,11 +614,7 @@ SharedMemoryBasic::CloseHandle()
}
}
bool
SharedMemoryBasic::IsHandleValid(const Handle& aHandle) const
{
return aHandle > 0;
}
bool SharedMemoryBasic::IsHandleValid(const Handle& aHandle) const { return aHandle > 0; }
} // namespace ipc
} // namespace mozilla
} // namespace ipc
} // namespace mozilla

View File

@ -342,15 +342,18 @@ def run_command(command, check=False, **kwargs):
return stdout, stderr, status
# Replacement strings in environment variables.
REPLACEMENTS = {
'DIR': DIR.scripts,
'TOOLTOOL_CHECKOUT': DIR.tooltool,
'MOZ_UPLOAD_DIR': env['MOZ_UPLOAD_DIR'],
'OUTDIR': OUTDIR,
}
# Add in environment variable settings for this variant. Normally used to
# modify the flags passed to the shell or to set the GC zeal mode.
for k, v in variant.get('env', {}).items():
env[k.encode('ascii')] = v.encode('ascii').format(
DIR=DIR.scripts,
TOOLTOOL_CHECKOUT=DIR.tooltool,
MOZ_UPLOAD_DIR=env['MOZ_UPLOAD_DIR'],
OUTDIR=OUTDIR,
)
env[k.encode('ascii')] = v.encode('ascii').format(**REPLACEMENTS)
if AUTOMATION:
# Currently only supported on linux64.
@ -460,6 +463,10 @@ elif platform.system() == 'Darwin':
else:
variant_platform = 'other'
# Override environment variant settings conditionally.
for k, v in variant.get('conditional-env', {}).get(variant_platform, {}).items():
env[k.encode('ascii')] = v.encode('ascii').format(**REPLACEMENTS)
# Skip any tests that are not run on this platform (or the 'all' platform).
test_suites -= set(normalize_tests(variant.get('skip-tests', {}).get(variant_platform, [])))
test_suites -= set(normalize_tests(variant.get('skip-tests', {}).get('all', [])))

View File

@ -7,6 +7,11 @@
"JITTEST_EXTRA_ARGS": "--jitflags=debug --ignore-timeouts={DIR}/cgc-jittest-timeouts.txt",
"JSTESTS_EXTRA_ARGS": "--exclude-file={DIR}/cgc-jstests-slow.txt"
},
"conditional-env": {
"linux64": {
"JITTEST_EXTRA_ARGS": "--jitflags=debug --ignore-timeouts={DIR}/cgc-jittest-timeouts.txt --run-binast"
}
},
"skip-tests": {
"win32": ["jstests"],
"win64": ["jstests"]

View File

@ -3,5 +3,10 @@
"optimize": true,
"env": {
"JSTESTS_EXTRA_ARGS": "--jitflags=all"
},
"conditional-env": {
"linux64": {
"JITTEST_EXTRA_ARGS": "--run-binast"
}
}
}

View File

@ -3,5 +3,10 @@
"debug": true,
"env": {
"JSTESTS_EXTRA_ARGS": "--jitflags=debug"
},
"conditional-env": {
"linux64": {
"JITTEST_EXTRA_ARGS": "--run-binast"
}
}
}

View File

@ -104,7 +104,7 @@ void LifoAlloc::reset(size_t defaultChunkSize) {
chunks_.popFirst();
}
while (!oversize_.empty()) {
chunks_.popFirst();
oversize_.popFirst();
}
while (!unused_.empty()) {
unused_.popFirst();
@ -113,10 +113,15 @@ void LifoAlloc::reset(size_t defaultChunkSize) {
oversizeThreshold_ = defaultChunkSize;
markCount = 0;
curSize_ = 0;
oversizeSize_ = 0;
smallAllocsSize_ = 0;
}
void LifoAlloc::freeAll() {
// When free-ing all chunks, we can no longer determine which chunks were
// transferred and which were not, so simply clear the heuristic to zero
// right away.
smallAllocsSize_ = 0;
while (!chunks_.empty()) {
UniqueBumpChunk bc = chunks_.popFirst();
decrementCurSize(bc->computedSizeOfIncludingThis());
@ -124,7 +129,6 @@ void LifoAlloc::freeAll() {
while (!oversize_.empty()) {
UniqueBumpChunk bc = oversize_.popFirst();
decrementCurSize(bc->computedSizeOfIncludingThis());
oversizeSize_ -= bc->computedSizeOfIncludingThis();
}
while (!unused_.empty()) {
UniqueBumpChunk bc = unused_.popFirst();
@ -134,7 +138,6 @@ void LifoAlloc::freeAll() {
// Nb: maintaining curSize_ correctly isn't easy. Fortunately, this is an
// excellent sanity check.
MOZ_ASSERT(curSize_ == 0);
MOZ_ASSERT(oversizeSize_ == 0);
}
// Round at the same page granularity used by malloc.
@ -176,11 +179,14 @@ LifoAlloc::UniqueBumpChunk LifoAlloc::newChunkWithCapacity(size_t n,
return nullptr;
}
MOZ_ASSERT(curSize_ >= oversizeSize_);
// Note: When computing chunkSize growth, we only are interested in chunks
// used for small allocations. This excludes unused chunks, oversized chunks,
// and chunks transferred in from another LifoAlloc.
MOZ_ASSERT(curSize_ >= smallAllocsSize_);
const size_t chunkSize =
(oversize || minSize > defaultChunkSize_)
? MallocGoodSize(minSize)
: NextSize(defaultChunkSize_, curSize_ - oversizeSize_);
: NextSize(defaultChunkSize_, smallAllocsSize_);
// Create a new BumpChunk, and allocate space for it.
UniqueBumpChunk result = detail::BumpChunk::newWithCapacity(chunkSize);
@ -219,8 +225,7 @@ LifoAlloc::UniqueBumpChunk LifoAlloc::getOrCreateChunk(size_t n) {
if (!newChunk) {
return newChunk;
}
size_t size = newChunk->computedSizeOfIncludingThis();
incrementCurSize(size);
incrementCurSize(newChunk->computedSizeOfIncludingThis());
return newChunk;
}
@ -231,6 +236,9 @@ void* LifoAlloc::allocImplColdPath(size_t n) {
return nullptr;
}
// This new chunk is about to be used for small allocations.
smallAllocsSize_ += newChunk->computedSizeOfIncludingThis();
// Since we just created a large enough chunk, this can't fail.
chunks_.append(std::move(newChunk));
result = chunks_.last()->tryAlloc(n);
@ -245,7 +253,6 @@ void* LifoAlloc::allocImplOversize(size_t n) {
return nullptr;
}
incrementCurSize(newChunk->computedSizeOfIncludingThis());
oversizeSize_ += newChunk->computedSizeOfIncludingThis();
// Since we just created a large enough chunk, this can't fail.
oversize_.append(std::move(newChunk));
@ -266,9 +273,8 @@ bool LifoAlloc::ensureUnusedApproximateColdPath(size_t n, size_t total) {
if (!newChunk) {
return false;
}
size_t size = newChunk->computedSizeOfIncludingThis();
incrementCurSize(newChunk->computedSizeOfIncludingThis());
unused_.pushFront(std::move(newChunk));
incrementCurSize(size);
return true;
}
@ -325,6 +331,10 @@ void LifoAlloc::release(Mark mark) {
cutAtMark(mark.chunk, chunks_);
for (detail::BumpChunk& bc : released) {
bc.release();
// Chunks moved from (after a mark) in chunks_ to unused_ are no longer
// considered small allocations.
smallAllocsSize_ -= bc.computedSizeOfIncludingThis();
}
unused_.appendAll(std::move(released));
@ -333,7 +343,6 @@ void LifoAlloc::release(Mark mark) {
while (!released.empty()) {
UniqueBumpChunk bc = released.popFirst();
decrementCurSize(bc->computedSizeOfIncludingThis());
oversizeSize_ -= bc->computedSizeOfIncludingThis();
}
}
@ -353,7 +362,7 @@ void LifoAlloc::steal(LifoAlloc* other) {
oversizeThreshold_ = other->oversizeThreshold_;
curSize_ = other->curSize_;
peakSize_ = Max(peakSize_, other->peakSize_);
oversizeSize_ = other->oversizeSize_;
smallAllocsSize_ = other->smallAllocsSize_;
#if defined(DEBUG) || defined(JS_OOM_BREAKPOINT)
fallibleScope_ = other->fallibleScope_;
#endif
@ -365,13 +374,19 @@ void LifoAlloc::transferFrom(LifoAlloc* other) {
MOZ_ASSERT(!markCount);
MOZ_ASSERT(!other->markCount);
// Transferred chunks are not counted as part of |smallAllocsSize| as this
// could introduce bias in the |NextSize| heuristics, leading to
// over-allocations in *this* LifoAlloc. As well, to avoid interference with
// small allocations made with |this|, the last chunk of the |chunks_| list
// should remain the last chunk. Therefore, the transferred chunks are
// prepended to the |chunks_| list.
incrementCurSize(other->curSize_);
oversizeSize_ += other->oversizeSize_;
appendUnused(std::move(other->unused_));
appendUsed(std::move(other->chunks_));
oversize_.appendAll(std::move(other->oversize_));
chunks_.prependAll(std::move(other->chunks_));
oversize_.prependAll(std::move(other->oversize_));
other->curSize_ = 0;
other->oversizeSize_ = 0;
other->smallAllocsSize_ = 0;
}
void LifoAlloc::transferUnusedFrom(LifoAlloc* other) {

View File

@ -174,6 +174,17 @@ class SingleLinkedList {
assertInvariants();
list.assertInvariants();
}
void steal(SingleLinkedList&& list) {
head_ = std::move(list.head_);
last_ = list.last_;
list.last_ = nullptr;
assertInvariants();
list.assertInvariants();
}
void prependAll(SingleLinkedList&& list) {
list.appendAll(std::move(*this));
steal(std::move(list));
}
UniquePtr<T, D> popFirst() {
MOZ_ASSERT(head_);
UniquePtr<T, D> result = std::move(head_);
@ -505,7 +516,7 @@ class LifoAlloc {
// List of chunks containing allocated data where each allocation is larger
// than the oversize threshold. Each chunk contains exactly on allocation.
// This reduces wasted space in the normal chunk list.
// This reduces wasted space in the chunk list.
//
// Oversize chunks are allocated on demand and freed as soon as they are
// released, instead of being pushed to the unused list.
@ -517,9 +528,16 @@ class LifoAlloc {
size_t markCount;
size_t defaultChunkSize_;
size_t oversizeThreshold_;
// Size of all chunks in chunks_, oversize_, unused_ lists.
size_t curSize_;
size_t peakSize_;
size_t oversizeSize_;
// Size of all chunks containing small bump allocations. This heuristic is
// used to compute growth rate while ignoring chunks such as oversized,
// now-unused, or transferred (which followed their own growth patterns).
size_t smallAllocsSize_;
#if defined(DEBUG) || defined(JS_OOM_BREAKPOINT)
bool fallibleScope_;
#endif
@ -562,6 +580,7 @@ class LifoAlloc {
void decrementCurSize(size_t size) {
MOZ_ASSERT(curSize_ >= size);
curSize_ -= size;
MOZ_ASSERT(curSize_ >= smallAllocsSize_);
}
void* allocImplColdPath(size_t n);
@ -760,16 +779,22 @@ class LifoAlloc {
public:
void releaseAll() {
MOZ_ASSERT(!markCount);
// When releasing all chunks, we can no longer determine which chunks were
// transferred and which were not, so simply clear the heuristic to zero
// right away.
smallAllocsSize_ = 0;
for (detail::BumpChunk& bc : chunks_) {
bc.release();
}
unused_.appendAll(std::move(chunks_));
// On release, we free any oversize allocations instead of keeping them
// in unused chunks.
while (!oversize_.empty()) {
UniqueBumpChunk bc = oversize_.popFirst();
decrementCurSize(bc->computedSizeOfIncludingThis());
oversizeSize_ -= bc->computedSizeOfIncludingThis();
}
}

View File

@ -178,6 +178,11 @@ def main(argv):
op.add_option('--test-reflect-stringify', dest="test_reflect_stringify",
help="instead of running tests, use them to test the "
"Reflect.stringify code in specified file")
op.add_option('--run-binast', action='store_true',
dest="run_binast",
help="By default BinAST testcases encoded from JS "
"testcases are skipped. If specified, BinAST testcases "
"are also executed.")
options, args = op.parse_args(argv)
if len(args) < 1:
@ -227,7 +232,7 @@ def main(argv):
if test_args:
read_all = False
for arg in test_args:
test_list += jittests.find_tests(arg)
test_list += jittests.find_tests(arg, run_binast=options.run_binast)
if options.read_tests:
read_all = False
@ -247,7 +252,7 @@ def main(argv):
sys.stderr.write('---\n')
if read_all:
test_list = jittests.find_tests()
test_list = jittests.find_tests(run_binast=options.run_binast)
# Exclude tests when code coverage is enabled.
# This part is equivalent to:
@ -281,7 +286,7 @@ def main(argv):
if options.exclude:
exclude_list = []
for exclude in options.exclude:
exclude_list += jittests.find_tests(exclude)
exclude_list += jittests.find_tests(exclude, run_binast=options.run_binast)
test_list = [test for test in test_list
if test not in set(exclude_list)]
@ -327,8 +332,16 @@ def main(argv):
read_all = False
try:
with open(options.ignore_timeouts) as f:
options.ignore_timeouts = set(
[line.strip('\n') for line in f.readlines()])
ignore = set()
for line in f.readlines():
path = line.strip('\n')
ignore.add(path)
binjs_path = path.replace('.js', '.binjs')
# Do not use os.path.join to always use '/'.
ignore.add('binast/nonlazy/{}'.format(binjs_path))
ignore.add('binast/lazy/{}'.format(binjs_path))
options.ignore_timeouts = ignore
except IOError:
sys.exit("Error reading file: " + options.ignore_timeouts)
else:

View File

@ -0,0 +1 @@
// |jit-test| error:TypeError

View File

@ -0,0 +1 @@
// |jit-test| error:Error

View File

@ -0,0 +1 @@
|jit-test| skip-if: !this.hasOwnProperty("TypedObject")

View File

@ -0,0 +1 @@
// |jit-test| error:Error

View File

@ -0,0 +1 @@
// |jit-test| error:Error

View File

@ -0,0 +1 @@
// |jit-test| error:Error;

Some files were not shown because too many files have changed in this diff Show More