1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
// 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/

//! This module provides structures and functionality related to surfaces.

// -------------------------------------------------------------------------------------------------

use std::time::Instant;

use graphics::attributes::{EglAttributes, DmabufAttributes};

use image::Image;
use memory::MemoryView;
use defs::{DmabufId, EglImageId, MemoryViewId};
use defs::{Position, Size, Vector};
pub use defs::{SurfaceId, SurfaceIdType};

// -------------------------------------------------------------------------------------------------

/// This structure defines how the surface should be drawn.
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct SurfaceContext {
    pub id: SurfaceId,
    pub pos: Position,
}

// -------------------------------------------------------------------------------------------------

impl SurfaceContext {
    /// `SurfaceContext` constructor.
    pub fn new(id: SurfaceId, pos: Position) -> Self {
        SurfaceContext { id: id, pos: pos }
    }

    /// Creates new context with position moved by given vector.
    pub fn moved(&self, vector: Vector) -> Self {
        SurfaceContext::new(self.id, self.pos + vector)
    }
}

// -------------------------------------------------------------------------------------------------

/// These flags describe readiness of `Surface` to be displayed.
pub mod show_reason {
    bitflags!(
        pub flags ShowReason: u32 {
            const NONE = 0b0000,
            const DRAWABLE = 0b0001,
            const IN_SHELL = 0b0010,
            const READY = DRAWABLE.bits | IN_SHELL.bits,
        }
    );
}

// -------------------------------------------------------------------------------------------------

/// These constants describe state of `Surface`.
pub mod surface_state {
    bitflags!(
        pub flags SurfaceState: u32 {
            const REGULAR = 0x0000,
            const MAXIMIZED = 0b0001,
            const FULLSCREEN = 0x0010,
            const RESIZING = 0x0100,
        }
    );
}

// -------------------------------------------------------------------------------------------------

/// This enum gathers information about source of data to be used when drawing surface.
///
/// Must be easy to copy and ensure data is not destroyed during use.
#[derive(Clone)]
pub enum DataSource {
    /// View on shared memory pool or buffer.
    Shm {
        source: MemoryView,
        time_stamp: Instant,
    },

    /// EGL image stored in graphic card memory.
    EglImage {
        source: EglAttributes,
        time_stamp: Instant,
    },

    /// Image stored in some graphic device (webcam, GPU, etc...).
    Dmabuf {
        source: DmabufAttributes,
        time_stamp: Instant,
    },

    /// Source unspecified.
    None,
}

// -------------------------------------------------------------------------------------------------

impl DataSource {
    /// Constructs new shared memory `DataSource`.
    pub fn new_shm(buffer: MemoryView) -> Self {
        DataSource::Shm {
            source: buffer,
            time_stamp: Instant::now(),
        }
    }

    /// Constructs new EGL image `DataSource`.
    pub fn new_egl_image(attrs: EglAttributes) -> Self {
        DataSource::EglImage {
            source: attrs,
            time_stamp: Instant::now(),
        }
    }

    /// Constructs new dmabuf `DataSource`.
    pub fn new_dmabuf(attrs: DmabufAttributes) -> Self {
        DataSource::Dmabuf {
            source: attrs,
            time_stamp: Instant::now(),
        }
    }

    /// Returns true if data source is unspecified, false otherwise.
    pub fn is_none(&self) -> bool {
        if let DataSource::None = *self {
            true
        } else {
            false
        }
    }

    /// Returns data as `Image` if available.
    pub fn as_image(&self) -> Option<&Image> {
        match *self {
            DataSource::Shm { source: ref memory_view, time_stamp: _ } => Some(memory_view),
            DataSource::EglImage { source: ref attrs, time_stamp: _ } => Some(attrs),
            DataSource::Dmabuf { source: ref attrs, time_stamp: _ } => Some(attrs),
            DataSource::None => None,
        }
    }
}

// -------------------------------------------------------------------------------------------------

