< prev index next >

src/java.desktop/macosx/native/libawt_lwawt/awt/JavaComponentAccessibility.m

Print this page
rev 54094 : 8257853: Remove dependencies on JNF's JNI utility functions in AWT and 2D code
rev 54095 : 8259343: [macOS] Update JNI error handling in Cocoa code.
rev 54096 : 8259651: [macOS] Replace JNF_COCOA_ENTER/EXIT macros
rev 54097 : 8259869: [macOS] Remove desktop module dependencies on JNF Reference APIs
rev 54098 : 8260616: Removing remaining JNF dependencies in the java.desktop module
8259729: Missed JNFInstanceOf -> IsInstanceOf conversion
rev 54102 : 8261198: [macOS] Incorrect JNI parameters in number conversion in A11Y code
Reviewed-by: serb, psadhukhan
rev 54103 : 8263846: Bad JNI lookup getFocusOwner in accessibility code on Mac OS X
Reviewed-by: azvegint, prr

*** 33,72 **** #import "sun_lwawt_macosx_CAccessibility.h" #import <AppKit/AppKit.h> - #import <JavaNativeFoundation/JavaNativeFoundation.h> #import <JavaRuntimeSupport/JavaRuntimeSupport.h> #import <dlfcn.h> #import "JavaAccessibilityAction.h" #import "JavaAccessibilityUtilities.h" #import "JavaTextAccessibility.h" #import "ThreadUtilities.h" #import "AWTView.h" // these constants are duplicated in CAccessibility.java #define JAVA_AX_ALL_CHILDREN (-1) #define JAVA_AX_SELECTED_CHILDREN (-2) #define JAVA_AX_VISIBLE_CHILDREN (-3) // If the value is >=0, it's an index ! static JNF_STATIC_MEMBER_CACHE(jm_getChildrenAndRoles, sjc_CAccessibility, "getChildrenAndRoles", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;IZ)[Ljava/lang/Object;"); ! static JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleComponent, sjc_CAccessibility, "getAccessibleComponent", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljavax/accessibility/AccessibleComponent;"); ! static JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleValue, sjc_CAccessibility, "getAccessibleValue", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljavax/accessibility/AccessibleValue;"); ! static JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleName, sjc_CAccessibility, "getAccessibleName", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljava/lang/String;"); ! static JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleDescription, sjc_CAccessibility, "getAccessibleDescription", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljava/lang/String;"); ! static JNF_STATIC_MEMBER_CACHE(sjm_isFocusTraversable, sjc_CAccessibility, "isFocusTraversable", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Z"); ! static JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleIndexInParent, sjc_CAccessibility, "getAccessibleIndexInParent", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)I"); ! static JNF_CLASS_CACHE(sjc_CAccessible, "sun/lwawt/macosx/CAccessible"); - static JNF_MEMBER_CACHE(jf_ptr, sjc_CAccessible, "ptr", "J"); - static JNF_STATIC_MEMBER_CACHE(sjm_getCAccessible, sjc_CAccessible, "getCAccessible", "(Ljavax/accessibility/Accessible;)Lsun/lwawt/macosx/CAccessible;"); static jobject sAccessibilityClass = NULL; // sAttributeNamesForRoleCache holds the names of the attributes to which each java // AccessibleRole responds (see AccessibleRole.java). --- 33,91 ---- #import "sun_lwawt_macosx_CAccessibility.h" #import <AppKit/AppKit.h> #import <JavaRuntimeSupport/JavaRuntimeSupport.h> #import <dlfcn.h> #import "JavaAccessibilityAction.h" #import "JavaAccessibilityUtilities.h" #import "JavaTextAccessibility.h" #import "ThreadUtilities.h" + #import "JNIUtilities.h" #import "AWTView.h" // these constants are duplicated in CAccessibility.java #define JAVA_AX_ALL_CHILDREN (-1) #define JAVA_AX_SELECTED_CHILDREN (-2) #define JAVA_AX_VISIBLE_CHILDREN (-3) // If the value is >=0, it's an index ! // GET* macros defined in JavaAccessibilityUtilities.h, so they can be shared. ! static jclass sjc_CAccessibility = NULL; ! static jmethodID sjm_getAccessibleName = NULL; ! #define GET_ACCESSIBLENAME_METHOD_RETURN(ret) \ ! GET_CACCESSIBILITY_CLASS_RETURN(ret); \ ! GET_STATIC_METHOD_RETURN(sjm_getAccessibleName, sjc_CAccessibility, "getAccessibleName", \ ! "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljava/lang/String;", ret); ! ! static jmethodID jm_getChildrenAndRoles = NULL; ! #define GET_CHILDRENANDROLES_METHOD_RETURN(ret) \ ! GET_CACCESSIBILITY_CLASS_RETURN(ret); \ ! GET_STATIC_METHOD_RETURN(jm_getChildrenAndRoles, sjc_CAccessibility, "getChildrenAndRoles",\ ! "(Ljavax/accessibility/Accessible;Ljava/awt/Component;IZ)[Ljava/lang/Object;", ret); ! ! static jmethodID sjm_getAccessibleComponent = NULL; ! #define GET_ACCESSIBLECOMPONENT_STATIC_METHOD_RETURN(ret) \ ! GET_CACCESSIBILITY_CLASS_RETURN(ret); \ ! GET_STATIC_METHOD_RETURN(sjm_getAccessibleComponent, sjc_CAccessibility, "getAccessibleComponent", \ ! "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljavax/accessibility/AccessibleComponent;", ret); ! ! static jmethodID sjm_getAccessibleIndexInParent = NULL; ! #define GET_ACCESSIBLEINDEXINPARENT_STATIC_METHOD_RETURN(ret) \ ! GET_CACCESSIBILITY_CLASS_RETURN(ret); \ ! GET_STATIC_METHOD_RETURN(sjm_getAccessibleIndexInParent, sjc_CAccessibility, "getAccessibleIndexInParent", \ ! "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)I", ret); ! ! static jclass sjc_CAccessible = NULL; ! #define GET_CACCESSIBLE_CLASS_RETURN(ret) \ ! GET_CLASS_RETURN(sjc_CAccessible, "sun/lwawt/macosx/CAccessible", ret); static jobject sAccessibilityClass = NULL; // sAttributeNamesForRoleCache holds the names of the attributes to which each java // AccessibleRole responds (see AccessibleRole.java).
*** 254,312 **** if (sRoles == nil) { initializeRoles(); } if (sAccessibilityClass == NULL) { ! JNF_STATIC_MEMBER_CACHE(jm_getAccessibility, sjc_CAccessibility, "getAccessibility", "([Ljava/lang/String;)Lsun/lwawt/macosx/CAccessibility;"); #ifdef JAVA_AX_NO_IGNORES NSArray *ignoredKeys = [NSArray array]; #else NSArray *ignoredKeys = [sRoles allKeysForObject:JavaAccessibilityIgnore]; #endif jobjectArray result = NULL; jsize count = [ignoredKeys count]; ! JNIEnv *env = [ThreadUtilities getJNIEnv]; ! ! static JNF_CLASS_CACHE(jc_String, "java/lang/String"); ! result = JNFNewObjectArray(env, &jc_String, count); if (!result) { NSLog(@"In %s, can't create Java array of String objects", __FUNCTION__); return; } NSInteger i; for (i = 0; i < count; i++) { ! jstring jString = JNFNSToJavaString(env, [ignoredKeys objectAtIndex:i]); (*env)->SetObjectArrayElement(env, result, i, jString); (*env)->DeleteLocalRef(env, jString); } ! sAccessibilityClass = JNFCallStaticObjectMethod(env, jm_getAccessibility, result); // AWT_THREADING Safe (known object) } } + (void)postFocusChanged:(id)message { AWT_ASSERT_APPKIT_THREAD; NSAccessibilityPostNotification([NSApp accessibilityFocusedUIElement], NSAccessibilityFocusedUIElementChangedNotification); } + (jobject) getCAccessible:(jobject)jaccessible withEnv:(JNIEnv *)env { ! if (JNFIsInstanceOf(env, jaccessible, &sjc_CAccessible)) { return jaccessible; ! } else if (JNFIsInstanceOf(env, jaccessible, &sjc_Accessible)) { ! return JNFCallStaticObjectMethod(env, sjm_getCAccessible, jaccessible); } return NULL; } + (NSArray *)childrenOfParent:(JavaComponentAccessibility *)parent withEnv:(JNIEnv *)env withChildrenCode:(NSInteger)whichChildren allowIgnored:(BOOL)allowIgnored { if (parent->fAccessible == NULL) return nil; ! jobjectArray jchildrenAndRoles = (jobjectArray)JNFCallStaticObjectMethod(env, jm_getChildrenAndRoles, parent->fAccessible, parent->fComponent, whichChildren, allowIgnored); // AWT_THREADING Safe (AWTRunLoop) if (jchildrenAndRoles == NULL) return nil; jsize arrayLen = (*env)->GetArrayLength(env, jchildrenAndRoles); NSMutableArray *children = [NSMutableArray arrayWithCapacity:arrayLen/2]; //childrenAndRoles array contains two elements (child, role) for each child --- 273,343 ---- if (sRoles == nil) { initializeRoles(); } if (sAccessibilityClass == NULL) { ! JNIEnv *env = [ThreadUtilities getJNIEnv]; ! ! GET_CACCESSIBILITY_CLASS(); ! DECLARE_STATIC_METHOD(jm_getAccessibility, sjc_CAccessibility, "getAccessibility", "([Ljava/lang/String;)Lsun/lwawt/macosx/CAccessibility;"); #ifdef JAVA_AX_NO_IGNORES NSArray *ignoredKeys = [NSArray array]; #else NSArray *ignoredKeys = [sRoles allKeysForObject:JavaAccessibilityIgnore]; #endif jobjectArray result = NULL; jsize count = [ignoredKeys count]; ! DECLARE_CLASS(jc_String, "java/lang/String"); ! result = (*env)->NewObjectArray(env, count, jc_String, NULL); ! CHECK_EXCEPTION(); if (!result) { NSLog(@"In %s, can't create Java array of String objects", __FUNCTION__); return; } NSInteger i; for (i = 0; i < count; i++) { ! jstring jString = NSStringToJavaString(env, [ignoredKeys objectAtIndex:i]); (*env)->SetObjectArrayElement(env, result, i, jString); (*env)->DeleteLocalRef(env, jString); } ! sAccessibilityClass = (*env)->CallStaticObjectMethod(env, sjc_CAccessibility, jm_getAccessibility, result); // AWT_THREADING Safe (known object) ! CHECK_EXCEPTION(); } } + (void)postFocusChanged:(id)message { AWT_ASSERT_APPKIT_THREAD; NSAccessibilityPostNotification([NSApp accessibilityFocusedUIElement], NSAccessibilityFocusedUIElementChangedNotification); } + (jobject) getCAccessible:(jobject)jaccessible withEnv:(JNIEnv *)env { ! DECLARE_CLASS_RETURN(sjc_Accessible, "javax/accessibility/Accessible", NULL); ! GET_CACCESSIBLE_CLASS_RETURN(NULL); ! DECLARE_STATIC_METHOD_RETURN(sjm_getCAccessible, sjc_CAccessible, "getCAccessible", ! "(Ljavax/accessibility/Accessible;)Lsun/lwawt/macosx/CAccessible;", NULL); ! if ((*env)->IsInstanceOf(env, jaccessible, sjc_CAccessible)) { return jaccessible; ! } else if ((*env)->IsInstanceOf(env, jaccessible, sjc_Accessible)) { ! jobject o = (*env)->CallStaticObjectMethod(env, sjc_CAccessible, sjm_getCAccessible, jaccessible); ! CHECK_EXCEPTION(); ! return o; } return NULL; } + (NSArray *)childrenOfParent:(JavaComponentAccessibility *)parent withEnv:(JNIEnv *)env withChildrenCode:(NSInteger)whichChildren allowIgnored:(BOOL)allowIgnored { if (parent->fAccessible == NULL) return nil; ! GET_CHILDRENANDROLES_METHOD_RETURN(nil); ! jobjectArray jchildrenAndRoles = (jobjectArray)(*env)->CallStaticObjectMethod(env, sjc_CAccessibility, jm_getChildrenAndRoles, ! parent->fAccessible, parent->fComponent, whichChildren, allowIgnored); ! CHECK_EXCEPTION(); if (jchildrenAndRoles == NULL) return nil; jsize arrayLen = (*env)->GetArrayLength(env, jchildrenAndRoles); NSMutableArray *children = [NSMutableArray arrayWithCapacity:arrayLen/2]; //childrenAndRoles array contains two elements (child, role) for each child
*** 317,328 **** jobject /* Accessible */ jchild = (*env)->GetObjectArrayElement(env, jchildrenAndRoles, i); jobject /* String */ jchildJavaRole = (*env)->GetObjectArrayElement(env, jchildrenAndRoles, i+1); NSString *childJavaRole = nil; if (jchildJavaRole != NULL) { ! jobject jkey = JNFGetObjectField(env, jchildJavaRole, sjf_key); ! childJavaRole = JNFJavaToNSString(env, jkey); (*env)->DeleteLocalRef(env, jkey); } JavaComponentAccessibility *child = [self createWithParent:parent accessible:jchild role:childJavaRole index:childIndex withEnv:env withView:parent->fView]; --- 348,362 ---- jobject /* Accessible */ jchild = (*env)->GetObjectArrayElement(env, jchildrenAndRoles, i); jobject /* String */ jchildJavaRole = (*env)->GetObjectArrayElement(env, jchildrenAndRoles, i+1); NSString *childJavaRole = nil; if (jchildJavaRole != NULL) { ! DECLARE_CLASS_RETURN(sjc_AccessibleRole, "javax/accessibility/AccessibleRole", nil); ! DECLARE_FIELD_RETURN(sjf_key, sjc_AccessibleRole, "key", "Ljava/lang/String;", nil); ! jobject jkey = (*env)->GetObjectField(env, jchildJavaRole, sjf_key); ! CHECK_EXCEPTION(); ! childJavaRole = JavaStringToNSString(env, jkey); (*env)->DeleteLocalRef(env, jkey); } JavaComponentAccessibility *child = [self createWithParent:parent accessible:jchild role:childJavaRole index:childIndex withEnv:env withView:parent->fView];
*** 337,349 **** return children; } + (JavaComponentAccessibility *)createWithAccessible:(jobject)jaccessible withEnv:(JNIEnv *)env withView:(NSView *)view { JavaComponentAccessibility *ret = nil; jobject jcomponent = [(AWTView *)view awtComponent:env]; ! jint index = JNFCallStaticIntMethod(env, sjm_getAccessibleIndexInParent, jaccessible, jcomponent); if (index >= 0) { NSString *javaRole = getJavaRole(env, jaccessible, jcomponent); ret = [self createWithAccessible:jaccessible role:javaRole index:index withEnv:env withView:view]; } (*env)->DeleteLocalRef(env, jcomponent); --- 371,385 ---- return children; } + (JavaComponentAccessibility *)createWithAccessible:(jobject)jaccessible withEnv:(JNIEnv *)env withView:(NSView *)view { + GET_ACCESSIBLEINDEXINPARENT_STATIC_METHOD_RETURN(nil); JavaComponentAccessibility *ret = nil; jobject jcomponent = [(AWTView *)view awtComponent:env]; ! jint index = (*env)->CallStaticIntMethod(env, sjc_CAccessibility, sjm_getAccessibleIndexInParent, jaccessible, jcomponent); ! CHECK_EXCEPTION(); if (index >= 0) { NSString *javaRole = getJavaRole(env, jaccessible, jcomponent); ret = [self createWithAccessible:jaccessible role:javaRole index:index withEnv:env withView:view]; } (*env)->DeleteLocalRef(env, jcomponent);
*** 355,368 **** return [self createWithParent:nil accessible:jaccessible role:javaRole index:index withEnv:env withView:view]; } + (JavaComponentAccessibility *) createWithParent:(JavaComponentAccessibility *)parent accessible:(jobject)jaccessible role:(NSString *)javaRole index:(jint)index withEnv:(JNIEnv *)env withView:(NSView *)view { // try to fetch the jCAX from Java, and return autoreleased jobject jCAX = [JavaComponentAccessibility getCAccessible:jaccessible withEnv:env]; if (jCAX == NULL) return nil; ! JavaComponentAccessibility *value = (JavaComponentAccessibility *) jlong_to_ptr(JNFGetLongField(env, jCAX, jf_ptr)); if (value != nil) { (*env)->DeleteLocalRef(env, jCAX); return [[value retain] autorelease]; } --- 391,406 ---- return [self createWithParent:nil accessible:jaccessible role:javaRole index:index withEnv:env withView:view]; } + (JavaComponentAccessibility *) createWithParent:(JavaComponentAccessibility *)parent accessible:(jobject)jaccessible role:(NSString *)javaRole index:(jint)index withEnv:(JNIEnv *)env withView:(NSView *)view { + GET_CACCESSIBLE_CLASS_RETURN(NULL); + DECLARE_FIELD_RETURN(jf_ptr, sjc_CAccessible, "ptr", "J", NULL); // try to fetch the jCAX from Java, and return autoreleased jobject jCAX = [JavaComponentAccessibility getCAccessible:jaccessible withEnv:env]; if (jCAX == NULL) return nil; ! JavaComponentAccessibility *value = (JavaComponentAccessibility *) jlong_to_ptr((*env)->GetLongField(env, jCAX, jf_ptr)); if (value != nil) { (*env)->DeleteLocalRef(env, jCAX); return [[value retain] autorelease]; }
*** 392,411 **** [newChild postMenuOpened]; } // must hard retain pointer poked into Java object [newChild retain]; ! JNFSetLongField(env, jCAX, jf_ptr, ptr_to_jlong(newChild)); (*env)->DeleteLocalRef(env, jCAX); // return autoreleased instance return [newChild autorelease]; } - (NSArray *)initializeAttributeNamesWithEnv:(JNIEnv *)env { ! static JNF_STATIC_MEMBER_CACHE(jm_getInitialAttributeStates, sjc_CAccessibility, "getInitialAttributeStates", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)[Z"); NSMutableArray *attributeNames = [NSMutableArray arrayWithCapacity:20]; [attributeNames retain]; // all elements respond to parent, role, role description, window, topLevelUIElement, help --- 430,451 ---- [newChild postMenuOpened]; } // must hard retain pointer poked into Java object [newChild retain]; ! (*env)->SetLongField(env, jCAX, jf_ptr, ptr_to_jlong(newChild)); (*env)->DeleteLocalRef(env, jCAX); // return autoreleased instance return [newChild autorelease]; } - (NSArray *)initializeAttributeNamesWithEnv:(JNIEnv *)env { ! GET_CACCESSIBILITY_CLASS_RETURN(nil); ! DECLARE_STATIC_METHOD_RETURN(jm_getInitialAttributeStates, sjc_CAccessibility, "getInitialAttributeStates", ! "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)[Z", nil); NSMutableArray *attributeNames = [NSMutableArray arrayWithCapacity:20]; [attributeNames retain]; // all elements respond to parent, role, role description, window, topLevelUIElement, help
*** 426,436 **** [attributeNames addObject:NSAccessibilitySubroleAttribute]; } // Get all the other accessibility attributes states we need in one swell foop. // javaRole isn't pulled in because we need protected access to AccessibleRole.key ! jbooleanArray attributeStates = (jbooleanArray)JNFCallStaticObjectMethod(env, jm_getInitialAttributeStates, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop) if (attributeStates == NULL) return nil; jboolean *attributeStatesArray = (*env)->GetBooleanArrayElements(env, attributeStates, 0); if (attributeStatesArray == NULL) { // Note: Java will not be on the stack here so a java exception can't happen and no need to call ExceptionCheck. NSLog(@"%s failed calling GetBooleanArrayElements", __FUNCTION__); --- 466,478 ---- [attributeNames addObject:NSAccessibilitySubroleAttribute]; } // Get all the other accessibility attributes states we need in one swell foop. // javaRole isn't pulled in because we need protected access to AccessibleRole.key ! jbooleanArray attributeStates = (jbooleanArray)(*env)->CallStaticObjectMethod(env, sjc_CAccessibility, ! jm_getInitialAttributeStates, fAccessible, fComponent); ! CHECK_EXCEPTION(); if (attributeStates == NULL) return nil; jboolean *attributeStatesArray = (*env)->GetBooleanArrayElements(env, attributeStates, 0); if (attributeStatesArray == NULL) { // Note: Java will not be on the stack here so a java exception can't happen and no need to call ExceptionCheck. NSLog(@"%s failed calling GetBooleanArrayElements", __FUNCTION__);
*** 515,529 **** return fActions; } - (void)getActionsWithEnv:(JNIEnv *)env { ! static JNF_STATIC_MEMBER_CACHE(jm_getAccessibleAction, sjc_CAccessibility, "getAccessibleAction", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljavax/accessibility/AccessibleAction;"); // On MacOSX, text doesn't have actions, in java it does. // cmcnote: NOT TRUE - Editable text has AXShowMenu. Textfields have AXConfirm. Static text has no actions. ! jobject axAction = JNFCallStaticObjectMethod(env, jm_getAccessibleAction, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop) if (axAction != NULL) { //+++gdb NOTE: In MacOSX, there is just a single Action, not multiple. In java, // the first one seems to be the most basic, so this will be used. // cmcnote: NOT TRUE - Sometimes there are multiple actions, eg sliders have AXDecrement AND AXIncrement (radr://3893192) JavaAxAction *action = [[JavaAxAction alloc] initWithEnv:env withAccessibleAction:axAction withIndex:0 withComponent:fComponent]; --- 557,574 ---- return fActions; } - (void)getActionsWithEnv:(JNIEnv *)env { ! GET_CACCESSIBILITY_CLASS(); ! DECLARE_STATIC_METHOD(jm_getAccessibleAction, sjc_CAccessibility, "getAccessibleAction", ! "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljavax/accessibility/AccessibleAction;"); // On MacOSX, text doesn't have actions, in java it does. // cmcnote: NOT TRUE - Editable text has AXShowMenu. Textfields have AXConfirm. Static text has no actions. ! jobject axAction = (*env)->CallStaticObjectMethod(env, sjc_CAccessibility, jm_getAccessibleAction, fAccessible, fComponent); ! CHECK_EXCEPTION(); if (axAction != NULL) { //+++gdb NOTE: In MacOSX, there is just a single Action, not multiple. In java, // the first one seems to be the most basic, so this will be used. // cmcnote: NOT TRUE - Sometimes there are multiple actions, eg sliders have AXDecrement AND AXIncrement (radr://3893192) JavaAxAction *action = [[JavaAxAction alloc] initWithEnv:env withAccessibleAction:axAction withIndex:0 withComponent:fComponent];
*** 538,563 **** return getAxContext(env, fAccessible, fComponent); } - (id)parent { - static JNF_CLASS_CACHE(sjc_Window, "java/awt/Window"); - static JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleParent, sjc_CAccessibility, "getAccessibleParent", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljavax/accessibility/Accessible;"); - static JNF_STATIC_MEMBER_CACHE(sjm_getSwingAccessible, sjc_CAccessible, "getSwingAccessible", "(Ljavax/accessibility/Accessible;)Ljavax/accessibility/Accessible;"); - if(fParent == nil) { JNIEnv* env = [ThreadUtilities getJNIEnv]; ! jobject jparent = JNFCallStaticObjectMethod(env, sjm_getAccessibleParent, fAccessible, fComponent); if (jparent == NULL) { fParent = fView; } else { AWTView *view = fView; ! jobject jax = JNFCallStaticObjectMethod(env, sjm_getSwingAccessible, fAccessible); ! if (JNFIsInstanceOf(env, jax, &sjc_Window)) { // In this case jparent is an owner toplevel and we should retrieve its own view view = [AWTView awtView:env ofAccessible:jparent]; } if (view != nil) { fParent = [JavaComponentAccessibility createWithAccessible:jparent withEnv:env withView:view]; --- 583,613 ---- return getAxContext(env, fAccessible, fComponent); } - (id)parent { if(fParent == nil) { JNIEnv* env = [ThreadUtilities getJNIEnv]; + GET_CACCESSIBILITY_CLASS_RETURN(nil); + DECLARE_STATIC_METHOD_RETURN(sjm_getAccessibleParent, sjc_CAccessibility, "getAccessibleParent", + "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljavax/accessibility/Accessible;", nil); + GET_CACCESSIBLE_CLASS_RETURN(nil); + DECLARE_STATIC_METHOD_RETURN(sjm_getSwingAccessible, sjc_CAccessible, "getSwingAccessible", + "(Ljavax/accessibility/Accessible;)Ljavax/accessibility/Accessible;", nil); + DECLARE_CLASS_RETURN(sjc_Window, "java/awt/Window", nil); ! jobject jparent = (*env)->CallStaticObjectMethod(env, sjc_CAccessibility, sjm_getAccessibleParent, fAccessible, fComponent); ! CHECK_EXCEPTION(); if (jparent == NULL) { fParent = fView; } else { AWTView *view = fView; ! jobject jax = (*env)->CallStaticObjectMethod(env, sjc_CAccessible, sjm_getSwingAccessible, fAccessible); ! CHECK_EXCEPTION(); ! if ((*env)->IsInstanceOf(env, jax, sjc_Window)) { // In this case jparent is an owner toplevel and we should retrieve its own view view = [AWTView awtView:env ofAccessible:jparent]; } if (view != nil) { fParent = [JavaComponentAccessibility createWithAccessible:jparent withEnv:env withView:view];
*** 757,771 **** // only ones that override the default implementation in NSAccessibility if (![[self accessibilityRoleAttribute] isEqualToString:NSAccessibilityListRole]) { return [super accessibilityIndexOfChild:child]; } jint returnValue = ! JNFCallStaticIntMethod( [ThreadUtilities getJNIEnv], sjm_getAccessibleIndexInParent, ((JavaComponentAccessibility *)child)->fAccessible, ((JavaComponentAccessibility *)child)->fComponent ); return (returnValue == -1) ? NSNotFound : returnValue; } // Without this optimization accessibilityChildrenAttribute is called in order to get the entire array of children. - (NSArray *)accessibilityArrayAttributeValues:(NSString *)attribute index:(NSUInteger)index maxCount:(NSUInteger)maxCount { --- 807,825 ---- // only ones that override the default implementation in NSAccessibility if (![[self accessibilityRoleAttribute] isEqualToString:NSAccessibilityListRole]) { return [super accessibilityIndexOfChild:child]; } + JNIEnv *env = [ThreadUtilities getJNIEnv]; + GET_ACCESSIBLEINDEXINPARENT_STATIC_METHOD_RETURN(0); jint returnValue = ! (*env)->CallStaticIntMethod( env, ! sjc_CAccessibility, sjm_getAccessibleIndexInParent, ((JavaComponentAccessibility *)child)->fAccessible, ((JavaComponentAccessibility *)child)->fComponent ); + CHECK_EXCEPTION(); return (returnValue == -1) ? NSNotFound : returnValue; } // Without this optimization accessibilityChildrenAttribute is called in order to get the entire array of children. - (NSArray *)accessibilityArrayAttributeValues:(NSString *)attribute index:(NSUInteger)index maxCount:(NSUInteger)maxCount {
*** 780,793 **** } // Flag indicating enabled state of element (NSNumber) - (NSNumber *)accessibilityEnabledAttribute { - static JNF_STATIC_MEMBER_CACHE(jm_isEnabled, sjc_CAccessibility, "isEnabled", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Z"); - JNIEnv* env = [ThreadUtilities getJNIEnv]; ! NSNumber *value = [NSNumber numberWithBool:JNFCallStaticBooleanMethod(env, jm_isEnabled, fAccessible, fComponent)]; // AWT_THREADING Safe (AWTRunLoop) if (value == nil) { NSLog(@"WARNING: %s called on component that has no accessible component: %@", __FUNCTION__, self); } return value; } --- 834,849 ---- } // Flag indicating enabled state of element (NSNumber) - (NSNumber *)accessibilityEnabledAttribute { JNIEnv* env = [ThreadUtilities getJNIEnv]; ! GET_CACCESSIBILITY_CLASS_RETURN(nil); ! DECLARE_STATIC_METHOD_RETURN(jm_isEnabled, sjc_CAccessibility, "isEnabled", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Z", nil); ! ! NSNumber *value = [NSNumber numberWithBool:(*env)->CallStaticBooleanMethod(env, sjc_CAccessibility, jm_isEnabled, fAccessible, fComponent)]; ! CHECK_EXCEPTION(); if (value == nil) { NSLog(@"WARNING: %s called on component that has no accessible component: %@", __FUNCTION__, self); } return value; }
*** 807,848 **** } - (BOOL)accessibilityIsFocusedAttributeSettable { JNIEnv* env = [ThreadUtilities getJNIEnv]; // According to javadoc, a component that is focusable will return true from isFocusTraversable, // as well as having AccessibleState.FOCUSABLE in its AccessibleStateSet. // We use the former heuristic; if the component focus-traversable, add a focused attribute // See also initializeAttributeNamesWithEnv: ! if (JNFCallStaticBooleanMethod(env, sjm_isFocusTraversable, fAccessible, fComponent)) { // AWT_THREADING Safe (AWTRunLoop) return YES; } return NO; } - (void)accessibilitySetFocusedAttribute:(id)value { ! static JNF_STATIC_MEMBER_CACHE(jm_requestFocus, sjc_CAccessibility, "requestFocus", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)V"); if ([(NSNumber*)value boolValue]) { ! JNIEnv* env = [ThreadUtilities getJNIEnv]; ! JNFCallStaticVoidMethod(env, jm_requestFocus, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop) } } // Instance description, such as a help tag string (NSString) - (NSString *)accessibilityHelpAttribute { JNIEnv* env = [ThreadUtilities getJNIEnv]; ! jobject val = JNFCallStaticObjectMethod(env, sjm_getAccessibleDescription, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop) if (val == NULL) { return nil; } ! NSString* str = JNFJavaToNSString(env, val); (*env)->DeleteLocalRef(env, val); return str; } - (BOOL)accessibilityIsHelpAttributeSettable --- 863,916 ---- } - (BOOL)accessibilityIsFocusedAttributeSettable { JNIEnv* env = [ThreadUtilities getJNIEnv]; + GET_CACCESSIBILITY_CLASS_RETURN(NO); + DECLARE_STATIC_METHOD_RETURN(sjm_isFocusTraversable, sjc_CAccessibility, "isFocusTraversable", + "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Z", NO); // According to javadoc, a component that is focusable will return true from isFocusTraversable, // as well as having AccessibleState.FOCUSABLE in its AccessibleStateSet. // We use the former heuristic; if the component focus-traversable, add a focused attribute // See also initializeAttributeNamesWithEnv: ! if ((*env)->CallStaticBooleanMethod(env, sjc_CAccessibility, sjm_isFocusTraversable, fAccessible, fComponent)) { return YES; } + CHECK_EXCEPTION(); return NO; } - (void)accessibilitySetFocusedAttribute:(id)value { ! JNIEnv* env = [ThreadUtilities getJNIEnv]; ! ! GET_CACCESSIBILITY_CLASS(); ! DECLARE_STATIC_METHOD(jm_requestFocus, sjc_CAccessibility, "requestFocus", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)V"); if ([(NSNumber*)value boolValue]) { ! (*env)->CallStaticVoidMethod(env, sjc_CAccessibility, jm_requestFocus, fAccessible, fComponent); ! CHECK_EXCEPTION(); } } // Instance description, such as a help tag string (NSString) - (NSString *)accessibilityHelpAttribute { JNIEnv* env = [ThreadUtilities getJNIEnv]; ! GET_CACCESSIBILITY_CLASS_RETURN(nil); ! DECLARE_STATIC_METHOD_RETURN(sjm_getAccessibleDescription, sjc_CAccessibility, "getAccessibleDescription", ! "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljava/lang/String;", nil); ! jobject val = (*env)->CallStaticObjectMethod(env, sjc_CAccessibility, ! sjm_getAccessibleDescription, fAccessible, fComponent); ! CHECK_EXCEPTION(); if (val == NULL) { return nil; } ! NSString* str = JavaStringToNSString(env, val); (*env)->DeleteLocalRef(env, val); return str; } - (BOOL)accessibilityIsHelpAttributeSettable
*** 860,881 **** - (BOOL)accessibilityIsIndexAttributeSettable { return NO; } // Element's maximum value (id) - (id)accessibilityMaxValueAttribute { - static JNF_STATIC_MEMBER_CACHE(jm_getMaximumAccessibleValue, sjc_CAccessibility, "getMaximumAccessibleValue", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljava/lang/Number;"); - JNIEnv* env = [ThreadUtilities getJNIEnv]; ! jobject axValue = JNFCallStaticObjectMethod(env, jm_getMaximumAccessibleValue, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop) if (axValue == NULL) { return [NSNumber numberWithInt:0]; } ! NSNumber* num = JNFJavaToNSNumber(env, axValue); (*env)->DeleteLocalRef(env, axValue); return num; } - (BOOL)accessibilityIsMaxValueAttributeSettable --- 928,977 ---- - (BOOL)accessibilityIsIndexAttributeSettable { return NO; } + /* + * The java/lang/Number concrete class could be for any of the Java primitive + * numerical types or some other subclass. + * All existing A11Y code uses Integer so that is what we look for first + * But all must be able to return a double and NSNumber accepts a double, + * so that's the fall back. + */ + static NSNumber* JavaNumberToNSNumber(JNIEnv *env, jobject jnumber) { + if (jnumber == NULL) { + return nil; + } + DECLARE_CLASS_RETURN(jnumber_Class, "java/lang/Number", nil); + DECLARE_CLASS_RETURN(jinteger_Class, "java/lang/Integer", nil); + DECLARE_METHOD_RETURN(jm_intValue, jnumber_Class, "intValue", "()I", nil); + DECLARE_METHOD_RETURN(jm_doubleValue, jnumber_Class, "doubleValue", "()D", nil); + if ((*env)->IsInstanceOf(env, jnumber, jinteger_Class)) { + jint i = (*env)->CallIntMethod(env, jnumber, jm_intValue); + CHECK_EXCEPTION(); + return [NSNumber numberWithInteger:i]; + } else { + jdouble d = (*env)->CallDoubleMethod(env, jnumber, jm_doubleValue); + CHECK_EXCEPTION(); + return [NSNumber numberWithDouble:d]; + } + } + // Element's maximum value (id) - (id)accessibilityMaxValueAttribute { JNIEnv* env = [ThreadUtilities getJNIEnv]; + GET_CACCESSIBILITY_CLASS_RETURN(nil); + DECLARE_STATIC_METHOD_RETURN(jm_getMaximumAccessibleValue, sjc_CAccessibility, "getMaximumAccessibleValue", + "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljava/lang/Number;", nil); ! jobject axValue = (*env)->CallStaticObjectMethod(env, sjc_CAccessibility, jm_getMaximumAccessibleValue, fAccessible, fComponent); ! CHECK_EXCEPTION(); if (axValue == NULL) { return [NSNumber numberWithInt:0]; } ! NSNumber* num = JavaNumberToNSNumber(env, axValue); (*env)->DeleteLocalRef(env, axValue); return num; } - (BOOL)accessibilityIsMaxValueAttributeSettable
*** 884,902 **** } // Element's minimum value (id) - (id)accessibilityMinValueAttribute { - static JNF_STATIC_MEMBER_CACHE(jm_getMinimumAccessibleValue, sjc_CAccessibility, "getMinimumAccessibleValue", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljava/lang/Number;"); - JNIEnv* env = [ThreadUtilities getJNIEnv]; ! jobject axValue = JNFCallStaticObjectMethod(env, jm_getMinimumAccessibleValue, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop) if (axValue == NULL) { return [NSNumber numberWithInt:0]; } ! NSNumber* num = JNFJavaToNSNumber(env, axValue); (*env)->DeleteLocalRef(env, axValue); return num; } - (BOOL)accessibilityIsMinValueAttributeSettable --- 980,1000 ---- } // Element's minimum value (id) - (id)accessibilityMinValueAttribute { JNIEnv* env = [ThreadUtilities getJNIEnv]; + GET_CACCESSIBILITY_CLASS_RETURN(nil); + DECLARE_STATIC_METHOD_RETURN(jm_getMinimumAccessibleValue, sjc_CAccessibility, "getMinimumAccessibleValue", + "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljava/lang/Number;", nil); ! jobject axValue = (*env)->CallStaticObjectMethod(env, sjc_CAccessibility, jm_getMinimumAccessibleValue, fAccessible, fComponent); ! CHECK_EXCEPTION(); if (axValue == NULL) { return [NSNumber numberWithInt:0]; } ! NSNumber* num = JavaNumberToNSNumber(env, axValue); (*env)->DeleteLocalRef(env, axValue); return num; } - (BOOL)accessibilityIsMinValueAttributeSettable
*** 942,952 **** // Screen position of element's lower-left corner in lower-left relative screen coordinates (NSValue) - (NSValue *)accessibilityPositionAttribute { JNIEnv* env = [ThreadUtilities getJNIEnv]; ! jobject axComponent = JNFCallStaticObjectMethod(env, sjm_getAccessibleComponent, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop) // NSAccessibility wants the bottom left point of the object in // bottom left based screen coords // Get the java screen coords, and make a NSPoint of the bottom left of the AxComponent. --- 1040,1053 ---- // Screen position of element's lower-left corner in lower-left relative screen coordinates (NSValue) - (NSValue *)accessibilityPositionAttribute { JNIEnv* env = [ThreadUtilities getJNIEnv]; ! GET_ACCESSIBLECOMPONENT_STATIC_METHOD_RETURN(nil); ! jobject axComponent = (*env)->CallStaticObjectMethod(env, sjc_CAccessibility, sjm_getAccessibleComponent, ! fAccessible, fComponent); ! CHECK_EXCEPTION(); // NSAccessibility wants the bottom left point of the object in // bottom left based screen coords // Get the java screen coords, and make a NSPoint of the bottom left of the AxComponent.
*** 1003,1019 **** // first ask AppKit for its accessible role description for a given AXRole NSString *value = NSAccessibilityRoleDescription([self accessibilityRoleAttribute], nil); if (value == nil) { // query java if necessary - static JNF_STATIC_MEMBER_CACHE(jm_getAccessibleRoleDisplayString, sjc_CAccessibility, "getAccessibleRoleDisplayString", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljava/lang/String;"); - JNIEnv* env = [ThreadUtilities getJNIEnv]; ! jobject axRole = JNFCallStaticObjectMethod(env, jm_getAccessibleRoleDisplayString, fAccessible, fComponent); if (axRole != NULL) { ! value = JNFJavaToNSString(env, axRole); (*env)->DeleteLocalRef(env, axRole); } else { value = @"unknown"; } } --- 1104,1123 ---- // first ask AppKit for its accessible role description for a given AXRole NSString *value = NSAccessibilityRoleDescription([self accessibilityRoleAttribute], nil); if (value == nil) { // query java if necessary JNIEnv* env = [ThreadUtilities getJNIEnv]; + GET_CACCESSIBILITY_CLASS_RETURN(nil); + DECLARE_STATIC_METHOD_RETURN(jm_getAccessibleRoleDisplayString, sjc_CAccessibility, "getAccessibleRoleDisplayString", + "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljava/lang/String;", nil); ! ! jobject axRole = (*env)->CallStaticObjectMethod(env, jm_getAccessibleRoleDisplayString, fAccessible, fComponent); ! CHECK_EXCEPTION(); if (axRole != NULL) { ! value = JavaStringToNSString(env, axRole); (*env)->DeleteLocalRef(env, axRole); } else { value = @"unknown"; } }
*** 1057,1081 **** } } - (void)accessibilitySetSelectedAttribute:(id)value { ! static JNF_STATIC_MEMBER_CACHE( jm_requestSelection, sjc_CAccessibility, "requestSelection", ! "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)V" ); if ([(NSNumber*)value boolValue]) { ! JNIEnv* env = [ThreadUtilities getJNIEnv]; ! JNFCallStaticVoidMethod(env, jm_requestSelection, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop) } } // Element size (NSValue) - (NSValue *)accessibilitySizeAttribute { JNIEnv* env = [ThreadUtilities getJNIEnv]; ! jobject axComponent = JNFCallStaticObjectMethod(env, sjm_getAccessibleComponent, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop) NSValue* size = [NSValue valueWithSize:getAxComponentSize(env, axComponent, fComponent)]; (*env)->DeleteLocalRef(env, axComponent); return size; } --- 1161,1190 ---- } } - (void)accessibilitySetSelectedAttribute:(id)value { ! JNIEnv* env = [ThreadUtilities getJNIEnv]; ! GET_CACCESSIBILITY_CLASS(); ! DECLARE_STATIC_METHOD(jm_requestSelection, sjc_CAccessibility, "requestSelection", ! "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)V"); if ([(NSNumber*)value boolValue]) { ! (*env)->CallStaticVoidMethod(env, sjc_CAccessibility, jm_requestSelection, fAccessible, fComponent); ! CHECK_EXCEPTION(); } } // Element size (NSValue) - (NSValue *)accessibilitySizeAttribute { JNIEnv* env = [ThreadUtilities getJNIEnv]; ! GET_ACCESSIBLECOMPONENT_STATIC_METHOD_RETURN(nil); ! jobject axComponent = (*env)->CallStaticObjectMethod(env, sjc_CAccessibility, ! sjm_getAccessibleComponent, fAccessible, fComponent); ! CHECK_EXCEPTION(); NSValue* size = [NSValue valueWithSize:getAxComponentSize(env, axComponent, fComponent)]; (*env)->DeleteLocalRef(env, axComponent); return size; }
*** 1131,1145 **** return @""; } JNIEnv* env = [ThreadUtilities getJNIEnv]; ! jobject val = JNFCallStaticObjectMethod(env, sjm_getAccessibleName, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop) if (val == NULL) { return nil; } ! NSString* str = JNFJavaToNSString(env, val); (*env)->DeleteLocalRef(env, val); return str; } - (BOOL)accessibilityIsTitleAttributeSettable --- 1240,1256 ---- return @""; } JNIEnv* env = [ThreadUtilities getJNIEnv]; ! GET_ACCESSIBLENAME_METHOD_RETURN(nil); ! jobject val = (*env)->CallStaticObjectMethod(env, sjc_CAccessibility, sjm_getAccessibleName, fAccessible, fComponent); ! CHECK_EXCEPTION(); if (val == NULL) { return nil; } ! NSString* str = JavaStringToNSString(env, val); (*env)->DeleteLocalRef(env, val); return str; } - (BOOL)accessibilityIsTitleAttributeSettable
*** 1161,1172 **** // note that the appKit meaning of "accessibilityValue" is different from the java // meaning of "accessibleValue", which is specific to numerical values // (https://docs.oracle.com/javase/8/docs/api/javax/accessibility/AccessibleValue.html#setCurrentAccessibleValue-java.lang.Number-) - (id)accessibilityValueAttribute { - static JNF_STATIC_MEMBER_CACHE(jm_getCurrentAccessibleValue, sjc_CAccessibility, "getCurrentAccessibleValue", "(Ljavax/accessibility/AccessibleValue;Ljava/awt/Component;)Ljava/lang/Number;"); - JNIEnv* env = [ThreadUtilities getJNIEnv]; // Need to handle popupmenus differently. // // At least for now don't handle combo box menus. --- 1272,1281 ----
*** 1187,1205 **** NSArray *selectedChildrenOfMenu = [self accessibilitySelectedChildrenAttribute]; JavaComponentAccessibility *selectedMenuItem = [selectedChildrenOfMenu objectAtIndex:0]; if (selectedMenuItem != nil) { jobject itemValue = ! JNFCallStaticObjectMethod( env, sjm_getAccessibleName, selectedMenuItem->fAccessible, ! selectedMenuItem->fComponent ); // AWT_THREADING Safe (AWTRunLoop) if (itemValue == NULL) { return nil; } ! NSString* itemString = JNFJavaToNSString(env, itemValue); (*env)->DeleteLocalRef(env, itemValue); return itemString; } else { return nil; } --- 1296,1317 ---- NSArray *selectedChildrenOfMenu = [self accessibilitySelectedChildrenAttribute]; JavaComponentAccessibility *selectedMenuItem = [selectedChildrenOfMenu objectAtIndex:0]; if (selectedMenuItem != nil) { + GET_CACCESSIBILITY_CLASS_RETURN(nil); + GET_ACCESSIBLENAME_METHOD_RETURN(nil); jobject itemValue = ! (*env)->CallStaticObjectMethod( env, sjm_getAccessibleName, selectedMenuItem->fAccessible, ! selectedMenuItem->fComponent ); ! CHECK_EXCEPTION(); if (itemValue == NULL) { return nil; } ! NSString* itemString = JavaStringToNSString(env, itemValue); (*env)->DeleteLocalRef(env, itemValue); return itemString; } else { return nil; }
*** 1209,1223 **** // ask Java for the component's accessibleValue. In java, the "accessibleValue" just means a numerical value // a text value is taken care of in JavaTextAccessibility // cmcnote should coalesce these calls into one java call NSNumber *num = nil; ! jobject axValue = JNFCallStaticObjectMethod(env, sjm_getAccessibleValue, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop) if (axValue != NULL) { ! jobject str = JNFCallStaticObjectMethod(env, jm_getCurrentAccessibleValue, axValue, fComponent); if (str != NULL) { ! num = JNFJavaToNSNumber(env, str); // AWT_THREADING Safe (AWTRunLoop) (*env)->DeleteLocalRef(env, str); } (*env)->DeleteLocalRef(env, axValue); } if (num == nil) { --- 1321,1342 ---- // ask Java for the component's accessibleValue. In java, the "accessibleValue" just means a numerical value // a text value is taken care of in JavaTextAccessibility // cmcnote should coalesce these calls into one java call NSNumber *num = nil; ! GET_CACCESSIBILITY_CLASS_RETURN(nil); ! DECLARE_STATIC_METHOD_RETURN(sjm_getAccessibleValue, sjc_CAccessibility, "getAccessibleValue", ! "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljavax/accessibility/AccessibleValue;", nil); ! jobject axValue = (*env)->CallStaticObjectMethod(env, sjc_CAccessibility, sjm_getAccessibleValue, fAccessible, fComponent); ! CHECK_EXCEPTION(); if (axValue != NULL) { ! DECLARE_STATIC_METHOD_RETURN(jm_getCurrentAccessibleValue, sjc_CAccessibility, "getCurrentAccessibleValue", ! "(Ljavax/accessibility/AccessibleValue;Ljava/awt/Component;)Ljava/lang/Number;", nil); ! jobject str = (*env)->CallStaticObjectMethod(env, sjc_CAccessibility, jm_getCurrentAccessibleValue, axValue, fComponent); ! CHECK_EXCEPTION(); if (str != NULL) { ! num = JavaNumberToNSNumber(env, str); (*env)->DeleteLocalRef(env, str); } (*env)->DeleteLocalRef(env, axValue); } if (num == nil) {
*** 1309,1329 **** #endif /* JAVA_AX_NO_IGNORES */ } - (id)accessibilityHitTest:(NSPoint)point withEnv:(JNIEnv *)env { ! static JNF_CLASS_CACHE(jc_Container, "java/awt/Container"); ! static JNF_STATIC_MEMBER_CACHE(jm_accessibilityHitTest, sjc_CAccessibility, "accessibilityHitTest", "(Ljava/awt/Container;FF)Ljavax/accessibility/Accessible;"); // Make it into java screen coords point.y = [[[[self view] window] screen] frame].size.height - point.y; jobject jparent = fComponent; id value = nil; ! if (JNFIsInstanceOf(env, jparent, &jc_Container)) { ! jobject jaccessible = JNFCallStaticObjectMethod(env, jm_accessibilityHitTest, jparent, (jfloat)point.x, (jfloat)point.y); // AWT_THREADING Safe (AWTRunLoop) if (jaccessible != NULL) { value = [JavaComponentAccessibility createWithAccessible:jaccessible withEnv:env withView:fView]; (*env)->DeleteLocalRef(env, jaccessible); } } --- 1428,1451 ---- #endif /* JAVA_AX_NO_IGNORES */ } - (id)accessibilityHitTest:(NSPoint)point withEnv:(JNIEnv *)env { ! DECLARE_CLASS_RETURN(jc_Container, "java/awt/Container", nil); ! DECLARE_STATIC_METHOD_RETURN(jm_accessibilityHitTest, sjc_CAccessibility, "accessibilityHitTest", ! "(Ljava/awt/Container;FF)Ljavax/accessibility/Accessible;", nil); // Make it into java screen coords point.y = [[[[self view] window] screen] frame].size.height - point.y; jobject jparent = fComponent; id value = nil; ! if ((*env)->IsInstanceOf(env, jparent, jc_Container)) { ! jobject jaccessible = (*env)->CallStaticObjectMethod(env, sjc_CAccessibility, jm_accessibilityHitTest, ! jparent, (jfloat)point.x, (jfloat)point.y); ! CHECK_EXCEPTION(); if (jaccessible != NULL) { value = [JavaComponentAccessibility createWithAccessible:jaccessible withEnv:env withView:fView]; (*env)->DeleteLocalRef(env, jaccessible); } }
*** 1342,1364 **** return value; } - (id)accessibilityFocusedUIElement { - static JNF_STATIC_MEMBER_CACHE(jm_getFocusOwner, sjc_CAccessibility, "getFocusOwner", "(Ljava/awt/Component;)Ljavax/accessibility/Accessible;"); - JNIEnv *env = [ThreadUtilities getJNIEnv]; id value = nil; NSWindow* hostWindow = [[self->fView window] retain]; ! jobject focused = JNFCallStaticObjectMethod(env, jm_getFocusOwner, fComponent); // AWT_THREADING Safe (AWTRunLoop) [hostWindow release]; if (focused != NULL) { ! if (JNFIsInstanceOf(env, focused, &sjc_Accessible)) { value = [JavaComponentAccessibility createWithAccessible:focused withEnv:env withView:fView]; } (*env)->DeleteLocalRef(env, focused); } if (value == nil) { value = self; --- 1464,1490 ---- return value; } - (id)accessibilityFocusedUIElement { JNIEnv *env = [ThreadUtilities getJNIEnv]; + GET_CACCESSIBILITY_CLASS_RETURN(nil); + DECLARE_STATIC_METHOD_RETURN(jm_getFocusOwner, sjc_CAccessibility, "getFocusOwner", + "(Ljava/awt/Component;)Ljavax/accessibility/Accessible;", nil); id value = nil; NSWindow* hostWindow = [[self->fView window] retain]; ! jobject focused = (*env)->CallStaticObjectMethod(env, sjc_CAccessibility, jm_getFocusOwner, fComponent); [hostWindow release]; + CHECK_EXCEPTION(); if (focused != NULL) { ! DECLARE_CLASS_RETURN(sjc_Accessible, "javax/accessibility/Accessible", nil); ! if ((*env)->IsInstanceOf(env, focused, sjc_Accessible)) { value = [JavaComponentAccessibility createWithAccessible:focused withEnv:env withView:fView]; } + CHECK_EXCEPTION(); (*env)->DeleteLocalRef(env, focused); } if (value == nil) { value = self;
*** 1377,1492 **** * Signature: ()V */ JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CAccessibility_focusChanged (JNIEnv *env, jobject jthis) { ! JNF_COCOA_ENTER(env); [ThreadUtilities performOnMainThread:@selector(postFocusChanged:) on:[JavaComponentAccessibility class] withObject:nil waitUntilDone:NO]; ! JNF_COCOA_EXIT(env); } /* * Class: sun_lwawt_macosx_CAccessible * Method: valueChanged * Signature: (I)V */ JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CAccessible_valueChanged (JNIEnv *env, jclass jklass, jlong element) { ! JNF_COCOA_ENTER(env); [ThreadUtilities performOnMainThread:@selector(postValueChanged) on:(JavaComponentAccessibility *)jlong_to_ptr(element) withObject:nil waitUntilDone:NO]; ! JNF_COCOA_EXIT(env); } /* * Class: sun_lwawt_macosx_CAccessible * Method: selectedTextChanged * Signature: (I)V */ JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CAccessible_selectedTextChanged (JNIEnv *env, jclass jklass, jlong element) { ! JNF_COCOA_ENTER(env); [ThreadUtilities performOnMainThread:@selector(postSelectedTextChanged) on:(JavaComponentAccessibility *)jlong_to_ptr(element) withObject:nil waitUntilDone:NO]; ! JNF_COCOA_EXIT(env); } /* * Class: sun_lwawt_macosx_CAccessible * Method: selectionChanged * Signature: (I)V */ JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CAccessible_selectionChanged (JNIEnv *env, jclass jklass, jlong element) { ! JNF_COCOA_ENTER(env); [ThreadUtilities performOnMainThread:@selector(postSelectionChanged) on:(JavaComponentAccessibility *)jlong_to_ptr(element) withObject:nil waitUntilDone:NO]; ! JNF_COCOA_EXIT(env); } /* * Class: sun_lwawt_macosx_CAccessible * Method: menuOpened * Signature: (I)V */ JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CAccessible_menuOpened (JNIEnv *env, jclass jklass, jlong element) { ! JNF_COCOA_ENTER(env); [ThreadUtilities performOnMainThread:@selector(postMenuOpened) on:(JavaComponentAccessibility *)jlong_to_ptr(element) withObject:nil waitUntilDone:NO]; ! JNF_COCOA_EXIT(env); } /* * Class: sun_lwawt_macosx_CAccessible * Method: menuClosed * Signature: (I)V */ JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CAccessible_menuClosed (JNIEnv *env, jclass jklass, jlong element) { ! JNF_COCOA_ENTER(env); [ThreadUtilities performOnMainThread:@selector(postMenuClosed) on:(JavaComponentAccessibility *)jlong_to_ptr(element) withObject:nil waitUntilDone:NO]; ! JNF_COCOA_EXIT(env); } /* * Class: sun_lwawt_macosx_CAccessible * Method: menuItemSelected * Signature: (I)V */ JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CAccessible_menuItemSelected (JNIEnv *env, jclass jklass, jlong element) { ! JNF_COCOA_ENTER(env); [ThreadUtilities performOnMainThread:@selector(postMenuItemSelected) on:(JavaComponentAccessibility *)jlong_to_ptr(element) withObject:nil waitUntilDone:NO]; ! JNF_COCOA_EXIT(env); } /* * Class: sun_lwawt_macosx_CAccessible * Method: unregisterFromCocoaAXSystem * Signature: (I)V */ JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CAccessible_unregisterFromCocoaAXSystem (JNIEnv *env, jclass jklass, jlong element) { ! JNF_COCOA_ENTER(env); [ThreadUtilities performOnMainThread:@selector(unregisterFromCocoaAXSystem) on:(JavaComponentAccessibility *)jlong_to_ptr(element) withObject:nil waitUntilDone:NO]; ! JNF_COCOA_EXIT(env); } @implementation TabGroupAccessibility - (id)initWithParent:(NSObject *)parent withEnv:(JNIEnv *)env withAccessible:(jobject)accessible withIndex:(jint)index withView:(NSView *)view withJavaRole:(NSString *)javaRole --- 1503,1618 ---- * Signature: ()V */ JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CAccessibility_focusChanged (JNIEnv *env, jobject jthis) { ! JNI_COCOA_ENTER(env); [ThreadUtilities performOnMainThread:@selector(postFocusChanged:) on:[JavaComponentAccessibility class] withObject:nil waitUntilDone:NO]; ! JNI_COCOA_EXIT(env); } /* * Class: sun_lwawt_macosx_CAccessible * Method: valueChanged * Signature: (I)V */ JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CAccessible_valueChanged (JNIEnv *env, jclass jklass, jlong element) { ! JNI_COCOA_ENTER(env); [ThreadUtilities performOnMainThread:@selector(postValueChanged) on:(JavaComponentAccessibility *)jlong_to_ptr(element) withObject:nil waitUntilDone:NO]; ! JNI_COCOA_EXIT(env); } /* * Class: sun_lwawt_macosx_CAccessible * Method: selectedTextChanged * Signature: (I)V */ JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CAccessible_selectedTextChanged (JNIEnv *env, jclass jklass, jlong element) { ! JNI_COCOA_ENTER(env); [ThreadUtilities performOnMainThread:@selector(postSelectedTextChanged) on:(JavaComponentAccessibility *)jlong_to_ptr(element) withObject:nil waitUntilDone:NO]; ! JNI_COCOA_EXIT(env); } /* * Class: sun_lwawt_macosx_CAccessible * Method: selectionChanged * Signature: (I)V */ JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CAccessible_selectionChanged (JNIEnv *env, jclass jklass, jlong element) { ! JNI_COCOA_ENTER(env); [ThreadUtilities performOnMainThread:@selector(postSelectionChanged) on:(JavaComponentAccessibility *)jlong_to_ptr(element) withObject:nil waitUntilDone:NO]; ! JNI_COCOA_EXIT(env); } /* * Class: sun_lwawt_macosx_CAccessible * Method: menuOpened * Signature: (I)V */ JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CAccessible_menuOpened (JNIEnv *env, jclass jklass, jlong element) { ! JNI_COCOA_ENTER(env); [ThreadUtilities performOnMainThread:@selector(postMenuOpened) on:(JavaComponentAccessibility *)jlong_to_ptr(element) withObject:nil waitUntilDone:NO]; ! JNI_COCOA_EXIT(env); } /* * Class: sun_lwawt_macosx_CAccessible * Method: menuClosed * Signature: (I)V */ JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CAccessible_menuClosed (JNIEnv *env, jclass jklass, jlong element) { ! JNI_COCOA_ENTER(env); [ThreadUtilities performOnMainThread:@selector(postMenuClosed) on:(JavaComponentAccessibility *)jlong_to_ptr(element) withObject:nil waitUntilDone:NO]; ! JNI_COCOA_EXIT(env); } /* * Class: sun_lwawt_macosx_CAccessible * Method: menuItemSelected * Signature: (I)V */ JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CAccessible_menuItemSelected (JNIEnv *env, jclass jklass, jlong element) { ! JNI_COCOA_ENTER(env); [ThreadUtilities performOnMainThread:@selector(postMenuItemSelected) on:(JavaComponentAccessibility *)jlong_to_ptr(element) withObject:nil waitUntilDone:NO]; ! JNI_COCOA_EXIT(env); } /* * Class: sun_lwawt_macosx_CAccessible * Method: unregisterFromCocoaAXSystem * Signature: (I)V */ JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CAccessible_unregisterFromCocoaAXSystem (JNIEnv *env, jclass jklass, jlong element) { ! JNI_COCOA_ENTER(env); [ThreadUtilities performOnMainThread:@selector(unregisterFromCocoaAXSystem) on:(JavaComponentAccessibility *)jlong_to_ptr(element) withObject:nil waitUntilDone:NO]; ! JNI_COCOA_EXIT(env); } @implementation TabGroupAccessibility - (id)initWithParent:(NSObject *)parent withEnv:(JNIEnv *)env withAccessible:(jobject)accessible withIndex:(jint)index withView:(NSView *)view withJavaRole:(NSString *)javaRole
*** 1532,1542 **** return nil; } - (NSArray *)tabControlsWithEnv:(JNIEnv *)env withTabGroupAxContext:(jobject)axContext withTabCode:(NSInteger)whichTabs allowIgnored:(BOOL)allowIgnored { ! jobjectArray jtabsAndRoles = (jobjectArray)JNFCallStaticObjectMethod(env, jm_getChildrenAndRoles, fAccessible, fComponent, whichTabs, allowIgnored); // AWT_THREADING Safe (AWTRunLoop) if(jtabsAndRoles == NULL) return nil; jsize arrayLen = (*env)->GetArrayLength(env, jtabsAndRoles); if (arrayLen == 0) { (*env)->DeleteLocalRef(env, jtabsAndRoles); --- 1658,1671 ---- return nil; } - (NSArray *)tabControlsWithEnv:(JNIEnv *)env withTabGroupAxContext:(jobject)axContext withTabCode:(NSInteger)whichTabs allowIgnored:(BOOL)allowIgnored { ! GET_CHILDRENANDROLES_METHOD_RETURN(nil); ! jobjectArray jtabsAndRoles = (jobjectArray)(*env)->CallStaticObjectMethod(env, sjc_CAccessibility, jm_getChildrenAndRoles, ! fAccessible, fComponent, whichTabs, allowIgnored); ! CHECK_EXCEPTION(); if(jtabsAndRoles == NULL) return nil; jsize arrayLen = (*env)->GetArrayLength(env, jtabsAndRoles); if (arrayLen == 0) { (*env)->DeleteLocalRef(env, jtabsAndRoles);
*** 1548,1559 **** jobject jtabJavaRole = (*env)->GetObjectArrayElement(env, jtabsAndRoles, 1); // the array entries alternate between tab/role, starting with tab. so the first role is entry 1. if (jtabJavaRole == NULL) { (*env)->DeleteLocalRef(env, jtabsAndRoles); return nil; } ! jobject jkey = JNFGetObjectField(env, jtabJavaRole, sjf_key); ! NSString *tabJavaRole = JNFJavaToNSString(env, jkey); (*env)->DeleteLocalRef(env, jkey); NSInteger i; NSUInteger tabIndex = (whichTabs >= 0) ? whichTabs : 0; // if we're getting one particular child, make sure to set its index correctly for(i = 0; i < arrayLen; i+=2) { --- 1677,1691 ---- jobject jtabJavaRole = (*env)->GetObjectArrayElement(env, jtabsAndRoles, 1); // the array entries alternate between tab/role, starting with tab. so the first role is entry 1. if (jtabJavaRole == NULL) { (*env)->DeleteLocalRef(env, jtabsAndRoles); return nil; } ! DECLARE_CLASS_RETURN(sjc_AccessibleRole, "javax/accessibility/AccessibleRole", nil); ! DECLARE_FIELD_RETURN(sjf_key, sjc_AccessibleRole, "key", "Ljava/lang/String;", nil); ! jobject jkey = (*env)->GetObjectField(env, jtabJavaRole, sjf_key); ! CHECK_EXCEPTION(); ! NSString *tabJavaRole = JavaStringToNSString(env, jkey); (*env)->DeleteLocalRef(env, jkey); NSInteger i; NSUInteger tabIndex = (whichTabs >= 0) ? whichTabs : 0; // if we're getting one particular child, make sure to set its index correctly for(i = 0; i < arrayLen; i+=2) {
*** 1691,1701 **** - (id)initWithParent:(NSObject *)parent withEnv:(JNIEnv *)env withAccessible:(jobject)accessible withIndex:(jint)index withTabGroup:(jobject)tabGroup withView:(NSView *)view withJavaRole:(NSString *)javaRole { self = [super initWithParent:parent withEnv:env withAccessible:accessible withIndex:index withView:view withJavaRole:javaRole]; if (self) { if (tabGroup != NULL) { ! fTabGroupAxContext = JNFNewWeakGlobalRef(env, tabGroup); } else { fTabGroupAxContext = NULL; } } return self; --- 1823,1834 ---- - (id)initWithParent:(NSObject *)parent withEnv:(JNIEnv *)env withAccessible:(jobject)accessible withIndex:(jint)index withTabGroup:(jobject)tabGroup withView:(NSView *)view withJavaRole:(NSString *)javaRole { self = [super initWithParent:parent withEnv:env withAccessible:accessible withIndex:index withView:view withJavaRole:javaRole]; if (self) { if (tabGroup != NULL) { ! fTabGroupAxContext = (*env)->NewWeakGlobalRef(env, tabGroup); ! CHECK_EXCEPTION(); } else { fTabGroupAxContext = NULL; } } return self;
*** 1704,1714 **** - (void)dealloc { JNIEnv *env = [ThreadUtilities getJNIEnvUncached]; if (fTabGroupAxContext != NULL) { ! JNFDeleteWeakGlobalRef(env, fTabGroupAxContext); fTabGroupAxContext = NULL; } [super dealloc]; } --- 1837,1847 ---- - (void)dealloc { JNIEnv *env = [ThreadUtilities getJNIEnvUncached]; if (fTabGroupAxContext != NULL) { ! (*env)->DeleteWeakGlobalRef(env, fTabGroupAxContext); fTabGroupAxContext = NULL; } [super dealloc]; }
*** 1737,1747 **** - (jobject)tabGroup { if (fTabGroupAxContext == NULL) { JNIEnv* env = [ThreadUtilities getJNIEnv]; jobject tabGroupAxContext = [(JavaComponentAccessibility *)[self parent] axContextWithEnv:env]; ! fTabGroupAxContext = JNFNewWeakGlobalRef(env, tabGroupAxContext); (*env)->DeleteLocalRef(env, tabGroupAxContext); } return fTabGroupAxContext; } --- 1870,1881 ---- - (jobject)tabGroup { if (fTabGroupAxContext == NULL) { JNIEnv* env = [ThreadUtilities getJNIEnv]; jobject tabGroupAxContext = [(JavaComponentAccessibility *)[self parent] axContextWithEnv:env]; ! fTabGroupAxContext = (*env)->NewWeakGlobalRef(env, tabGroupAxContext); ! CHECK_EXCEPTION(); (*env)->DeleteLocalRef(env, tabGroupAxContext); } return fTabGroupAxContext; }
*** 1850,1871 **** /* * Returns Object.equals for the two items * This may use LWCToolkit.invokeAndWait(); don't call while holding fLock * and try to pass a component so the event happens on the correct thread. */ - static JNF_CLASS_CACHE(sjc_Object, "java/lang/Object"); static BOOL ObjectEquals(JNIEnv *env, jobject a, jobject b, jobject component) { ! static JNF_MEMBER_CACHE(jm_equals, sjc_Object, "equals", "(Ljava/lang/Object;)Z"); if ((a == NULL) && (b == NULL)) return YES; if ((a == NULL) || (b == NULL)) return NO; if (pthread_main_np() != 0) { // If we are on the AppKit thread ! static JNF_CLASS_CACHE(sjc_LWCToolkit, "sun/lwawt/macosx/LWCToolkit"); ! static JNF_STATIC_MEMBER_CACHE(jm_doEquals, sjc_LWCToolkit, "doEquals", "(Ljava/lang/Object;Ljava/lang/Object;Ljava/awt/Component;)Z"); ! return JNFCallStaticBooleanMethod(env, jm_doEquals, a, b, component); // AWT_THREADING Safe (AWTRunLoopMode) } ! return JNFCallBooleanMethod(env, a, jm_equals, b); // AWT_THREADING Safe (!appKit) } --- 1984,2009 ---- /* * Returns Object.equals for the two items * This may use LWCToolkit.invokeAndWait(); don't call while holding fLock * and try to pass a component so the event happens on the correct thread. */ static BOOL ObjectEquals(JNIEnv *env, jobject a, jobject b, jobject component) { ! DECLARE_CLASS_RETURN(sjc_Object, "java/lang/Object", NO); ! DECLARE_METHOD_RETURN(jm_equals, sjc_Object, "equals", "(Ljava/lang/Object;)Z", NO); if ((a == NULL) && (b == NULL)) return YES; if ((a == NULL) || (b == NULL)) return NO; if (pthread_main_np() != 0) { // If we are on the AppKit thread ! DECLARE_CLASS_RETURN(sjc_LWCToolkit, "sun/lwawt/macosx/LWCToolkit", NO); ! DECLARE_STATIC_METHOD_RETURN(jm_doEquals, sjc_LWCToolkit, "doEquals", ! "(Ljava/lang/Object;Ljava/lang/Object;Ljava/awt/Component;)Z", NO); ! return (*env)->CallStaticBooleanMethod(env, sjc_LWCToolkit, jm_doEquals, a, b, component); ! CHECK_EXCEPTION(); } ! jboolean jb = (*env)->CallBooleanMethod(env, a, jm_equals, b); ! CHECK_EXCEPTION(); ! return jb; }
< prev index next >