1 /*******************************************************************************
2 * Copyright (c) 2009, 2017 IBM Corporation and others.
4 * This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License 2.0
6 * which accompanies this distribution, and is available at
7 * https://www.eclipse.org/legal/epl-2.0/
9 * SPDX-License-Identifier: EPL-2.0
12 * IBM Corporation - initial API and implementation
13 *******************************************************************************/
14 package org.eclipse.swt.accessibility;
16 import org.eclipse.swt.*;
17 import org.eclipse.swt.internal.*;
18 import org.eclipse.swt.internal.ole.win32.*;
19 import org.eclipse.swt.internal.win32.*;
22 Accessible accessible;
23 COMObject objIAccessibleRelation;
27 static final String[] relationTypeString = {
28 "controlledBy", //$NON-NLS-1$
29 "controllerFor", //$NON-NLS-1$
30 "describedBy", //$NON-NLS-1$
31 "descriptionFor", //$NON-NLS-1$
32 "embeddedBy", //$NON-NLS-1$
33 "embeds", //$NON-NLS-1$
34 "flowsFrom", //$NON-NLS-1$
35 "flowsTo", //$NON-NLS-1$
36 "labelFor", //$NON-NLS-1$
37 "labelledBy", //$NON-NLS-1$
38 "memberOf", //$NON-NLS-1$
39 "nodeChildOf", //$NON-NLS-1$
40 "parentWindowOf", //$NON-NLS-1$
41 "popupFor", //$NON-NLS-1$
42 "subwindowOf", //$NON-NLS-1$
44 static final String[] localizedRelationTypeString = {
45 SWT.getMessage("SWT_Controlled_By"), //$NON-NLS-1$
46 SWT.getMessage("SWT_Controller_For"), //$NON-NLS-1$
47 SWT.getMessage("SWT_Described_By"), //$NON-NLS-1$
48 SWT.getMessage("SWT_Description_For"), //$NON-NLS-1$
49 SWT.getMessage("SWT_Embedded_By"), //$NON-NLS-1$
50 SWT.getMessage("SWT_Embeds"), //$NON-NLS-1$
51 SWT.getMessage("SWT_Flows_From"), //$NON-NLS-1$
52 SWT.getMessage("SWT_Flows_To"), //$NON-NLS-1$
53 SWT.getMessage("SWT_Label_For"), //$NON-NLS-1$
54 SWT.getMessage("SWT_Labelled_By"), //$NON-NLS-1$
55 SWT.getMessage("SWT_Member_Of"), //$NON-NLS-1$
56 SWT.getMessage("SWT_Node_Child_Of"), //$NON-NLS-1$
57 SWT.getMessage("SWT_Parent_Window_Of"), //$NON-NLS-1$
58 SWT.getMessage("SWT_Popup_For"), //$NON-NLS-1$
59 SWT.getMessage("SWT_Subwindow_Of"), //$NON-NLS-1$
62 Relation(Accessible accessible, int type) {
63 this.accessible = accessible;
65 this.targets = new Accessible[0];
70 /* The address of a Relation is the address of its IAccessibleRelation COMObject. */
71 if (objIAccessibleRelation == null) createIAccessibleRelation();
72 return objIAccessibleRelation.getAddress();
75 void createIAccessibleRelation() {
76 objIAccessibleRelation = new COMObject(new int[] {2,0,0,1,1,1,2,3}) {
78 public long method0(long[] args) {return QueryInterface(args[0], args[1]);}
80 public long method1(long[] args) {return AddRef();}
82 public long method2(long[] args) {return Release();}
84 public long method3(long[] args) {return get_relationType(args[0]);}
86 public long method4(long[] args) {return get_localizedRelationType(args[0]);}
88 public long method5(long[] args) {return get_nTargets(args[0]);}
90 public long method6(long[] args) {return get_target((int)args[0], args[1]);}
92 public long method7(long[] args) {return get_targets((int)args[0], args[1], args[2]);}
96 /* QueryInterface([in] iid, [out] ppvObject)
97 * Ownership of ppvObject transfers from callee to caller so reference count on ppvObject
98 * must be incremented before returning. Caller is responsible for releasing ppvObject.
100 int QueryInterface(long iid, long ppvObject) {
101 GUID guid = new GUID();
102 COM.MoveMemory(guid, iid, GUID.sizeof);
104 if (COM.IsEqualGUID(guid, COM.IIDIUnknown) || COM.IsEqualGUID(guid, COM.IIDIAccessibleRelation)) {
105 OS.MoveMemory(ppvObject, new long[] { getAddress() }, C.PTR_SIZEOF);
110 return COM.E_NOINTERFACE;
122 if (objIAccessibleRelation != null)
123 objIAccessibleRelation.dispose();
124 objIAccessibleRelation = null;
129 /* IAccessibleRelation::get_relationType([out] pbstrRelationType) */
130 int get_relationType(long pbstrRelationType) {
131 setString(pbstrRelationType, relationTypeString[type]);
135 /* IAccessibleRelation::get_localizedRelationType([out] pbstrLocalizedRelationType) */
136 int get_localizedRelationType(long pbstrLocalizedRelationType) {
137 setString(pbstrLocalizedRelationType, localizedRelationTypeString[type]);
141 /* IAccessibleRelation::get_nTargets([out] pNTargets) */
142 int get_nTargets(long pNTargets) {
143 OS.MoveMemory(pNTargets, new int [] { targets.length }, 4);
147 /* IAccessibleRelation::get_target([in] targetIndex, [out] ppTarget) */
148 int get_target(int targetIndex, long ppTarget) {
149 if (targetIndex < 0 || targetIndex >= targets.length) return COM.E_INVALIDARG;
150 Accessible target = targets[targetIndex];
152 OS.MoveMemory(ppTarget, new long[] { target.getAddress() }, C.PTR_SIZEOF);
156 /* IAccessibleRelation::get_targets([in] maxTargets, [out] ppTargets, [out] pNTargets) */
157 int get_targets(int maxTargets, long ppTargets, long pNTargets) {
158 int count = Math.min(targets.length, maxTargets);
159 for (int i = 0; i < count; i++) {
160 Accessible target = targets[i];
162 OS.MoveMemory(ppTargets + i * C.PTR_SIZEOF, new long[] { target.getAddress() }, C.PTR_SIZEOF);
164 OS.MoveMemory(pNTargets, new int [] { count }, 4);
168 void addTarget(Accessible target) {
169 if (containsTarget(target)) return;
170 Accessible[] newTargets = new Accessible[targets.length + 1];
171 System.arraycopy(targets, 0, newTargets, 0, targets.length);
172 newTargets[targets.length] = target;
173 targets = newTargets;
176 boolean containsTarget(Accessible target) {
177 for (int i = 0; i < targets.length; i++) {
178 if (targets[i] == target) return true;
183 void removeTarget(Accessible target) {
184 if (!containsTarget(target)) return;
185 Accessible[] newTargets = new Accessible[targets.length - 1];
187 for (int i = 0; i < targets.length; i++) {
188 if (targets[i] != target) {
189 newTargets[j++] = targets[i];
192 targets = newTargets;
195 boolean hasTargets() {
196 return targets.length > 0;
199 // setString copied from Accessible class
200 void setString(long psz, String string) {
201 char[] data = (string + "\0").toCharArray();
202 long ptr = COM.SysAllocString(data);
203 OS.MoveMemory(psz, new long [] { ptr }, C.PTR_SIZEOF);