1 | // Copyright 2022 The AccessKit Authors. All rights reserved. |
2 | // Licensed under the Apache License, Version 2.0 (found in |
3 | // the LICENSE-APACHE file) or the MIT license (found in |
4 | // the LICENSE-MIT file), at your option. |
5 | |
6 | use accesskit_atspi_common::{NodeIdOrRoot, PlatformNode, PlatformRoot}; |
7 | use atspi::{Interface, InterfaceSet, Role, StateSet}; |
8 | use zbus::{fdo, names::OwnedUniqueName}; |
9 | |
10 | use super::map_root_error; |
11 | use crate::atspi::{ObjectId, OwnedObjectAddress}; |
12 | |
13 | pub(crate) struct NodeAccessibleInterface { |
14 | bus_name: OwnedUniqueName, |
15 | node: PlatformNode, |
16 | } |
17 | |
18 | impl NodeAccessibleInterface { |
19 | pub fn new(bus_name: OwnedUniqueName, node: PlatformNode) -> Self { |
20 | Self { bus_name, node } |
21 | } |
22 | |
23 | fn map_error(&self) -> impl '_ + FnOnce(accesskit_atspi_common::Error) -> fdo::Error { |
24 | |error: Error| crate::util::map_error_from_node(&self.node, error) |
25 | } |
26 | } |
27 | |
28 | #[dbus_interface (name = "org.a11y.atspi.Accessible" )] |
29 | impl NodeAccessibleInterface { |
30 | #[dbus_interface (property)] |
31 | fn name(&self) -> fdo::Result<String> { |
32 | self.node.name().map_err(self.map_error()) |
33 | } |
34 | |
35 | #[dbus_interface (property)] |
36 | fn description(&self) -> fdo::Result<String> { |
37 | self.node.description().map_err(self.map_error()) |
38 | } |
39 | |
40 | #[dbus_interface (property)] |
41 | fn parent(&self) -> fdo::Result<OwnedObjectAddress> { |
42 | self.node.parent().map_err(self.map_error()).map(|parent| { |
43 | match parent { |
44 | NodeIdOrRoot::Node(node) => ObjectId::Node { |
45 | adapter: self.node.adapter_id(), |
46 | node, |
47 | }, |
48 | NodeIdOrRoot::Root => ObjectId::Root, |
49 | } |
50 | .to_address(self.bus_name.clone()) |
51 | }) |
52 | } |
53 | |
54 | #[dbus_interface (property)] |
55 | fn child_count(&self) -> fdo::Result<i32> { |
56 | self.node.child_count().map_err(self.map_error()) |
57 | } |
58 | |
59 | #[dbus_interface (property)] |
60 | fn locale(&self) -> &str { |
61 | "" |
62 | } |
63 | |
64 | #[dbus_interface (property)] |
65 | fn accessible_id(&self) -> ObjectId { |
66 | ObjectId::from(&self.node) |
67 | } |
68 | |
69 | fn get_child_at_index(&self, index: i32) -> fdo::Result<(OwnedObjectAddress,)> { |
70 | let index = index |
71 | .try_into() |
72 | .map_err(|_| fdo::Error::InvalidArgs("Index can't be negative." .into()))?; |
73 | let child = self |
74 | .node |
75 | .child_at_index(index) |
76 | .map_err(self.map_error())? |
77 | .map(|child| ObjectId::Node { |
78 | adapter: self.node.adapter_id(), |
79 | node: child, |
80 | }); |
81 | Ok(super::optional_object_address(&self.bus_name, child)) |
82 | } |
83 | |
84 | fn get_children(&self) -> fdo::Result<Vec<OwnedObjectAddress>> { |
85 | self.node |
86 | .map_children(|child| { |
87 | ObjectId::Node { |
88 | adapter: self.node.adapter_id(), |
89 | node: child, |
90 | } |
91 | .to_address(self.bus_name.clone()) |
92 | }) |
93 | .map_err(self.map_error()) |
94 | } |
95 | |
96 | fn get_index_in_parent(&self) -> fdo::Result<i32> { |
97 | self.node.index_in_parent().map_err(self.map_error()) |
98 | } |
99 | |
100 | fn get_role(&self) -> fdo::Result<Role> { |
101 | self.node.role().map_err(self.map_error()) |
102 | } |
103 | |
104 | fn get_localized_role_name(&self) -> fdo::Result<String> { |
105 | self.node.localized_role_name().map_err(self.map_error()) |
106 | } |
107 | |
108 | fn get_state(&self) -> StateSet { |
109 | self.node.state() |
110 | } |
111 | |
112 | fn get_application(&self) -> (OwnedObjectAddress,) { |
113 | (ObjectId::Root.to_address(self.bus_name.clone()),) |
114 | } |
115 | |
116 | fn get_interfaces(&self) -> fdo::Result<InterfaceSet> { |
117 | self.node.interfaces().map_err(self.map_error()) |
118 | } |
119 | } |
120 | |
121 | pub(crate) struct RootAccessibleInterface { |
122 | bus_name: OwnedUniqueName, |
123 | desktop_address: OwnedObjectAddress, |
124 | root: PlatformRoot, |
125 | } |
126 | |
127 | impl RootAccessibleInterface { |
128 | pub fn new( |
129 | bus_name: OwnedUniqueName, |
130 | desktop_address: OwnedObjectAddress, |
131 | root: PlatformRoot, |
132 | ) -> Self { |
133 | Self { |
134 | bus_name, |
135 | desktop_address, |
136 | root, |
137 | } |
138 | } |
139 | } |
140 | |
141 | #[dbus_interface (name = "org.a11y.atspi.Accessible" )] |
142 | impl RootAccessibleInterface { |
143 | #[dbus_interface (property)] |
144 | fn name(&self) -> fdo::Result<String> { |
145 | self.root.name().map_err(map_root_error) |
146 | } |
147 | |
148 | #[dbus_interface (property)] |
149 | fn description(&self) -> &str { |
150 | "" |
151 | } |
152 | |
153 | #[dbus_interface (property)] |
154 | fn parent(&self) -> OwnedObjectAddress { |
155 | self.desktop_address.clone() |
156 | } |
157 | |
158 | #[dbus_interface (property)] |
159 | fn child_count(&self) -> fdo::Result<i32> { |
160 | self.root.child_count().map_err(map_root_error) |
161 | } |
162 | |
163 | #[dbus_interface (property)] |
164 | fn locale(&self) -> &str { |
165 | "" |
166 | } |
167 | |
168 | #[dbus_interface (property)] |
169 | fn accessible_id(&self) -> ObjectId { |
170 | ObjectId::Root |
171 | } |
172 | |
173 | fn get_child_at_index(&self, index: i32) -> fdo::Result<(OwnedObjectAddress,)> { |
174 | let index = index |
175 | .try_into() |
176 | .map_err(|_| fdo::Error::InvalidArgs("Index can't be negative." .into()))?; |
177 | let child = self |
178 | .root |
179 | .child_id_at_index(index) |
180 | .map_err(map_root_error)? |
181 | .map(|(adapter, node)| ObjectId::Node { adapter, node }); |
182 | Ok(super::optional_object_address(&self.bus_name, child)) |
183 | } |
184 | |
185 | fn get_children(&self) -> fdo::Result<Vec<OwnedObjectAddress>> { |
186 | self.root |
187 | .map_child_ids(|(adapter, node)| { |
188 | ObjectId::Node { adapter, node }.to_address(self.bus_name.clone()) |
189 | }) |
190 | .map_err(map_root_error) |
191 | } |
192 | |
193 | fn get_index_in_parent(&self) -> i32 { |
194 | -1 |
195 | } |
196 | |
197 | fn get_role(&self) -> Role { |
198 | Role::Application |
199 | } |
200 | |
201 | fn get_state(&self) -> StateSet { |
202 | StateSet::empty() |
203 | } |
204 | |
205 | fn get_application(&self) -> (OwnedObjectAddress,) { |
206 | (ObjectId::Root.to_address(self.bus_name.clone()),) |
207 | } |
208 | |
209 | fn get_interfaces(&self) -> InterfaceSet { |
210 | InterfaceSet::new(Interface::Accessible | Interface::Application) |
211 | } |
212 | } |
213 | |