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
6use accesskit_atspi_common::{NodeIdOrRoot, PlatformNode, PlatformRoot};
7use atspi::{Interface, InterfaceSet, Role, StateSet};
8use zbus::{fdo, names::OwnedUniqueName};
9
10use super::map_root_error;
11use crate::atspi::{ObjectId, OwnedObjectAddress};
12
13pub(crate) struct NodeAccessibleInterface {
14 bus_name: OwnedUniqueName,
15 node: PlatformNode,
16}
17
18impl 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")]
29impl 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
121pub(crate) struct RootAccessibleInterface {
122 bus_name: OwnedUniqueName,
123 desktop_address: OwnedObjectAddress,
124 root: PlatformRoot,
125}
126
127impl 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")]
142impl 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