1/* gtkatspiutils.c: Shared utilities for ATSPI
2 *
3 * Copyright 2020 GNOME Foundation
4 *
5 * SPDX-License-Identifier: LGPL-2.1-or-later
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include "config.h"
22
23#include "gtkatspiutilsprivate.h"
24
25#include "gtkenums.h"
26#include "gtkpasswordentry.h"
27#include "gtkscrolledwindow.h"
28
29/*< private >
30 * gtk_accessible_role_to_atspi_role:
31 * @role: a `GtkAccessibleRole`
32 *
33 * Converts a `GtkAccessibleRole` value to the equivalent ATSPI role.
34 *
35 * Returns: an #AtspiRole
36 */
37static AtspiRole
38gtk_accessible_role_to_atspi_role (GtkAccessibleRole role)
39{
40 switch (role)
41 {
42 case GTK_ACCESSIBLE_ROLE_ALERT:
43 return ATSPI_ROLE_ALERT;
44
45 case GTK_ACCESSIBLE_ROLE_ALERT_DIALOG:
46 return ATSPI_ROLE_DIALOG;
47
48 case GTK_ACCESSIBLE_ROLE_BANNER:
49 break;
50
51 case GTK_ACCESSIBLE_ROLE_BUTTON:
52 return ATSPI_ROLE_PUSH_BUTTON;
53
54 case GTK_ACCESSIBLE_ROLE_CAPTION:
55 return ATSPI_ROLE_CAPTION;
56
57 case GTK_ACCESSIBLE_ROLE_CELL:
58 return ATSPI_ROLE_TABLE_CELL;
59
60 case GTK_ACCESSIBLE_ROLE_CHECKBOX:
61 return ATSPI_ROLE_CHECK_BOX;
62
63 case GTK_ACCESSIBLE_ROLE_COLUMN_HEADER:
64 break;
65
66 case GTK_ACCESSIBLE_ROLE_COMBO_BOX:
67 return ATSPI_ROLE_COMBO_BOX;
68
69 case GTK_ACCESSIBLE_ROLE_COMMAND:
70 break;
71
72 case GTK_ACCESSIBLE_ROLE_COMPOSITE:
73 break;
74
75 case GTK_ACCESSIBLE_ROLE_DIALOG:
76 return ATSPI_ROLE_DIALOG;
77
78 case GTK_ACCESSIBLE_ROLE_DOCUMENT:
79 return ATSPI_ROLE_DOCUMENT_TEXT;
80
81 case GTK_ACCESSIBLE_ROLE_FEED:
82 break;
83
84 case GTK_ACCESSIBLE_ROLE_FORM:
85 return ATSPI_ROLE_FORM;
86
87 case GTK_ACCESSIBLE_ROLE_GENERIC:
88 break;
89
90 case GTK_ACCESSIBLE_ROLE_GRID:
91 return ATSPI_ROLE_TABLE;
92
93 case GTK_ACCESSIBLE_ROLE_GRID_CELL:
94 return ATSPI_ROLE_TABLE_CELL;
95
96 case GTK_ACCESSIBLE_ROLE_GROUP:
97 return ATSPI_ROLE_PANEL;
98
99 case GTK_ACCESSIBLE_ROLE_HEADING:
100 return ATSPI_ROLE_HEADING;
101
102 case GTK_ACCESSIBLE_ROLE_IMG:
103 return ATSPI_ROLE_IMAGE;
104
105 case GTK_ACCESSIBLE_ROLE_INPUT:
106 return ATSPI_ROLE_ENTRY;
107
108 case GTK_ACCESSIBLE_ROLE_LABEL:
109 return ATSPI_ROLE_LABEL;
110
111 case GTK_ACCESSIBLE_ROLE_LANDMARK:
112 break;
113
114 case GTK_ACCESSIBLE_ROLE_LEGEND:
115 return ATSPI_ROLE_LABEL;
116
117 case GTK_ACCESSIBLE_ROLE_LINK:
118 return ATSPI_ROLE_LINK;
119
120 case GTK_ACCESSIBLE_ROLE_LIST:
121 return ATSPI_ROLE_LIST;
122
123 case GTK_ACCESSIBLE_ROLE_LIST_BOX:
124 return ATSPI_ROLE_LIST_BOX;
125
126 case GTK_ACCESSIBLE_ROLE_LIST_ITEM:
127 return ATSPI_ROLE_LIST_ITEM;
128
129 case GTK_ACCESSIBLE_ROLE_LOG:
130 return ATSPI_ROLE_LOG;
131
132 case GTK_ACCESSIBLE_ROLE_MAIN:
133 break;
134
135 case GTK_ACCESSIBLE_ROLE_MARQUEE:
136 return ATSPI_ROLE_MARQUEE;
137
138 case GTK_ACCESSIBLE_ROLE_MATH:
139 return ATSPI_ROLE_MATH;
140
141 case GTK_ACCESSIBLE_ROLE_METER:
142 return ATSPI_ROLE_LEVEL_BAR;
143
144 case GTK_ACCESSIBLE_ROLE_MENU:
145 return ATSPI_ROLE_MENU;
146
147 case GTK_ACCESSIBLE_ROLE_MENU_BAR:
148 return ATSPI_ROLE_MENU_BAR;
149
150 case GTK_ACCESSIBLE_ROLE_MENU_ITEM:
151 return ATSPI_ROLE_MENU_ITEM;
152
153 case GTK_ACCESSIBLE_ROLE_MENU_ITEM_CHECKBOX:
154 return ATSPI_ROLE_CHECK_MENU_ITEM;
155
156 case GTK_ACCESSIBLE_ROLE_MENU_ITEM_RADIO:
157 return ATSPI_ROLE_RADIO_MENU_ITEM;
158
159 case GTK_ACCESSIBLE_ROLE_NAVIGATION:
160 return ATSPI_ROLE_FILLER;
161
162 case GTK_ACCESSIBLE_ROLE_NONE:
163 return ATSPI_ROLE_INVALID;
164
165 case GTK_ACCESSIBLE_ROLE_NOTE:
166 return ATSPI_ROLE_FOOTNOTE;
167
168 case GTK_ACCESSIBLE_ROLE_OPTION:
169 return ATSPI_ROLE_OPTION_PANE;
170
171 case GTK_ACCESSIBLE_ROLE_PRESENTATION:
172 return ATSPI_ROLE_SECTION;
173
174 case GTK_ACCESSIBLE_ROLE_PROGRESS_BAR:
175 return ATSPI_ROLE_PROGRESS_BAR;
176
177 case GTK_ACCESSIBLE_ROLE_RADIO:
178 return ATSPI_ROLE_RADIO_BUTTON;
179
180 case GTK_ACCESSIBLE_ROLE_RADIO_GROUP:
181 return ATSPI_ROLE_GROUPING;
182
183 case GTK_ACCESSIBLE_ROLE_RANGE:
184 break;
185
186 case GTK_ACCESSIBLE_ROLE_REGION:
187 return ATSPI_ROLE_FILLER;
188
189 case GTK_ACCESSIBLE_ROLE_ROW:
190 return ATSPI_ROLE_TABLE_ROW;
191
192 case GTK_ACCESSIBLE_ROLE_ROW_GROUP:
193 return ATSPI_ROLE_GROUPING;
194
195 case GTK_ACCESSIBLE_ROLE_ROW_HEADER:
196 return ATSPI_ROLE_ROW_HEADER;
197
198 case GTK_ACCESSIBLE_ROLE_SCROLLBAR:
199 return ATSPI_ROLE_SCROLL_BAR;
200
201 case GTK_ACCESSIBLE_ROLE_SEARCH:
202 return ATSPI_ROLE_FORM;
203
204 case GTK_ACCESSIBLE_ROLE_SEARCH_BOX:
205 return ATSPI_ROLE_ENTRY;
206
207 case GTK_ACCESSIBLE_ROLE_SECTION:
208 return ATSPI_ROLE_FILLER;
209
210 case GTK_ACCESSIBLE_ROLE_SECTION_HEAD:
211 return ATSPI_ROLE_FILLER;
212
213 case GTK_ACCESSIBLE_ROLE_SELECT:
214 return ATSPI_ROLE_FILLER;
215
216 case GTK_ACCESSIBLE_ROLE_SEPARATOR:
217 return ATSPI_ROLE_SEPARATOR;
218
219 case GTK_ACCESSIBLE_ROLE_SLIDER:
220 return ATSPI_ROLE_SLIDER;
221
222 case GTK_ACCESSIBLE_ROLE_SPIN_BUTTON:
223 return ATSPI_ROLE_SPIN_BUTTON;
224
225 case GTK_ACCESSIBLE_ROLE_STATUS:
226 return ATSPI_ROLE_STATUS_BAR;
227
228 case GTK_ACCESSIBLE_ROLE_STRUCTURE:
229 return ATSPI_ROLE_FILLER;
230
231 case GTK_ACCESSIBLE_ROLE_SWITCH:
232 return ATSPI_ROLE_CHECK_BOX;
233
234 case GTK_ACCESSIBLE_ROLE_TAB:
235 return ATSPI_ROLE_PAGE_TAB;
236
237 case GTK_ACCESSIBLE_ROLE_TABLE:
238 return ATSPI_ROLE_TABLE;
239
240 case GTK_ACCESSIBLE_ROLE_TAB_LIST:
241 return ATSPI_ROLE_PAGE_TAB_LIST;
242
243 case GTK_ACCESSIBLE_ROLE_TAB_PANEL:
244 return ATSPI_ROLE_PANEL;
245
246 case GTK_ACCESSIBLE_ROLE_TEXT_BOX:
247 return ATSPI_ROLE_TEXT;
248
249 case GTK_ACCESSIBLE_ROLE_TIME:
250 return ATSPI_ROLE_TEXT;
251
252 case GTK_ACCESSIBLE_ROLE_TIMER:
253 return ATSPI_ROLE_TIMER;
254
255 case GTK_ACCESSIBLE_ROLE_TOOLBAR:
256 return ATSPI_ROLE_TOOL_BAR;
257
258 case GTK_ACCESSIBLE_ROLE_TOOLTIP:
259 return ATSPI_ROLE_TOOL_TIP;
260
261 case GTK_ACCESSIBLE_ROLE_TREE:
262 return ATSPI_ROLE_TREE;
263
264 case GTK_ACCESSIBLE_ROLE_TREE_GRID:
265 return ATSPI_ROLE_TREE_TABLE;
266
267 case GTK_ACCESSIBLE_ROLE_TREE_ITEM:
268 return ATSPI_ROLE_TREE_ITEM;
269
270 case GTK_ACCESSIBLE_ROLE_WIDGET:
271 return ATSPI_ROLE_FILLER;
272
273 case GTK_ACCESSIBLE_ROLE_WINDOW:
274 return ATSPI_ROLE_FRAME;
275
276 default:
277 break;
278 }
279
280 return ATSPI_ROLE_FILLER;
281}
282
283/*<private>
284 * gtk_atspi_role_for_context:
285 * @context: a `GtkATContext`
286 *
287 * Returns a suitable ATSPI role for a context, taking into account
288 * both the `GtkAccessibleRole` set on the context and the type
289 * of accessible.
290 *
291 * Returns: an #AtspiRole
292 */
293AtspiRole
294gtk_atspi_role_for_context (GtkATContext *context)
295{
296 GtkAccessible *accessible = gtk_at_context_get_accessible (self: context);
297 GtkAccessibleRole role = gtk_at_context_get_accessible_role (self: context);
298
299 /* ARIA does not have a "password entry" role, so we need to fudge it here */
300 if (GTK_IS_PASSWORD_ENTRY (accessible))
301 return ATSPI_ROLE_PASSWORD_TEXT;
302
303 /* ARIA does not have a "scroll area" role */
304 if (GTK_IS_SCROLLED_WINDOW (accessible))
305 return ATSPI_ROLE_SCROLL_PANE;
306
307 return gtk_accessible_role_to_atspi_role (role);
308}
309
310GVariant *
311gtk_at_spi_null_ref (void)
312{
313 return g_variant_new (format_string: "(so)", "", "/org/a11y/atspi/null");
314}
315
316void
317gtk_at_spi_emit_children_changed (GDBusConnection *connection,
318 const char *path,
319 GtkAccessibleChildState state,
320 int idx,
321 GVariant *child_ref,
322 GVariant *sender_ref)
323{
324 const char *change;
325
326 switch (state)
327 {
328 case GTK_ACCESSIBLE_CHILD_STATE_ADDED:
329 change = "add";
330 break;
331
332 case GTK_ACCESSIBLE_CHILD_STATE_REMOVED:
333 change = "remove";
334 break;
335
336 default:
337 g_assert_not_reached ();
338 return;
339 }
340
341 g_dbus_connection_emit_signal (connection,
342 NULL,
343 object_path: path,
344 interface_name: "org.a11y.atspi.Event.Object",
345 signal_name: "ChildrenChanged",
346 parameters: g_variant_new (format_string: "(siiv@(so))", change, idx, 0, child_ref, sender_ref),
347 NULL);
348}
349

source code of gtk/gtk/a11y/gtkatspiutils.c