]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.eclipse.swt.win32.win32.x86_64/src/org/eclipse/swt/accessibility/Relation.java
Merge branch 'bug-623' into release/1.43.0
[simantics/platform.git] / bundles / org.eclipse.swt.win32.win32.x86_64 / src / org / eclipse / swt / accessibility / Relation.java
1 /*******************************************************************************
2  * Copyright (c) 2009, 2017 IBM Corporation and others.
3  *
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/
8  *
9  * SPDX-License-Identifier: EPL-2.0
10  *
11  * Contributors:
12  *     IBM Corporation - initial API and implementation
13  *******************************************************************************/
14 package org.eclipse.swt.accessibility;
15
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.*;
20
21 class Relation {
22         Accessible accessible;
23         COMObject objIAccessibleRelation;
24         int refCount;
25         int type;
26         Accessible[] targets;
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$
43         };
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$
60         };
61
62         Relation(Accessible accessible, int type) {
63                 this.accessible = accessible;
64                 this.type = type;
65                 this.targets = new Accessible[0];
66                 AddRef();
67         }
68
69         long getAddress() {
70                 /* The address of a Relation is the address of its IAccessibleRelation COMObject. */
71                 if (objIAccessibleRelation == null) createIAccessibleRelation();
72                 return objIAccessibleRelation.getAddress();
73         }
74
75         void createIAccessibleRelation() {
76                 objIAccessibleRelation = new COMObject(new int[] {2,0,0,1,1,1,2,3}) {
77                         @Override
78                         public long method0(long[] args) {return QueryInterface(args[0], args[1]);}
79                         @Override
80                         public long method1(long[] args) {return AddRef();}
81                         @Override
82                         public long method2(long[] args) {return Release();}
83                         @Override
84                         public long method3(long[] args) {return get_relationType(args[0]);}
85                         @Override
86                         public long method4(long[] args) {return get_localizedRelationType(args[0]);}
87                         @Override
88                         public long method5(long[] args) {return get_nTargets(args[0]);}
89                         @Override
90                         public long method6(long[] args) {return get_target((int)args[0], args[1]);}
91                         @Override
92                         public long method7(long[] args) {return get_targets((int)args[0], args[1], args[2]);}
93                 };
94         }
95
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.
99          */
100         int QueryInterface(long iid, long ppvObject) {
101                 GUID guid = new GUID();
102                 COM.MoveMemory(guid, iid, GUID.sizeof);
103
104                 if (COM.IsEqualGUID(guid, COM.IIDIUnknown) || COM.IsEqualGUID(guid, COM.IIDIAccessibleRelation)) {
105                         OS.MoveMemory(ppvObject, new long[] { getAddress() }, C.PTR_SIZEOF);
106                         AddRef();
107                         return COM.S_OK;
108                 }
109
110                 return COM.E_NOINTERFACE;
111         }
112
113         int AddRef() {
114                 refCount++;
115                 return refCount;
116         }
117
118         int Release() {
119                 refCount--;
120
121                 if (refCount == 0) {
122                         if (objIAccessibleRelation != null)
123                                 objIAccessibleRelation.dispose();
124                         objIAccessibleRelation = null;
125                 }
126                 return refCount;
127         }
128
129         /* IAccessibleRelation::get_relationType([out] pbstrRelationType) */
130         int get_relationType(long pbstrRelationType) {
131                 setString(pbstrRelationType, relationTypeString[type]);
132                 return COM.S_OK;
133         }
134
135         /* IAccessibleRelation::get_localizedRelationType([out] pbstrLocalizedRelationType) */
136         int get_localizedRelationType(long pbstrLocalizedRelationType) {
137                 setString(pbstrLocalizedRelationType, localizedRelationTypeString[type]);
138                 return COM.S_OK;
139         }
140
141         /* IAccessibleRelation::get_nTargets([out] pNTargets) */
142         int get_nTargets(long pNTargets) {
143                 OS.MoveMemory(pNTargets, new int [] { targets.length }, 4);
144                 return COM.S_OK;
145         }
146
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];
151                 target.AddRef();
152                 OS.MoveMemory(ppTarget, new long[] { target.getAddress() }, C.PTR_SIZEOF);
153                 return COM.S_OK;
154         }
155
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];
161                         target.AddRef();
162                         OS.MoveMemory(ppTargets + i * C.PTR_SIZEOF, new long[] { target.getAddress() }, C.PTR_SIZEOF);
163                 }
164                 OS.MoveMemory(pNTargets, new int [] { count }, 4);
165                 return COM.S_OK;
166         }
167
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;
174         }
175
176         boolean containsTarget(Accessible target) {
177                 for (int i = 0; i < targets.length; i++) {
178                         if (targets[i] == target) return true;
179                 }
180                 return false;
181         }
182
183         void removeTarget(Accessible target) {
184                 if (!containsTarget(target)) return;
185                 Accessible[] newTargets = new Accessible[targets.length - 1];
186                 int j = 0;
187                 for (int i = 0; i < targets.length; i++) {
188                         if (targets[i] != target) {
189                                 newTargets[j++] = targets[i];
190                         }
191                 }
192                 targets = newTargets;
193         }
194
195         boolean hasTargets() {
196                 return targets.length > 0;
197         }
198
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);
204         }
205 }