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