wayland_bridge/
viewporter.rs

1// Copyright 2018 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use crate::client::Client;
6use crate::compositor::{Surface, SurfaceCommand, ViewportCropParams, ViewportScaleParams};
7use crate::object::{NewObjectExt, ObjectRef, RequestReceiver};
8use anyhow::Error;
9use wp_viewporter_server_protocol::{
10    WpViewport, WpViewportRequest, WpViewporter, WpViewporterRequest,
11};
12
13/// An implementation of the wp_viewporter global.
14pub struct Viewporter;
15
16impl Viewporter {
17    /// Creates a new `Viewporter`.
18    pub fn new() -> Self {
19        Viewporter
20    }
21}
22
23impl RequestReceiver<WpViewporter> for Viewporter {
24    fn receive(
25        this: ObjectRef<Self>,
26        request: WpViewporterRequest,
27        client: &mut Client,
28    ) -> Result<(), Error> {
29        match request {
30            WpViewporterRequest::Destroy => {
31                client.delete_id(this.id())?;
32            }
33            WpViewporterRequest::GetViewport { id, surface } => {
34                let surface: ObjectRef<Surface> = surface.into();
35                id.implement(client, Viewport::new(surface))?;
36            }
37        }
38        Ok(())
39    }
40}
41
42struct Viewport {
43    surface_ref: ObjectRef<Surface>,
44}
45
46impl Viewport {
47    pub fn new(surface_ref: ObjectRef<Surface>) -> Self {
48        Viewport { surface_ref }
49    }
50}
51
52impl RequestReceiver<WpViewport> for Viewport {
53    fn receive(
54        this: ObjectRef<Self>,
55        request: WpViewportRequest,
56        client: &mut Client,
57    ) -> Result<(), Error> {
58        match request {
59            WpViewportRequest::Destroy => {
60                let surface_ref = this.get(client)?.surface_ref;
61                if let Ok(surface) = surface_ref.get_mut(client) {
62                    surface.enqueue(SurfaceCommand::ClearViewportCropParams);
63                    surface.enqueue(SurfaceCommand::ClearViewportScaleParams);
64                }
65                client.delete_id(this.id())?;
66            }
67            WpViewportRequest::SetSource { x, y, width, height } => {
68                let (x, y, width, height) =
69                    (x.to_float(), y.to_float(), width.to_float(), height.to_float());
70                let surface_ref = this.get(client)?.surface_ref;
71                let surface = surface_ref.get_mut(client)?;
72                if x == -1.0 && y == -1.0 && width == -1.0 && height == -1.0 {
73                    surface.enqueue(SurfaceCommand::ClearViewportCropParams);
74                } else {
75                    surface.enqueue(SurfaceCommand::SetViewportCropParams(ViewportCropParams {
76                        x,
77                        y,
78                        width,
79                        height,
80                    }));
81                }
82            }
83            WpViewportRequest::SetDestination { width, height } => {
84                let surface_ref = this.get(client)?.surface_ref;
85                let surface = surface_ref.get_mut(client)?;
86                if width == -1 && height == -1 {
87                    surface.enqueue(SurfaceCommand::ClearViewportScaleParams);
88                } else {
89                    surface.enqueue(SurfaceCommand::SetViewportScaleParams(ViewportScaleParams {
90                        width,
91                        height,
92                    }));
93                }
94            }
95        }
96        Ok(())
97    }
98}