1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef mozilla_ServoBindings_h 8 #define mozilla_ServoBindings_h 9 10 #include <stdint.h> 11 12 #include "mozilla/ServoTypes.h" 13 #include "mozilla/ServoBindingTypes.h" 14 #include "mozilla/ServoElementSnapshot.h" 15 #include "mozilla/css/SheetParsingMode.h" 16 #include "nsChangeHint.h" 17 #include "nsStyleStruct.h" 18 19 /* 20 * API for Servo to access Gecko data structures. This file must compile as valid 21 * C code in order for the binding generator to parse it. 22 * 23 * Functions beginning with Gecko_ are implemented in Gecko and invoked from Servo. 24 * Functions beginning with Servo_ are implemented in Servo and invoked from Gecko. 25 */ 26 27 class nsIAtom; 28 class nsIPrincipal; 29 class nsIURI; 30 struct nsFont; 31 namespace mozilla { 32 class FontFamilyList; 33 enum FontFamilyType : uint32_t; 34 } 35 using mozilla::FontFamilyList; 36 using mozilla::FontFamilyType; 37 using mozilla::ServoElementSnapshot; 38 struct nsStyleList; 39 struct nsStyleImage; 40 struct nsStyleGradientStop; 41 class nsStyleGradient; 42 class nsStyleCoord; 43 struct nsStyleDisplay; 44 45 #define NS_DECL_THREADSAFE_FFI_REFCOUNTING(class_, name_) \ 46 void Gecko_AddRef##name_##ArbitraryThread(class_* aPtr); \ 47 void Gecko_Release##name_##ArbitraryThread(class_* aPtr); 48 #define NS_IMPL_THREADSAFE_FFI_REFCOUNTING(class_, name_) \ 49 static_assert(class_::HasThreadSafeRefCnt::value, \ 50 "NS_DECL_THREADSAFE_FFI_REFCOUNTING can only be used with " \ 51 "classes that have thread-safe refcounting"); \ 52 void Gecko_AddRef##name_##ArbitraryThread(class_* aPtr) \ 53 { NS_ADDREF(aPtr); } \ 54 void Gecko_Release##name_##ArbitraryThread(class_* aPtr) \ 55 { NS_RELEASE(aPtr); } 56 57 #define NS_DECL_HOLDER_FFI_REFCOUNTING(class_, name_) \ 58 typedef nsMainThreadPtrHolder<class_> ThreadSafe##name_##Holder; \ 59 void Gecko_AddRef##name_##ArbitraryThread(ThreadSafe##name_##Holder* aPtr); \ 60 void Gecko_Release##name_##ArbitraryThread(ThreadSafe##name_##Holder* aPtr); 61 #define NS_IMPL_HOLDER_FFI_REFCOUNTING(class_, name_) \ 62 void Gecko_AddRef##name_##ArbitraryThread(ThreadSafe##name_##Holder* aPtr) \ 63 { NS_ADDREF(aPtr); } \ 64 void Gecko_Release##name_##ArbitraryThread(ThreadSafe##name_##Holder* aPtr) \ 65 { NS_RELEASE(aPtr); } \ 66 67 extern "C" { 68 69 // Object refcounting. 70 NS_DECL_HOLDER_FFI_REFCOUNTING(nsIPrincipal, Principal) 71 NS_DECL_HOLDER_FFI_REFCOUNTING(nsIURI, URI) 72 73 // DOM Traversal. 74 uint32_t Gecko_ChildrenCount(RawGeckoNodeBorrowed node); 75 bool Gecko_NodeIsElement(RawGeckoNodeBorrowed node); 76 RawGeckoNodeBorrowedOrNull Gecko_GetParentNode(RawGeckoNodeBorrowed node); 77 RawGeckoNodeBorrowedOrNull Gecko_GetFirstChild(RawGeckoNodeBorrowed node); 78 RawGeckoNodeBorrowedOrNull Gecko_GetLastChild(RawGeckoNodeBorrowed node); 79 RawGeckoNodeBorrowedOrNull Gecko_GetPrevSibling(RawGeckoNodeBorrowed node); 80 RawGeckoNodeBorrowedOrNull Gecko_GetNextSibling(RawGeckoNodeBorrowed node); 81 RawGeckoElementBorrowedOrNull Gecko_GetParentElement(RawGeckoElementBorrowed element); 82 RawGeckoElementBorrowedOrNull Gecko_GetFirstChildElement(RawGeckoElementBorrowed element); 83 RawGeckoElementBorrowedOrNull Gecko_GetLastChildElement(RawGeckoElementBorrowed element); 84 RawGeckoElementBorrowedOrNull Gecko_GetPrevSiblingElement(RawGeckoElementBorrowed element); 85 RawGeckoElementBorrowedOrNull Gecko_GetNextSiblingElement(RawGeckoElementBorrowed element); 86 RawGeckoElementBorrowedOrNull Gecko_GetDocumentElement(RawGeckoDocumentBorrowed document); 87 88 // By default, Servo walks the DOM by traversing the siblings of the DOM-view 89 // first child. This generally works, but misses anonymous children, which we 90 // want to traverse during styling. To support these cases, we create an 91 // optional heap-allocated iterator for nodes that need it. If the creation 92 // method returns null, Servo falls back to the aforementioned simpler (and 93 // faster) sibling traversal. 94 StyleChildrenIteratorOwnedOrNull Gecko_MaybeCreateStyleChildrenIterator(RawGeckoNodeBorrowed node); 95 void Gecko_DropStyleChildrenIterator(StyleChildrenIteratorOwned it); 96 RawGeckoNodeBorrowedOrNull Gecko_GetNextStyleChild(StyleChildrenIteratorBorrowedMut it); 97 98 // Selector Matching. 99 uint8_t Gecko_ElementState(RawGeckoElementBorrowed element); 100 bool Gecko_IsHTMLElementInHTMLDocument(RawGeckoElementBorrowed element); 101 bool Gecko_IsLink(RawGeckoElementBorrowed element); 102 bool Gecko_IsTextNode(RawGeckoNodeBorrowed node); 103 bool Gecko_IsVisitedLink(RawGeckoElementBorrowed element); 104 bool Gecko_IsUnvisitedLink(RawGeckoElementBorrowed element); 105 bool Gecko_IsRootElement(RawGeckoElementBorrowed element); 106 nsIAtom* Gecko_LocalName(RawGeckoElementBorrowed element); 107 nsIAtom* Gecko_Namespace(RawGeckoElementBorrowed element); 108 nsIAtom* Gecko_GetElementId(RawGeckoElementBorrowed element); 109 110 // Attributes. 111 #define SERVO_DECLARE_ELEMENT_ATTR_MATCHING_FUNCTIONS(prefix_, implementor_) \ 112 nsIAtom* prefix_##AtomAttrValue(implementor_ element, nsIAtom* attribute); \ 113 bool prefix_##HasAttr(implementor_ element, nsIAtom* ns, nsIAtom* name); \ 114 bool prefix_##AttrEquals(implementor_ element, nsIAtom* ns, nsIAtom* name, \ 115 nsIAtom* str, bool ignoreCase); \ 116 bool prefix_##AttrDashEquals(implementor_ element, nsIAtom* ns, \ 117 nsIAtom* name, nsIAtom* str); \ 118 bool prefix_##AttrIncludes(implementor_ element, nsIAtom* ns, \ 119 nsIAtom* name, nsIAtom* str); \ 120 bool prefix_##AttrHasSubstring(implementor_ element, nsIAtom* ns, \ 121 nsIAtom* name, nsIAtom* str); \ 122 bool prefix_##AttrHasPrefix(implementor_ element, nsIAtom* ns, \ 123 nsIAtom* name, nsIAtom* str); \ 124 bool prefix_##AttrHasSuffix(implementor_ element, nsIAtom* ns, \ 125 nsIAtom* name, nsIAtom* str); \ 126 uint32_t prefix_##ClassOrClassList(implementor_ element, nsIAtom** class_, \ 127 nsIAtom*** classList); 128 129 SERVO_DECLARE_ELEMENT_ATTR_MATCHING_FUNCTIONS(Gecko_, RawGeckoElementBorrowed) 130 SERVO_DECLARE_ELEMENT_ATTR_MATCHING_FUNCTIONS(Gecko_Snapshot, 131 ServoElementSnapshot*) 132 133 #undef SERVO_DECLARE_ELEMENT_ATTR_MATCHING_FUNCTIONS 134 135 // Style attributes. 136 RawServoDeclarationBlockStrongBorrowedOrNull 137 Gecko_GetServoDeclarationBlock(RawGeckoElementBorrowed element); 138 139 // Atoms. 140 nsIAtom* Gecko_Atomize(const char* aString, uint32_t aLength); 141 void Gecko_AddRefAtom(nsIAtom* aAtom); 142 void Gecko_ReleaseAtom(nsIAtom* aAtom); 143 const uint16_t* Gecko_GetAtomAsUTF16(nsIAtom* aAtom, uint32_t* aLength); 144 bool Gecko_AtomEqualsUTF8(nsIAtom* aAtom, const char* aString, uint32_t aLength); 145 bool Gecko_AtomEqualsUTF8IgnoreCase(nsIAtom* aAtom, const char* aString, uint32_t aLength); 146 147 // Strings (temporary until bug 1294742) 148 void Gecko_Utf8SliceToString(nsString* aString, 149 const uint8_t* aBuffer, 150 size_t aBufferLen); 151 152 // Font style 153 void Gecko_FontFamilyList_Clear(FontFamilyList* aList); 154 void Gecko_FontFamilyList_AppendNamed(FontFamilyList* aList, nsIAtom* aName); 155 void Gecko_FontFamilyList_AppendGeneric(FontFamilyList* list, FontFamilyType familyType); 156 void Gecko_CopyFontFamilyFrom(nsFont* dst, const nsFont* src); 157 158 // Counter style. 159 void Gecko_SetListStyleType(nsStyleList* style_struct, uint32_t type); 160 void Gecko_CopyListStyleTypeFrom(nsStyleList* dst, const nsStyleList* src); 161 162 // background-image style. 163 // TODO: support element() and -moz-image() 164 void Gecko_SetNullImageValue(nsStyleImage* image); 165 void Gecko_SetGradientImageValue(nsStyleImage* image, nsStyleGradient* gradient); 166 void Gecko_SetUrlImageValue(nsStyleImage* image, 167 const uint8_t* url_bytes, 168 uint32_t url_length, 169 ThreadSafeURIHolder* base_uri, 170 ThreadSafeURIHolder* referrer, 171 ThreadSafePrincipalHolder* principal); 172 void Gecko_CopyImageValueFrom(nsStyleImage* image, const nsStyleImage* other); 173 174 nsStyleGradient* Gecko_CreateGradient(uint8_t shape, 175 uint8_t size, 176 bool repeating, 177 bool legacy_syntax, 178 uint32_t stops); 179 180 // list-style-image style. 181 void Gecko_SetListStyleImageNone(nsStyleList* style_struct); 182 void Gecko_SetListStyleImage(nsStyleList* style_struct, 183 const uint8_t* string_bytes, uint32_t string_length, 184 ThreadSafeURIHolder* base_uri, 185 ThreadSafeURIHolder* referrer, 186 ThreadSafePrincipalHolder* principal); 187 void Gecko_CopyListStyleImageFrom(nsStyleList* dest, const nsStyleList* src); 188 189 // Display style. 190 void Gecko_SetMozBinding(nsStyleDisplay* style_struct, 191 const uint8_t* string_bytes, uint32_t string_length, 192 ThreadSafeURIHolder* base_uri, 193 ThreadSafeURIHolder* referrer, 194 ThreadSafePrincipalHolder* principal); 195 void Gecko_CopyMozBindingFrom(nsStyleDisplay* des, const nsStyleDisplay* src); 196 197 // Dirtiness tracking. 198 uint32_t Gecko_GetNodeFlags(RawGeckoNodeBorrowed node); 199 void Gecko_SetNodeFlags(RawGeckoNodeBorrowed node, uint32_t flags); 200 void Gecko_UnsetNodeFlags(RawGeckoNodeBorrowed node, uint32_t flags); 201 202 // Incremental restyle. 203 // TODO: We would avoid a few ffi calls if we decide to make an API like the 204 // former CalcAndStoreStyleDifference, but that would effectively mean breaking 205 // some safety guarantees in the servo side. 206 // 207 // Also, we might want a ComputedValues to ComputedValues API for animations? 208 // Not if we do them in Gecko... 209 nsStyleContext* Gecko_GetStyleContext(RawGeckoNodeBorrowed node, 210 nsIAtom* aPseudoTagOrNull); 211 nsChangeHint Gecko_CalcStyleDifference(nsStyleContext* oldstyle, 212 ServoComputedValuesBorrowed newstyle); 213 void Gecko_StoreStyleDifference(RawGeckoNodeBorrowed node, nsChangeHint change); 214 215 // `array` must be an nsTArray 216 // If changing this signature, please update the 217 // friend function declaration in nsTArray.h 218 void Gecko_EnsureTArrayCapacity(void* array, size_t capacity, size_t elem_size); 219 220 // Same here, `array` must be an nsTArray<T>, for some T. 221 // 222 // Important note: Only valid for POD types, since destructors won't be run 223 // otherwise. This is ensured with rust traits for the relevant structs. 224 void Gecko_ClearPODTArray(void* array, size_t elem_size, size_t elem_align); 225 226 // Clear the mContents field in nsStyleContent. This is needed to run the 227 // destructors, otherwise we'd leak the images (though we still don't support 228 // those), strings, and whatnot. 229 void Gecko_ClearStyleContents(nsStyleContent* content); 230 void Gecko_CopyStyleContentsFrom(nsStyleContent* content, const nsStyleContent* other); 231 232 void Gecko_EnsureImageLayersLength(nsStyleImageLayers* layers, size_t len, 233 nsStyleImageLayers::LayerType layer_type); 234 235 // Clean up pointer-based coordinates 236 void Gecko_ResetStyleCoord(nsStyleUnit* unit, nsStyleUnion* value); 237 238 // Set an nsStyleCoord to a computed `calc()` value 239 void Gecko_SetStyleCoordCalcValue(nsStyleUnit* unit, nsStyleUnion* value, nsStyleCoord::CalcValue calc); 240 241 void Gecko_CopyClipPathValueFrom(mozilla::StyleClipPath* dst, const mozilla::StyleClipPath* src); 242 243 void Gecko_DestroyClipPath(mozilla::StyleClipPath* clip); 244 mozilla::StyleBasicShape* Gecko_NewBasicShape(mozilla::StyleBasicShapeType type); 245 246 void Gecko_ResetFilters(nsStyleEffects* effects, size_t new_len); 247 void Gecko_CopyFiltersFrom(nsStyleEffects* aSrc, nsStyleEffects* aDest); 248 249 void Gecko_FillAllBackgroundLists(nsStyleImageLayers* layers, uint32_t max_len); 250 void Gecko_FillAllMaskLists(nsStyleImageLayers* layers, uint32_t max_len); 251 NS_DECL_THREADSAFE_FFI_REFCOUNTING(nsStyleCoord::Calc, Calc); 252 253 nsCSSShadowArray* Gecko_NewCSSShadowArray(uint32_t len); 254 NS_DECL_THREADSAFE_FFI_REFCOUNTING(nsCSSShadowArray, CSSShadowArray); 255 256 nsStyleQuoteValues* Gecko_NewStyleQuoteValues(uint32_t len); 257 NS_DECL_THREADSAFE_FFI_REFCOUNTING(nsStyleQuoteValues, QuoteValues); 258 259 nsCSSValueSharedList* Gecko_NewCSSValueSharedList(uint32_t len); 260 void Gecko_CSSValue_SetAbsoluteLength(nsCSSValueBorrowedMut css_value, nscoord len); 261 void Gecko_CSSValue_SetNumber(nsCSSValueBorrowedMut css_value, float number); 262 void Gecko_CSSValue_SetKeyword(nsCSSValueBorrowedMut css_value, nsCSSKeyword keyword); 263 void Gecko_CSSValue_SetPercentage(nsCSSValueBorrowedMut css_value, float percent); 264 void Gecko_CSSValue_SetAngle(nsCSSValueBorrowedMut css_value, float radians); 265 void Gecko_CSSValue_SetCalc(nsCSSValueBorrowedMut css_value, nsStyleCoord::CalcValue calc); 266 void Gecko_CSSValue_SetFunction(nsCSSValueBorrowedMut css_value, int32_t len); 267 nsCSSValueBorrowedMut Gecko_CSSValue_GetArrayItem(nsCSSValueBorrowedMut css_value, int32_t index); 268 NS_DECL_THREADSAFE_FFI_REFCOUNTING(nsCSSValueSharedList, CSSValueSharedList); 269 270 // Style-struct management. 271 #define STYLE_STRUCT(name, checkdata_cb) \ 272 void Gecko_Construct_nsStyle##name(nsStyle##name* ptr); \ 273 void Gecko_CopyConstruct_nsStyle##name(nsStyle##name* ptr, \ 274 const nsStyle##name* other); \ 275 void Gecko_Destroy_nsStyle##name(nsStyle##name* ptr); 276 #include "nsStyleStructList.h" 277 #undef STYLE_STRUCT 278 279 #define SERVO_BINDING_FUNC(name_, return_, ...) return_ name_(__VA_ARGS__); 280 #include "mozilla/ServoBindingList.h" 281 #undef SERVO_BINDING_FUNC 282 283 } // extern "C" 284 285 #endif // mozilla_ServoBindings_h 286