michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "base/basictypes.h" michael@0: #include "ipc/IPCMessageUtils.h" michael@0: #include "mozilla/dom/DOMRect.h" michael@0: #include "mozilla/dom/NotifyPaintEvent.h" michael@0: #include "mozilla/dom/PaintRequest.h" michael@0: #include "mozilla/GfxMessageUtils.h" michael@0: #include "nsContentUtils.h" michael@0: michael@0: namespace mozilla { michael@0: namespace dom { michael@0: michael@0: NotifyPaintEvent::NotifyPaintEvent(EventTarget* aOwner, michael@0: nsPresContext* aPresContext, michael@0: WidgetEvent* aEvent, michael@0: uint32_t aEventType, michael@0: nsInvalidateRequestList* aInvalidateRequests) michael@0: : Event(aOwner, aPresContext, aEvent) michael@0: { michael@0: if (mEvent) { michael@0: mEvent->message = aEventType; michael@0: } michael@0: if (aInvalidateRequests) { michael@0: mInvalidateRequests.MoveElementsFrom(aInvalidateRequests->mRequests); michael@0: } michael@0: } michael@0: michael@0: NS_INTERFACE_MAP_BEGIN(NotifyPaintEvent) michael@0: NS_INTERFACE_MAP_ENTRY(nsIDOMNotifyPaintEvent) michael@0: NS_INTERFACE_MAP_END_INHERITING(Event) michael@0: michael@0: NS_IMPL_ADDREF_INHERITED(NotifyPaintEvent, Event) michael@0: NS_IMPL_RELEASE_INHERITED(NotifyPaintEvent, Event) michael@0: michael@0: nsRegion michael@0: NotifyPaintEvent::GetRegion() michael@0: { michael@0: nsRegion r; michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return r; michael@0: } michael@0: for (uint32_t i = 0; i < mInvalidateRequests.Length(); ++i) { michael@0: r.Or(r, mInvalidateRequests[i].mRect); michael@0: r.SimplifyOutward(10); michael@0: } michael@0: return r; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: NotifyPaintEvent::GetBoundingClientRect(nsIDOMClientRect** aResult) michael@0: { michael@0: *aResult = BoundingClientRect().take(); michael@0: return NS_OK; michael@0: } michael@0: michael@0: already_AddRefed michael@0: NotifyPaintEvent::BoundingClientRect() michael@0: { michael@0: nsRefPtr rect = new DOMRect(ToSupports(this)); michael@0: michael@0: if (mPresContext) { michael@0: rect->SetLayoutRect(GetRegion().GetBounds()); michael@0: } michael@0: michael@0: return rect.forget(); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: NotifyPaintEvent::GetClientRects(nsIDOMClientRectList** aResult) michael@0: { michael@0: *aResult = ClientRects().take(); michael@0: return NS_OK; michael@0: } michael@0: michael@0: already_AddRefed michael@0: NotifyPaintEvent::ClientRects() michael@0: { michael@0: nsISupports* parent = ToSupports(this); michael@0: nsRefPtr rectList = new DOMRectList(parent); michael@0: michael@0: nsRegion r = GetRegion(); michael@0: nsRegionRectIterator iter(r); michael@0: for (const nsRect* rgnRect = iter.Next(); rgnRect; rgnRect = iter.Next()) { michael@0: nsRefPtr rect = new DOMRect(parent); michael@0: michael@0: rect->SetLayoutRect(*rgnRect); michael@0: rectList->Append(rect); michael@0: } michael@0: michael@0: return rectList.forget(); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: NotifyPaintEvent::GetPaintRequests(nsISupports** aResult) michael@0: { michael@0: nsRefPtr requests = PaintRequests(); michael@0: requests.forget(aResult); michael@0: return NS_OK; michael@0: } michael@0: michael@0: already_AddRefed michael@0: NotifyPaintEvent::PaintRequests() michael@0: { michael@0: Event* parent = this; michael@0: nsRefPtr requests = new PaintRequestList(parent); michael@0: michael@0: if (nsContentUtils::IsCallerChrome()) { michael@0: for (uint32_t i = 0; i < mInvalidateRequests.Length(); ++i) { michael@0: nsRefPtr r = new PaintRequest(parent); michael@0: r->SetRequest(mInvalidateRequests[i]); michael@0: requests->Append(r); michael@0: } michael@0: } michael@0: michael@0: return requests.forget(); michael@0: } michael@0: michael@0: NS_IMETHODIMP_(void) michael@0: NotifyPaintEvent::Serialize(IPC::Message* aMsg, michael@0: bool aSerializeInterfaceType) michael@0: { michael@0: if (aSerializeInterfaceType) { michael@0: IPC::WriteParam(aMsg, NS_LITERAL_STRING("notifypaintevent")); michael@0: } michael@0: michael@0: Event::Serialize(aMsg, false); michael@0: michael@0: uint32_t length = mInvalidateRequests.Length(); michael@0: IPC::WriteParam(aMsg, length); michael@0: for (uint32_t i = 0; i < length; ++i) { michael@0: IPC::WriteParam(aMsg, mInvalidateRequests[i].mRect); michael@0: IPC::WriteParam(aMsg, mInvalidateRequests[i].mFlags); michael@0: } michael@0: } michael@0: michael@0: NS_IMETHODIMP_(bool) michael@0: NotifyPaintEvent::Deserialize(const IPC::Message* aMsg, void** aIter) michael@0: { michael@0: NS_ENSURE_TRUE(Event::Deserialize(aMsg, aIter), false); michael@0: michael@0: uint32_t length = 0; michael@0: NS_ENSURE_TRUE(IPC::ReadParam(aMsg, aIter, &length), false); michael@0: mInvalidateRequests.SetCapacity(length); michael@0: for (uint32_t i = 0; i < length; ++i) { michael@0: nsInvalidateRequestList::Request req; michael@0: NS_ENSURE_TRUE(IPC::ReadParam(aMsg, aIter, &req.mRect), false); michael@0: NS_ENSURE_TRUE(IPC::ReadParam(aMsg, aIter, &req.mFlags), false); michael@0: mInvalidateRequests.AppendElement(req); michael@0: } michael@0: michael@0: return true; michael@0: } michael@0: michael@0: } // namespace dom michael@0: } // namespace mozilla michael@0: michael@0: using namespace mozilla; michael@0: using namespace mozilla::dom; michael@0: michael@0: nsresult michael@0: NS_NewDOMNotifyPaintEvent(nsIDOMEvent** aInstancePtrResult, michael@0: EventTarget* aOwner, michael@0: nsPresContext* aPresContext, michael@0: WidgetEvent* aEvent, michael@0: uint32_t aEventType, michael@0: nsInvalidateRequestList* aInvalidateRequests) michael@0: { michael@0: NotifyPaintEvent* it = new NotifyPaintEvent(aOwner, aPresContext, aEvent, michael@0: aEventType, aInvalidateRequests); michael@0: NS_ADDREF(it); michael@0: *aInstancePtrResult = static_cast(it); michael@0: return NS_OK; michael@0: }