/* 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/. */ //! The high-level interface from script to constellation. Using this abstract interface helps //! reduce coupling between these two components. use std::cell::Cell; use std::fmt; use webrender_traits; #[derive(PartialEq, Eq, Copy, Clone, Debug, Deserialize, Serialize)] pub enum KeyState { Pressed, Released, Repeated, } //N.B. Based on the glutin key enum #[derive(Debug, PartialEq, Eq, Copy, Clone, Deserialize, Serialize, HeapSizeOf)] pub enum Key { Space, Apostrophe, Comma, Minus, Period, Slash, Num0, Num1, Num2, Num3, Num4, Num5, Num6, Num7, Num8, Num9, Semicolon, Equal, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, LeftBracket, Backslash, RightBracket, GraveAccent, World1, World2, Escape, Enter, Tab, Backspace, Insert, Delete, Right, Left, Down, Up, PageUp, PageDown, Home, End, CapsLock, ScrollLock, NumLock, PrintScreen, Pause, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F13, F14, F15, F16, F17, F18, F19, F20, F21, F22, F23, F24, F25, Kp0, Kp1, Kp2, Kp3, Kp4, Kp5, Kp6, Kp7, Kp8, Kp9, KpDecimal, KpDivide, KpMultiply, KpSubtract, KpAdd, KpEnter, KpEqual, LeftShift, LeftControl, LeftAlt, LeftSuper, RightShift, RightControl, RightAlt, RightSuper, Menu, NavigateBackward, NavigateForward, } bitflags! { #[derive(Deserialize, Serialize)] pub flags KeyModifiers: u8 { const NONE = 0x00, const SHIFT = 0x01, const CONTROL = 0x02, const ALT = 0x04, const SUPER = 0x08, } } #[derive(Clone, PartialEq, Eq, Copy, Hash, Debug, Deserialize, Serialize)] pub enum TraversalDirection { Forward(usize), Back(usize), } /// Each pipeline ID needs to be unique. However, it also needs to be possible to /// generate the pipeline ID from an iframe element (this simplifies a lot of other /// code that makes use of pipeline IDs). /// /// To achieve this, each pipeline index belongs to a particular namespace. There is /// a namespace for the constellation thread, and also one for every script thread. /// This allows pipeline IDs to be generated by any of those threads without conflicting /// with pipeline IDs created by other script threads or the constellation. The /// constellation is the only code that is responsible for creating new *namespaces*. /// This ensures that namespaces are always unique, even when using multi-process mode. /// /// It may help conceptually to think of the namespace ID as an identifier for the /// thread that created this pipeline ID - however this is really an implementation /// detail so shouldn't be relied upon in code logic. It's best to think of the /// pipeline ID as a simple unique identifier that doesn't convey any more information. #[derive(Clone, Copy)] pub struct PipelineNamespace { id: PipelineNamespaceId, index: u32, } impl PipelineNamespace { pub fn install(namespace_id: PipelineNamespaceId) { PIPELINE_NAMESPACE.with(|tls| { assert!(tls.get().is_none()); tls.set(Some(PipelineNamespace { id: namespace_id, index: 0, })); }); } fn next_index(&mut self) -> u32 { let result = self.index; self.index = result + 1; result } fn next_pipeline_id(&mut self) -> PipelineId { PipelineId { namespace_id: self.id, index: PipelineIndex(self.next_index()), } } fn next_frame_id(&mut self) -> FrameId { FrameId { namespace_id: self.id, index: FrameIndex(self.next_index()), } } } thread_local!(pub static PIPELINE_NAMESPACE: Cell> = Cell::new(None)); thread_local!(pub static PIPELINE_ID: Cell> = Cell::new(None)); #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Copy, Hash, Debug, Deserialize, Serialize, HeapSizeOf)] pub struct PipelineNamespaceId(pub u32); #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Copy, Hash, Debug, Deserialize, Serialize, HeapSizeOf)] pub struct PipelineIndex(pub u32); #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Copy, Hash, Debug, Deserialize, Serialize, HeapSizeOf)] pub struct PipelineId { pub namespace_id: PipelineNamespaceId, pub index: PipelineIndex } impl PipelineId { pub fn new() -> PipelineId { PIPELINE_NAMESPACE.with(|tls| { let mut namespace = tls.get().expect("No namespace set for this thread!"); let new_pipeline_id = namespace.next_pipeline_id(); tls.set(Some(namespace)); new_pipeline_id }) } pub fn to_webrender(&self) -> webrender_traits::PipelineId { let PipelineNamespaceId(namespace_id) = self.namespace_id; let PipelineIndex(index) = self.index; webrender_traits::PipelineId(namespace_id, index) } pub fn install(id: PipelineId) { PIPELINE_ID.with(|tls| tls.set(Some(id))) } pub fn installed() -> Option { PIPELINE_ID.with(|tls| tls.get()) } } impl fmt::Display for PipelineId { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { let PipelineNamespaceId(namespace_id) = self.namespace_id; let PipelineIndex(index) = self.index; write!(fmt, "({},{})", namespace_id, index) } } #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Copy, Hash, Debug, Deserialize, Serialize, HeapSizeOf)] pub struct FrameIndex(pub u32); #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Copy, Hash, Debug, Deserialize, Serialize, HeapSizeOf)] pub struct FrameId { pub namespace_id: PipelineNamespaceId, pub index: FrameIndex } impl FrameId { pub fn new() -> FrameId { PIPELINE_NAMESPACE.with(|tls| { let mut namespace = tls.get().expect("No namespace set for this thread!"); let new_frame_id = namespace.next_frame_id(); tls.set(Some(namespace)); new_frame_id }) } } impl fmt::Display for FrameId { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { let PipelineNamespaceId(namespace_id) = self.namespace_id; let FrameIndex(index) = self.index; write!(fmt, "({},{})", namespace_id, index) } } // We provide ids just for unit testing. pub const TEST_NAMESPACE: PipelineNamespaceId = PipelineNamespaceId(1234); pub const TEST_PIPELINE_INDEX: PipelineIndex = PipelineIndex(5678); pub const TEST_PIPELINE_ID: PipelineId = PipelineId { namespace_id: TEST_NAMESPACE, index: TEST_PIPELINE_INDEX }; pub const TEST_FRAME_INDEX: FrameIndex = FrameIndex(8765); pub const TEST_FRAME_ID: FrameId = FrameId { namespace_id: TEST_NAMESPACE, index: TEST_FRAME_INDEX }; #[derive(Clone, PartialEq, Eq, Copy, Hash, Debug, Deserialize, Serialize, HeapSizeOf)] pub enum FrameType { IFrame, MozBrowserIFrame, }