/// Structure containing public information about surface.
#[derive(Clone)]
pub struct SurfaceInfo {
    pub id: SurfaceId,
    pub offset: Vector,
    pub parent_sid: SurfaceId,
    pub desired_size: Size,
    pub requested_size: Size,
    pub state_flags: surface_state::SurfaceState,
    pub data_source: DataSource,
}

// -------------------------------------------------------------------------------------------------

/// Managing surface content.
pub trait SurfaceManagement {
    /// Creates new surface with newly generated unique ID.
    fn create_surface(&mut self) -> SurfaceId;

    /// Sets given buffer as pending for given surface.
    fn attach_shm(&self, mvid: MemoryViewId, sid: SurfaceId);

    /// Sets given hardware image as pending for given surface.
    fn attach_egl_image(&self, eiid: EglImageId, sid: SurfaceId);

    /// Sets given dmabuf as pending for given surface.
    fn attach_dmabuf(&self, dmid: DmabufId, sid: SurfaceId);

    /// Informs other parts of application the surface is now not visible.
    fn detach_surface(&self, sid: SurfaceId);

    /// Commits the surface.
    fn commit_surface(&self, sid: SurfaceId);

    /// Detaches and forgets given surface.
    fn destroy_surface(&self, sid: SurfaceId);
}

// -------------------------------------------------------------------------------------------------

/// Controlling surfaces parameters like size, position and relationships.
pub trait SurfaceControl {
    /// Adds given show reason flag to set of surfaces show reason.
    fn show_surface(&self, sid: SurfaceId, reason: show_reason::ShowReason);

    /// Docks given surface.
    fn dock_surface(&self, sid: SurfaceId, size: Size, display_id: i32);

    /// Subtracts given show reason flag from set of surfaces show reason.
    fn hide_surface(&self, sid: SurfaceId, reason: show_reason::ShowReason);

    /// Sets position offset given surface.
    fn set_surface_offset(&self, sid: SurfaceId, offset: Vector);

    /// Sets requested size for given surface.
    fn set_surface_requested_size(&self, sid: SurfaceId, size: Size);

    /// Sets satellite surface position relative to its parent.
    fn set_surface_relative_position(&self, sid: SurfaceId, offset: Vector);

    /// Relates two surfaces.
    fn relate_surfaces(&self, sid: SurfaceId, parent_sid: SurfaceId);

    /// Unrelates two surfaces.
    fn unrelate_surface(&self, sid: SurfaceId);
}

// -------------------------------------------------------------------------------------------------

/// Viewing information about surface.
pub trait SurfaceViewer {
    /// Returns information about surface.
    fn get_surface(&self, sid: SurfaceId) -> Option<SurfaceInfo>;
}

// -------------------------------------------------------------------------------------------------

/// Trait used for configuring and manipulating surfaces.
pub trait SurfaceAccess {
    /// Reconfigure surface and send notification about this event.
    fn reconfigure(&mut self,
                   sid: SurfaceId,
                   size: Size,
                   state_flags: surface_state::SurfaceState);
}

// -------------------------------------------------------------------------------------------------

/// Listing related surfaces.
pub trait SurfaceListing {
    /// Returns surface context.
    fn get_renderer_context(&self, sid: SurfaceId) -> Option<Vec<SurfaceContext>>;
}

// -------------------------------------------------------------------------------------------------

/// Focusing and obtaining information about keyboard and pointer focus.
pub trait SurfaceFocusing {
    /// Returns ID of currently keyboard-focussed surface.
    fn get_keyboard_focused_sid(&self) -> SurfaceId;

    /// Informs rest of the application exhibitor set keyboard focus to given surface.
    fn set_keyboard_focus(&mut self, sid: SurfaceId);

    /// Returns ID of currently pointer-focussed surface.
    fn get_pointer_focused_sid(&self) -> SurfaceId;

    /// Informs rest of the application exhibitor set pointer focus to given surface.
    fn set_pointer_focus(&mut self, sid: SurfaceId, position: Position);
}

// -------------------------------------------------------------------------------------------------