7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 #import "JavaAccessibilityUtilities.h"
27
28 #import <AppKit/AppKit.h>
29 #import <JavaNativeFoundation/JavaNativeFoundation.h>
30
31
32 static BOOL JavaAccessibilityIsSupportedAttribute(id element, NSString *attribute);
33 static void JavaAccessibilityLogError(NSString *message);
34 static void _JavaAccessibilityRaiseException(NSString *reason, SInt32 errorCode);
35 static NSString *AttributeWithoutAXPrefix(NSString *attribute);
36 static SEL JavaAccessibilityAttributeGetter(NSString *attribute);
37 static SEL JavaAccessibilityAttributeSettableTester(NSString *attribute);
38 static SEL JavaAccessibilityAttributeSetter(NSString *attribute);
39
40 NSString *const JavaAccessibilityIgnore = @"JavaAxIgnore";
41
42 NSMutableDictionary *sRoles = nil;
43 void initializeRoles();
44
45 // Unique
46 static JNF_CLASS_CACHE(sjc_AccessibleState, "javax/accessibility/AccessibleState");
47
48 // Duplicate
49 JNF_CLASS_CACHE(sjc_CAccessibility, "sun/lwawt/macosx/CAccessibility");
50 JNF_CLASS_CACHE(sjc_AccessibleComponent, "javax/accessibility/AccessibleComponent");
51 JNF_CLASS_CACHE(sjc_AccessibleContext, "javax/accessibility/AccessibleContext");
52 JNF_CLASS_CACHE(sjc_Accessible, "javax/accessibility/Accessible");
53 JNF_CLASS_CACHE(sjc_AccessibleRole, "javax/accessibility/AccessibleRole");
54 JNF_CLASS_CACHE(sjc_Point, "java/awt/Point");
55 JNF_CLASS_CACHE(sjc_AccessibleText, "javax/accessibility/AccessibleText");
56
57 JNF_MEMBER_CACHE(sjf_key, sjc_AccessibleRole, "key", "Ljava/lang/String;");
58 JNF_MEMBER_CACHE(sjf_X, sjc_Point, "x", "I");
59 JNF_MEMBER_CACHE(sjf_Y, sjc_Point, "y", "I");
60
61 NSSize getAxComponentSize(JNIEnv *env, jobject axComponent, jobject component)
62 {
63 static JNF_CLASS_CACHE(jc_Dimension, "java/awt/Dimension");
64 static JNF_MEMBER_CACHE(jf_width, jc_Dimension, "width", "I");
65 static JNF_MEMBER_CACHE(jf_height, jc_Dimension, "height", "I");
66 static JNF_STATIC_MEMBER_CACHE(jm_getSize, sjc_CAccessibility, "getSize", "(Ljavax/accessibility/AccessibleComponent;Ljava/awt/Component;)Ljava/awt/Dimension;");
67
68 jobject dimension = JNFCallStaticObjectMethod(env, jm_getSize, axComponent, component); // AWT_THREADING Safe (AWTRunLoopMode)
69
70 if (dimension == NULL) return NSZeroSize;
71 return NSMakeSize(JNFGetIntField(env, dimension, jf_width), JNFGetIntField(env, dimension, jf_height));
72 }
73
74 NSString *getJavaRole(JNIEnv *env, jobject axComponent, jobject component)
75 {
76 static JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleRole, sjc_CAccessibility, "getAccessibleRole", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljava/lang/String;");
77 jobject axRole = JNFCallStaticObjectMethod(env, sjm_getAccessibleRole, axComponent, component); // AWT_THREADING Safe (AWTRunLoopMode)
78 if (axRole == NULL) return @"unknown";
79
80 NSString* str = JNFJavaToNSString(env, axRole);
81 (*env)->DeleteLocalRef(env, axRole);
82 return str;
83 }
84
85 jobject getAxSelection(JNIEnv *env, jobject axContext, jobject component)
86 {
87 static JNF_STATIC_MEMBER_CACHE(jm_getAccessibleSelection, sjc_CAccessibility, "getAccessibleSelection", "(Ljavax/accessibility/AccessibleContext;Ljava/awt/Component;)Ljavax/accessibility/AccessibleSelection;");
88 return JNFCallStaticObjectMethod(env, jm_getAccessibleSelection, axContext, component); // AWT_THREADING Safe (AWTRunLoopMode)
89 }
90
91 jobject getAxContextSelection(JNIEnv *env, jobject axContext, jint index, jobject component)
92 {
93 static JNF_STATIC_MEMBER_CACHE(jm_ax_getAccessibleSelection, sjc_CAccessibility, "ax_getAccessibleSelection", "(Ljavax/accessibility/AccessibleContext;ILjava/awt/Component;)Ljavax/accessibility/Accessible;");
94 return JNFCallStaticObjectMethod(env, jm_ax_getAccessibleSelection, axContext, index, component); // AWT_THREADING Safe (AWTRunLoopMode)
95 }
96
97 void setAxContextSelection(JNIEnv *env, jobject axContext, jint index, jobject component)
98 {
99 static JNF_STATIC_MEMBER_CACHE(jm_addAccessibleSelection, sjc_CAccessibility, "addAccessibleSelection", "(Ljavax/accessibility/AccessibleContext;ILjava/awt/Component;)V");
100 JNFCallStaticVoidMethod(env, jm_addAccessibleSelection, axContext, index, component); // AWT_THREADING Safe (AWTRunLoopMode)
101 }
102
103 jobject getAxContext(JNIEnv *env, jobject accessible, jobject component)
104 {
105 static JNF_STATIC_MEMBER_CACHE(jm_getAccessibleContext, sjc_CAccessibility, "getAccessibleContext", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljavax/accessibility/AccessibleContext;");
106 return JNFCallStaticObjectMethod(env, jm_getAccessibleContext, accessible, component); // AWT_THREADING Safe (AWTRunLoopMode)
107 }
108
109 BOOL isChildSelected(JNIEnv *env, jobject accessible, jint index, jobject component)
110 {
111 static JNF_STATIC_MEMBER_CACHE(jm_isAccessibleChildSelected, sjc_CAccessibility, "isAccessibleChildSelected", "(Ljavax/accessibility/Accessible;ILjava/awt/Component;)Z");
112 return JNFCallStaticBooleanMethod(env, jm_isAccessibleChildSelected, accessible, index, component); // AWT_THREADING Safe (AWTRunLoopMode)
113 }
114
115 jobject getAxStateSet(JNIEnv *env, jobject axContext, jobject component)
116 {
117 static JNF_STATIC_MEMBER_CACHE(jm_getAccessibleStateSet, sjc_CAccessibility, "getAccessibleStateSet", "(Ljavax/accessibility/AccessibleContext;Ljava/awt/Component;)Ljavax/accessibility/AccessibleStateSet;");
118 return JNFCallStaticObjectMethod(env, jm_getAccessibleStateSet, axContext, component); // AWT_THREADING Safe (AWTRunLoopMode)
119 }
120
121 BOOL containsAxState(JNIEnv *env, jobject axContext, jobject axState, jobject component)
122 {
123 static JNF_STATIC_MEMBER_CACHE(jm_contains, sjc_CAccessibility, "contains", "(Ljavax/accessibility/AccessibleContext;Ljavax/accessibility/AccessibleState;Ljava/awt/Component;)Z");
124 return JNFCallStaticBooleanMethod(env, jm_contains, axContext, axState, component); // AWT_THREADING Safe (AWTRunLoopMode)
125 }
126
127 BOOL isVertical(JNIEnv *env, jobject axContext, jobject component)
128 {
129 static JNF_STATIC_MEMBER_CACHE(jm_VERTICAL, sjc_AccessibleState, "VERTICAL", "Ljavax/accessibility/AccessibleState;");
130 jobject axVertState = JNFGetStaticObjectField(env, jm_VERTICAL);
131 BOOL vertical = containsAxState(env, axContext, axVertState, component);
132 (*env)->DeleteLocalRef(env, axVertState);
133 return vertical;
134 }
135
136 BOOL isHorizontal(JNIEnv *env, jobject axContext, jobject component)
137 {
138 static JNF_STATIC_MEMBER_CACHE(jm_HORIZONTAL, sjc_AccessibleState, "HORIZONTAL", "Ljavax/accessibility/AccessibleState;");
139 jobject axHorizState = JNFGetStaticObjectField(env, jm_HORIZONTAL);
140 BOOL horizontal = containsAxState(env, axContext, axHorizState, component);
141 (*env)->DeleteLocalRef(env, axHorizState);
142 return horizontal;
143 }
144
145 BOOL isShowing(JNIEnv *env, jobject axContext, jobject component)
146 {
147 static JNF_STATIC_MEMBER_CACHE(jm_SHOWING, sjc_AccessibleState, "SHOWING", "Ljavax/accessibility/AccessibleState;");
148 jobject axVisibleState = JNFGetStaticObjectField(env, jm_SHOWING);
149 BOOL showing = containsAxState(env, axContext, axVisibleState, component);
150 (*env)->DeleteLocalRef(env, axVisibleState);
151 return showing;
152 }
153
154 BOOL isSelectable(JNIEnv *env, jobject axContext, jobject component)
155 {
156 static JNF_STATIC_MEMBER_CACHE( jm_SELECTABLE,
157 sjc_AccessibleState,
158 "SELECTABLE",
159 "Ljavax/accessibility/AccessibleState;" );
160 jobject axSelectableState = JNFGetStaticObjectField(env, jm_SELECTABLE);
161 BOOL selectable = containsAxState(env, axContext, axSelectableState, component);
162 (*env)->DeleteLocalRef(env, axSelectableState);
163 return selectable;
164 }
165
166 NSPoint getAxComponentLocationOnScreen(JNIEnv *env, jobject axComponent, jobject component)
167 {
168 static JNF_STATIC_MEMBER_CACHE(jm_getLocationOnScreen, sjc_CAccessibility, "getLocationOnScreen", "(Ljavax/accessibility/AccessibleComponent;Ljava/awt/Component;)Ljava/awt/Point;");
169 jobject jpoint = JNFCallStaticObjectMethod(env, jm_getLocationOnScreen, axComponent, component); // AWT_THREADING Safe (AWTRunLoopMode)
170 if (jpoint == NULL) return NSZeroPoint;
171 return NSMakePoint(JNFGetIntField(env, jpoint, sjf_X), JNFGetIntField(env, jpoint, sjf_Y));
172 }
173
174 jint getAxTextCharCount(JNIEnv *env, jobject axText, jobject component)
175 {
176 static JNF_STATIC_MEMBER_CACHE(jm_getCharCount, sjc_CAccessibility, "getCharCount", "(Ljavax/accessibility/AccessibleText;Ljava/awt/Component;)I");
177 return JNFCallStaticIntMethod(env, jm_getCharCount, axText, component); // AWT_THREADING Safe (AWTRunLoopMode)
178 }
179
180 // The following JavaAccessibility methods are copied from the corresponding
181 // NSAccessibility methods in NSAccessibility.m.
182 //
183 // They implement a key-value-like coding scheme to transform messages like
184 // [self accessibilityAttributeValue:NSAccessibilityEnabledAttribute]
185 // into calls on to specific methods like
186 // [self accessibilityEnabledAttribute].
187
188 static NSString *AttributeWithoutAXPrefix(NSString *attribute)
189 {
190 return [attribute hasPrefix:@"AX"] ? [attribute substringFromIndex:2] : attribute;
191 }
192
193 static SEL JavaAccessibilityAttributeGetter(NSString *attribute)
194 {
195 return NSSelectorFromString([NSString stringWithFormat:@"accessibility%@Attribute", AttributeWithoutAXPrefix(attribute)]);
196 }
197
248 return;
249 }
250 #endif
251
252 [element performSelector:setter withObject:value];
253 }
254
255 static BOOL JavaAccessibilityIsSupportedAttribute(id element, NSString *attribute)
256 {
257 return [[element accessibilityAttributeNames] indexOfObject:attribute] != NSNotFound;
258 }
259
260 /*
261 * Class: sun_lwawt_macosx_CAccessibility
262 * Method: roleKey
263 * Signature: (Ljavax/accessibility/AccessibleRole;)Ljava/lang/String;
264 */
265 JNIEXPORT jstring JNICALL Java_sun_lwawt_macosx_CAccessibility_roleKey
266 (JNIEnv *env, jclass clz, jobject axRole)
267 {
268 return JNFGetObjectField(env, axRole, sjf_key);
269 }
270
271
272 // errors from NSAccessibilityErrors
273 void JavaAccessibilityRaiseSetAttributeToIllegalTypeException(const char *functionName, id element, NSString *attribute, id value)
274 {
275 NSString *reason = [NSString stringWithFormat:@"%s: Attempt set \"%@\" attribute to illegal type of value (%@:%@) for element: %@", functionName, attribute, [value class], value, element];
276 _JavaAccessibilityRaiseException(reason, kAXErrorIllegalArgument);
277 }
278
279 void JavaAccessibilityRaiseUnimplementedAttributeException(const char *functionName, id element, NSString *attribute)
280 {
281 NSString *reason = [NSString stringWithFormat:@"%s: \"%@\" attribute unimplemented by element: %@", functionName, attribute, element];
282 _JavaAccessibilityRaiseException(reason, kAXErrorFailure);
283 }
284
285 void JavaAccessibilityRaiseIllegalParameterTypeException(const char *functionName, id element, NSString *attribute, id parameter)
286 {
287 NSString *reason = [NSString stringWithFormat:@"%s: \"%@\" parameterized attribute passed illegal type of parameter (%@:%@) for element: %@", functionName, attribute, [parameter class], parameter, element];
288 _JavaAccessibilityRaiseException(reason, kAXErrorIllegalArgument);
|
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 #import "JavaAccessibilityUtilities.h"
27 #import "JNIUtilities.h"
28
29 #import <AppKit/AppKit.h>
30
31 static BOOL JavaAccessibilityIsSupportedAttribute(id element, NSString *attribute);
32 static void JavaAccessibilityLogError(NSString *message);
33 static void _JavaAccessibilityRaiseException(NSString *reason, SInt32 errorCode);
34 static NSString *AttributeWithoutAXPrefix(NSString *attribute);
35 static SEL JavaAccessibilityAttributeGetter(NSString *attribute);
36 static SEL JavaAccessibilityAttributeSettableTester(NSString *attribute);
37 static SEL JavaAccessibilityAttributeSetter(NSString *attribute);
38
39 NSString *const JavaAccessibilityIgnore = @"JavaAxIgnore";
40
41 NSMutableDictionary *sRoles = nil;
42 void initializeRoles();
43
44 // Unique
45 static jclass sjc_AccessibleState = NULL;
46 #define GET_ACCESSIBLESTATE_CLASS_RETURN(ret) \
47 GET_CLASS_RETURN(sjc_AccessibleState, "javax/accessibility/AccessibleState", ret);
48
49 static jclass sjc_CAccessibility = NULL;
50
51 NSSize getAxComponentSize(JNIEnv *env, jobject axComponent, jobject component)
52 {
53 DECLARE_CLASS_RETURN(jc_Dimension, "java/awt/Dimension", NSZeroSize);
54 DECLARE_FIELD_RETURN(jf_width, jc_Dimension, "width", "I", NSZeroSize);
55 DECLARE_FIELD_RETURN(jf_height, jc_Dimension, "height", "I", NSZeroSize);
56 DECLARE_STATIC_METHOD_RETURN(jm_getSize, sjc_CAccessibility, "getSize",
57 "(Ljavax/accessibility/AccessibleComponent;Ljava/awt/Component;)Ljava/awt/Dimension;", NSZeroSize);
58
59 jobject dimension = (*env)->CallStaticObjectMethod(env, jc_Dimension, jm_getSize, axComponent, component);
60 CHECK_EXCEPTION();
61
62 if (dimension == NULL) return NSZeroSize;
63 return NSMakeSize((*env)->GetIntField(env, dimension, jf_width), (*env)->GetIntField(env, dimension, jf_height));
64 }
65
66 NSString *getJavaRole(JNIEnv *env, jobject axComponent, jobject component)
67 {
68 GET_CACCESSIBILITY_CLASS_RETURN(nil);
69 DECLARE_STATIC_METHOD_RETURN(sjm_getAccessibleRole, sjc_CAccessibility, "getAccessibleRole",
70 "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljava/lang/String;", nil);
71 jobject axRole = (*env)->CallStaticObjectMethod(env, sjc_CAccessibility, sjm_getAccessibleRole,
72 axComponent, component);
73 CHECK_EXCEPTION();
74 if (axRole == NULL) return @"unknown";
75
76 NSString* str = JavaStringToNSString(env, axRole);
77 (*env)->DeleteLocalRef(env, axRole);
78 return str;
79 }
80
81 jobject getAxSelection(JNIEnv *env, jobject axContext, jobject component)
82 {
83 GET_CACCESSIBILITY_CLASS_RETURN(nil);
84 DECLARE_STATIC_METHOD_RETURN(jm_getAccessibleSelection, sjc_CAccessibility, "getAccessibleSelection",
85 "(Ljavax/accessibility/AccessibleContext;Ljava/awt/Component;)Ljavax/accessibility/AccessibleSelection;", nil);
86 jobject o = (*env)->CallStaticObjectMethod(env, sjc_CAccessibility, jm_getAccessibleSelection,
87 axContext, component);
88 CHECK_EXCEPTION();
89 return o;
90 }
91
92 jobject getAxContextSelection(JNIEnv *env, jobject axContext, jint index, jobject component)
93 {
94 GET_CACCESSIBILITY_CLASS_RETURN(nil);
95 DECLARE_STATIC_METHOD_RETURN(jm_ax_getAccessibleSelection, sjc_CAccessibility, "ax_getAccessibleSelection",
96 "(Ljavax/accessibility/AccessibleContext;ILjava/awt/Component;)Ljavax/accessibility/Accessible;", nil);
97 return (*env)->CallStaticObjectMethod(env, sjc_CAccessibility, jm_ax_getAccessibleSelection,
98 axContext, index, component);
99 CHECK_EXCEPTION();
100 }
101
102 void setAxContextSelection(JNIEnv *env, jobject axContext, jint index, jobject component)
103 {
104 GET_CACCESSIBILITY_CLASS();
105 DECLARE_STATIC_METHOD(jm_addAccessibleSelection, sjc_CAccessibility, "addAccessibleSelection",
106 "(Ljavax/accessibility/AccessibleContext;ILjava/awt/Component;)V");
107 (*env)->CallStaticVoidMethod(env, sjc_CAccessibility, jm_addAccessibleSelection,
108 axContext, index, component);
109 CHECK_EXCEPTION();
110 }
111
112 jobject getAxContext(JNIEnv *env, jobject accessible, jobject component)
113 {
114 GET_CACCESSIBILITY_CLASS_RETURN(nil);
115 DECLARE_STATIC_METHOD_RETURN(jm_getAccessibleContext, sjc_CAccessibility, "getAccessibleContext",
116 "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljavax/accessibility/AccessibleContext;", nil);
117 jobject o = (*env)->CallStaticObjectMethod(env, sjc_CAccessibility, jm_getAccessibleContext,
118 accessible, component);
119 CHECK_EXCEPTION();
120 return o;
121 }
122
123 BOOL isChildSelected(JNIEnv *env, jobject accessible, jint index, jobject component)
124 {
125 GET_CACCESSIBILITY_CLASS_RETURN(NO);
126 DECLARE_STATIC_METHOD_RETURN(jm_isAccessibleChildSelected, sjc_CAccessibility, "isAccessibleChildSelected",
127 "(Ljavax/accessibility/Accessible;ILjava/awt/Component;)Z", NO);
128 jboolean b = (*env)->CallStaticBooleanMethod(env, sjc_CAccessibility, jm_isAccessibleChildSelected,
129 accessible, index, component);
130 CHECK_EXCEPTION();
131 return b;
132 }
133
134 jobject getAxStateSet(JNIEnv *env, jobject axContext, jobject component)
135 {
136 GET_CACCESSIBILITY_CLASS_RETURN(nil);
137 DECLARE_STATIC_METHOD_RETURN(jm_getAccessibleStateSet, sjc_CAccessibility, "getAccessibleStateSet",
138 "(Ljavax/accessibility/AccessibleContext;Ljava/awt/Component;)Ljavax/accessibility/AccessibleStateSet;", nil);
139 jobject o = (*env)->CallStaticObjectMethod(env, sjc_CAccessibility, jm_getAccessibleStateSet,
140 axContext, component);
141 CHECK_EXCEPTION();
142 return o;
143 }
144
145 BOOL containsAxState(JNIEnv *env, jobject axContext, jobject axState, jobject component)
146 {
147 GET_CACCESSIBILITY_CLASS_RETURN(NO);
148 DECLARE_STATIC_METHOD_RETURN(jm_contains, sjc_CAccessibility, "contains",
149 "(Ljavax/accessibility/AccessibleContext;Ljavax/accessibility/AccessibleState;Ljava/awt/Component;)Z", NO);
150 jboolean b = (*env)->CallStaticBooleanMethod(env, sjc_CAccessibility, jm_contains, axContext, axState, component);
151 CHECK_EXCEPTION();
152 return b;
153 }
154
155 BOOL isVertical(JNIEnv *env, jobject axContext, jobject component)
156 {
157 GET_ACCESSIBLESTATE_CLASS_RETURN(NO);
158 DECLARE_STATIC_FIELD_RETURN(jm_VERTICAL, sjc_AccessibleState, "VERTICAL", "Ljavax/accessibility/AccessibleState;", NO);
159 jobject axVertState = (*env)->GetStaticObjectField(env, sjc_AccessibleState, jm_VERTICAL);
160 CHECK_EXCEPTION_NULL_RETURN(axVertState, NO);
161 BOOL vertical = containsAxState(env, axContext, axVertState, component);
162 (*env)->DeleteLocalRef(env, axVertState);
163 return vertical;
164 }
165
166 BOOL isHorizontal(JNIEnv *env, jobject axContext, jobject component)
167 {
168 GET_ACCESSIBLESTATE_CLASS_RETURN(NO);
169 DECLARE_STATIC_FIELD_RETURN(jm_HORIZONTAL, sjc_AccessibleState, "HORIZONTAL", "Ljavax/accessibility/AccessibleState;", NO);
170 jobject axHorizState = (*env)->GetStaticObjectField(env, sjc_AccessibleState, jm_HORIZONTAL);
171 CHECK_EXCEPTION_NULL_RETURN(axHorizState, NO);
172 BOOL horizontal = containsAxState(env, axContext, axHorizState, component);
173 (*env)->DeleteLocalRef(env, axHorizState);
174 return horizontal;
175 }
176
177 BOOL isShowing(JNIEnv *env, jobject axContext, jobject component)
178 {
179 GET_ACCESSIBLESTATE_CLASS_RETURN(NO);
180 DECLARE_STATIC_FIELD_RETURN(jm_SHOWING, sjc_AccessibleState, "SHOWING", "Ljavax/accessibility/AccessibleState;", NO);
181 jobject axVisibleState = (*env)->GetStaticObjectField(env, sjc_AccessibleState, jm_SHOWING);
182 CHECK_EXCEPTION_NULL_RETURN(axVisibleState, NO);
183 BOOL showing = containsAxState(env, axContext, axVisibleState, component);
184 (*env)->DeleteLocalRef(env, axVisibleState);
185 return showing;
186 }
187
188 BOOL isSelectable(JNIEnv *env, jobject axContext, jobject component)
189 {
190 GET_ACCESSIBLESTATE_CLASS_RETURN(NO);
191 DECLARE_STATIC_FIELD_RETURN(jm_SELECTABLE,
192 sjc_AccessibleState,
193 "SELECTABLE",
194 "Ljavax/accessibility/AccessibleState;", NO );
195 jobject axSelectableState = (*env)->GetStaticObjectField(env, sjc_AccessibleState, jm_SELECTABLE);
196 CHECK_EXCEPTION_NULL_RETURN(axSelectableState, NO);
197 BOOL selectable = containsAxState(env, axContext, axSelectableState, component);
198 (*env)->DeleteLocalRef(env, axSelectableState);
199 return selectable;
200 }
201
202 NSPoint getAxComponentLocationOnScreen(JNIEnv *env, jobject axComponent, jobject component)
203 {
204 GET_CACCESSIBILITY_CLASS_RETURN(NSZeroPoint);
205 DECLARE_STATIC_METHOD_RETURN(jm_getLocationOnScreen, sjc_CAccessibility, "getLocationOnScreen",
206 "(Ljavax/accessibility/AccessibleComponent;Ljava/awt/Component;)Ljava/awt/Point;", NSZeroPoint);
207 DECLARE_CLASS_RETURN(sjc_Point, "java/awt/Point", NSZeroPoint);
208 DECLARE_FIELD_RETURN(sjf_X, sjc_Point, "x", "I", NSZeroPoint);
209 DECLARE_FIELD_RETURN(sjf_Y, sjc_Point, "y", "I", NSZeroPoint);
210 jobject jpoint = (*env)->CallStaticObjectMethod(env, sjc_CAccessibility, jm_getLocationOnScreen,
211 axComponent, component);
212 CHECK_EXCEPTION();
213 if (jpoint == NULL) return NSZeroPoint;
214 return NSMakePoint((*env)->GetIntField(env, jpoint, sjf_X), (*env)->GetIntField(env, jpoint, sjf_Y));
215 }
216
217 jint getAxTextCharCount(JNIEnv *env, jobject axText, jobject component)
218 {
219 GET_CACCESSIBILITY_CLASS_RETURN(0);
220 DECLARE_STATIC_METHOD_RETURN(jm_getCharCount, sjc_CAccessibility, "getCharCount",
221 "(Ljavax/accessibility/AccessibleText;Ljava/awt/Component;)I", 0);
222 int i = (*env)->CallStaticIntMethod(env, sjc_CAccessibility, jm_getCharCount, axText, component);
223 CHECK_EXCEPTION();
224 return i;
225 }
226
227 // The following JavaAccessibility methods are copied from the corresponding
228 // NSAccessibility methods in NSAccessibility.m.
229 //
230 // They implement a key-value-like coding scheme to transform messages like
231 // [self accessibilityAttributeValue:NSAccessibilityEnabledAttribute]
232 // into calls on to specific methods like
233 // [self accessibilityEnabledAttribute].
234
235 static NSString *AttributeWithoutAXPrefix(NSString *attribute)
236 {
237 return [attribute hasPrefix:@"AX"] ? [attribute substringFromIndex:2] : attribute;
238 }
239
240 static SEL JavaAccessibilityAttributeGetter(NSString *attribute)
241 {
242 return NSSelectorFromString([NSString stringWithFormat:@"accessibility%@Attribute", AttributeWithoutAXPrefix(attribute)]);
243 }
244
295 return;
296 }
297 #endif
298
299 [element performSelector:setter withObject:value];
300 }
301
302 static BOOL JavaAccessibilityIsSupportedAttribute(id element, NSString *attribute)
303 {
304 return [[element accessibilityAttributeNames] indexOfObject:attribute] != NSNotFound;
305 }
306
307 /*
308 * Class: sun_lwawt_macosx_CAccessibility
309 * Method: roleKey
310 * Signature: (Ljavax/accessibility/AccessibleRole;)Ljava/lang/String;
311 */
312 JNIEXPORT jstring JNICALL Java_sun_lwawt_macosx_CAccessibility_roleKey
313 (JNIEnv *env, jclass clz, jobject axRole)
314 {
315 DECLARE_CLASS_RETURN(sjc_AccessibleRole, "javax/accessibility/AccessibleRole", NULL);
316 DECLARE_FIELD_RETURN(sjf_key, sjc_AccessibleRole, "key", "Ljava/lang/String;", NULL);
317 return (*env)->GetObjectField(env, axRole, sjf_key);
318 }
319
320
321 // errors from NSAccessibilityErrors
322 void JavaAccessibilityRaiseSetAttributeToIllegalTypeException(const char *functionName, id element, NSString *attribute, id value)
323 {
324 NSString *reason = [NSString stringWithFormat:@"%s: Attempt set \"%@\" attribute to illegal type of value (%@:%@) for element: %@", functionName, attribute, [value class], value, element];
325 _JavaAccessibilityRaiseException(reason, kAXErrorIllegalArgument);
326 }
327
328 void JavaAccessibilityRaiseUnimplementedAttributeException(const char *functionName, id element, NSString *attribute)
329 {
330 NSString *reason = [NSString stringWithFormat:@"%s: \"%@\" attribute unimplemented by element: %@", functionName, attribute, element];
331 _JavaAccessibilityRaiseException(reason, kAXErrorFailure);
332 }
333
334 void JavaAccessibilityRaiseIllegalParameterTypeException(const char *functionName, id element, NSString *attribute, id parameter)
335 {
336 NSString *reason = [NSString stringWithFormat:@"%s: \"%@\" parameterized attribute passed illegal type of parameter (%@:%@) for element: %@", functionName, attribute, [parameter class], parameter, element];
337 _JavaAccessibilityRaiseException(reason, kAXErrorIllegalArgument);
|