jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/JavaComponentAccessibility.m
changeset 39873 76907ae1b680
parent 38408 3c80511b8982
child 41400 71893f19fd7f
equal deleted inserted replaced
39872:088180ff66b9 39873:76907ae1b680
   199 {
   199 {
   200     AWT_ASSERT_APPKIT_THREAD;
   200     AWT_ASSERT_APPKIT_THREAD;
   201     NSAccessibilityPostNotification(self, NSAccessibilityValueChangedNotification);
   201     NSAccessibilityPostNotification(self, NSAccessibilityValueChangedNotification);
   202 }
   202 }
   203 
   203 
   204 - (void)postSelectionChanged
   204 - (void)postSelectedTextChanged
   205 {
   205 {
   206     AWT_ASSERT_APPKIT_THREAD;
   206     AWT_ASSERT_APPKIT_THREAD;
   207     NSAccessibilityPostNotification(self, NSAccessibilitySelectedTextChangedNotification);
   207     NSAccessibilityPostNotification(self, NSAccessibilitySelectedTextChangedNotification);
   208 }
   208 }
   209 
   209 
       
   210 - (void)postSelectionChanged
       
   211 {
       
   212     AWT_ASSERT_APPKIT_THREAD;
       
   213     NSAccessibilityPostNotification(self, NSAccessibilitySelectedChildrenChangedNotification);
       
   214 }
       
   215 
   210 - (BOOL)isEqual:(id)anObject
   216 - (BOOL)isEqual:(id)anObject
   211 {
   217 {
   212     if (![anObject isKindOfClass:[self class]]) return NO;
   218     if (![anObject isKindOfClass:[self class]]) return NO;
   213     JavaComponentAccessibility *accessibility = (JavaComponentAccessibility *)anObject;
   219     JavaComponentAccessibility *accessibility = (JavaComponentAccessibility *)anObject;
   214 
   220 
   223 
   229 
   224 + (void)initialize
   230 + (void)initialize
   225 {
   231 {
   226     if (sAttributeNamesForRoleCache == nil) {
   232     if (sAttributeNamesForRoleCache == nil) {
   227         sAttributeNamesLOCK = [[NSObject alloc] init];
   233         sAttributeNamesLOCK = [[NSObject alloc] init];
   228         sAttributeNamesForRoleCache = [[NSMutableDictionary alloc] initWithCapacity:10];
   234         sAttributeNamesForRoleCache = [[NSMutableDictionary alloc] initWithCapacity:60];
   229     }
   235     }
   230 
   236 
   231     if (sRoles == nil) {
   237     if (sRoles == nil) {
   232         initializeRoles();
   238         initializeRoles();
   233     }
   239     }
   279     return NULL;
   285     return NULL;
   280 }
   286 }
   281 
   287 
   282 + (NSArray *)childrenOfParent:(JavaComponentAccessibility *)parent withEnv:(JNIEnv *)env withChildrenCode:(NSInteger)whichChildren allowIgnored:(BOOL)allowIgnored
   288 + (NSArray *)childrenOfParent:(JavaComponentAccessibility *)parent withEnv:(JNIEnv *)env withChildrenCode:(NSInteger)whichChildren allowIgnored:(BOOL)allowIgnored
   283 {
   289 {
       
   290     if (parent->fAccessible == NULL) return nil;
   284     jobjectArray jchildrenAndRoles = (jobjectArray)JNFCallStaticObjectMethod(env, jm_getChildrenAndRoles, parent->fAccessible, parent->fComponent, whichChildren, allowIgnored); // AWT_THREADING Safe (AWTRunLoop)
   291     jobjectArray jchildrenAndRoles = (jobjectArray)JNFCallStaticObjectMethod(env, jm_getChildrenAndRoles, parent->fAccessible, parent->fComponent, whichChildren, allowIgnored); // AWT_THREADING Safe (AWTRunLoop)
   285     if (jchildrenAndRoles == NULL) return nil;
   292     if (jchildrenAndRoles == NULL) return nil;
   286 
   293 
   287     jsize arrayLen = (*env)->GetArrayLength(env, jchildrenAndRoles);
   294     jsize arrayLen = (*env)->GetArrayLength(env, jchildrenAndRoles);
   288     NSMutableArray *children = [NSMutableArray arrayWithCapacity:arrayLen/2]; //childrenAndRoles array contains two elements (child, role) for each child
   295     NSMutableArray *children = [NSMutableArray arrayWithCapacity:arrayLen/2]; //childrenAndRoles array contains two elements (child, role) for each child
   368 
   375 
   369 - (NSArray *)initializeAttributeNamesWithEnv:(JNIEnv *)env
   376 - (NSArray *)initializeAttributeNamesWithEnv:(JNIEnv *)env
   370 {
   377 {
   371     static JNF_STATIC_MEMBER_CACHE(jm_getInitialAttributeStates, sjc_CAccessibility, "getInitialAttributeStates", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)[Z");
   378     static JNF_STATIC_MEMBER_CACHE(jm_getInitialAttributeStates, sjc_CAccessibility, "getInitialAttributeStates", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)[Z");
   372 
   379 
   373     NSMutableArray *attributeNames = [NSMutableArray arrayWithCapacity:10];
   380     NSMutableArray *attributeNames = [NSMutableArray arrayWithCapacity:20];
   374     [attributeNames retain];
   381     [attributeNames retain];
   375 
   382 
   376     // all elements respond to parent, role, role description, window, topLevelUIElement, help
   383     // all elements respond to parent, role, role description, window, topLevelUIElement, help
   377     [attributeNames addObject:NSAccessibilityParentAttribute];
   384     [attributeNames addObject:NSAccessibilityParentAttribute];
   378     [attributeNames addObject:NSAccessibilityRoleAttribute];
   385     [attributeNames addObject:NSAccessibilityRoleAttribute];
   447     }
   454     }
   448 
   455 
   449     // children
   456     // children
   450     if (attributeStatesArray[6]) {
   457     if (attributeStatesArray[6]) {
   451         [attributeNames addObject:NSAccessibilityChildrenAttribute];
   458         [attributeNames addObject:NSAccessibilityChildrenAttribute];
       
   459         if ([javaRole isEqualToString:@"list"]) {
       
   460             [attributeNames addObject:NSAccessibilitySelectedChildrenAttribute];
       
   461             [attributeNames addObject:NSAccessibilityVisibleChildrenAttribute];
       
   462         }
       
   463         // Just above, the below mentioned support has been added back in for lists.
       
   464         // However, the following comments may still be useful for future fixes.
   452 //        [attributeNames addObject:NSAccessibilitySelectedChildrenAttribute];
   465 //        [attributeNames addObject:NSAccessibilitySelectedChildrenAttribute];
   453 //        [attributeNames addObject:NSAccessibilityVisibleChildrenAttribute];
   466 //        [attributeNames addObject:NSAccessibilityVisibleChildrenAttribute];
   454                 //According to AXRoles.txt:
   467                 //According to AXRoles.txt:
   455                 //VisibleChildren: radio group, list, row, table row subrole
   468                 //VisibleChildren: radio group, list, row, table row subrole
   456                 //SelectedChildren: list
   469                 //SelectedChildren: list
   565     }
   578     }
   566 
   579 
   567     return isChildSelected(env, ((JavaComponentAccessibility *)[self parent])->fAccessible, fIndex, fComponent);
   580     return isChildSelected(env, ((JavaComponentAccessibility *)[self parent])->fAccessible, fIndex, fComponent);
   568 }
   581 }
   569 
   582 
       
   583 - (BOOL)isSelectable:(JNIEnv *)env
       
   584 {
       
   585     jobject axContext = [self axContextWithEnv:env];
       
   586     BOOL selectable = isSelectable(env, axContext, fComponent);
       
   587     (*env)->DeleteLocalRef(env, axContext);
       
   588     return selectable;
       
   589 }
       
   590 
   570 - (BOOL)isVisible:(JNIEnv *)env
   591 - (BOOL)isVisible:(JNIEnv *)env
   571 {
   592 {
   572     if (fIndex == -1) {
   593     if (fIndex == -1) {
   573         return NO;
   594         return NO;
   574     }
   595     }
   584 {
   605 {
   585     JNIEnv* env = [ThreadUtilities getJNIEnv];
   606     JNIEnv* env = [ThreadUtilities getJNIEnv];
   586 
   607 
   587     @synchronized(sAttributeNamesLOCK) {
   608     @synchronized(sAttributeNamesLOCK) {
   588         NSString *javaRole = [self javaRole];
   609         NSString *javaRole = [self javaRole];
   589         NSArray *names = (NSArray *)[sAttributeNamesForRoleCache objectForKey:javaRole];
   610         NSArray *names =
   590         if (names != nil) return names;
   611             (NSArray *)[sAttributeNamesForRoleCache objectForKey:javaRole];
   591 
   612         if (names == nil) {
   592         names = [self initializeAttributeNamesWithEnv:env];
   613             names = [self initializeAttributeNamesWithEnv:env];
   593         if (names != nil) {
       
   594 #ifdef JAVA_AX_DEBUG
   614 #ifdef JAVA_AX_DEBUG
   595             NSLog(@"Initializing: %s for %@: %@", __FUNCTION__, javaRole, names);
   615             NSLog(@"Initializing: %s for %@: %@", __FUNCTION__, javaRole, names);
   596 #endif
   616 #endif
   597             [sAttributeNamesForRoleCache setObject:names forKey:javaRole];
   617             [sAttributeNamesForRoleCache setObject:names forKey:javaRole];
   598             return names;
   618         }
   599         }
   619         // The above set of attributes is immutable per role, but some objects, if
   600     }
   620         // they are the child of a list, need to add the selected and index attributes.
       
   621         id myParent = [self accessibilityParentAttribute];
       
   622         if ([myParent isKindOfClass:[JavaComponentAccessibility class]]) {
       
   623             NSString *parentRole = [(JavaComponentAccessibility *)myParent javaRole];
       
   624             if ([parentRole isEqualToString:@"list"]) {
       
   625                 NSMutableArray *moreNames =
       
   626                     [[NSMutableArray alloc] initWithCapacity: [names count] + 2];
       
   627                 [moreNames addObjectsFromArray: names];
       
   628                 [moreNames addObject:NSAccessibilitySelectedAttribute];
       
   629                 [moreNames addObject:NSAccessibilityIndexAttribute];
       
   630                 return moreNames;
       
   631             }
       
   632         }
       
   633         return names;
       
   634 
       
   635     }  // end @synchronized
   601 
   636 
   602 #ifdef JAVA_AX_DEBUG
   637 #ifdef JAVA_AX_DEBUG
   603     NSLog(@"Warning in %s: could not find attribute names for role: %@", __FUNCTION__, [self javaRole]);
   638     NSLog(@"Warning in %s: could not find attribute names for role: %@", __FUNCTION__, [self javaRole]);
   604 #endif
   639 #endif
   605 
   640 
   654 
   689 
   655 // Elements that current element contains (NSArray)
   690 // Elements that current element contains (NSArray)
   656 - (NSArray *)accessibilityChildrenAttribute
   691 - (NSArray *)accessibilityChildrenAttribute
   657 {
   692 {
   658     JNIEnv* env = [ThreadUtilities getJNIEnv];
   693     JNIEnv* env = [ThreadUtilities getJNIEnv];
   659     NSArray *children = [JavaComponentAccessibility childrenOfParent:self withEnv:env withChildrenCode:JAVA_AX_VISIBLE_CHILDREN allowIgnored:NO];
   694     NSArray *children = [JavaComponentAccessibility childrenOfParent:self
       
   695                                                     withEnv:env
       
   696                                                     withChildrenCode:JAVA_AX_ALL_CHILDREN
       
   697                                                     allowIgnored:NO];
   660 
   698 
   661     NSArray *value = nil;
   699     NSArray *value = nil;
   662     if ([children count] > 0) {
   700     if ([children count] > 0) {
   663         value = children;
   701         value = children;
   664     }
   702     }
   678     // only ones that override the default implementation in NSAccessibility
   716     // only ones that override the default implementation in NSAccessibility
   679     if (![[self accessibilityRoleAttribute] isEqualToString:NSAccessibilityListRole]) {
   717     if (![[self accessibilityRoleAttribute] isEqualToString:NSAccessibilityListRole]) {
   680         return [super accessibilityIndexOfChild:child];
   718         return [super accessibilityIndexOfChild:child];
   681     }
   719     }
   682 
   720 
   683     return JNFCallStaticIntMethod([ThreadUtilities getJNIEnv], sjm_getAccessibleIndexInParent, ((JavaComponentAccessibility *)child)->fAccessible, ((JavaComponentAccessibility *)child)->fComponent);
   721     jint returnValue =
       
   722         JNFCallStaticIntMethod( [ThreadUtilities getJNIEnv],
       
   723                                 sjm_getAccessibleIndexInParent,
       
   724                                 ((JavaComponentAccessibility *)child)->fAccessible,
       
   725                                 ((JavaComponentAccessibility *)child)->fComponent );
       
   726     return (returnValue == -1) ? NSNotFound : returnValue;
   684 }
   727 }
   685 
   728 
   686 // Without this optimization accessibilityChildrenAttribute is called in order to get the entire array of children.
   729 // Without this optimization accessibilityChildrenAttribute is called in order to get the entire array of children.
   687 - (NSArray *)accessibilityArrayAttributeValues:(NSString *)attribute index:(NSUInteger)index maxCount:(NSUInteger)maxCount {
   730 - (NSArray *)accessibilityArrayAttributeValues:(NSString *)attribute index:(NSUInteger)index maxCount:(NSUInteger)maxCount {
   688     if ( (maxCount == 1) && [attribute isEqualToString:NSAccessibilityChildrenAttribute]) {
   731     if ( (maxCount == 1) && [attribute isEqualToString:NSAccessibilityChildrenAttribute]) {
   752 {
   795 {
   753     JNIEnv* env = [ThreadUtilities getJNIEnv];
   796     JNIEnv* env = [ThreadUtilities getJNIEnv];
   754 
   797 
   755     jobject val = JNFCallStaticObjectMethod(env, sjm_getAccessibleDescription, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
   798     jobject val = JNFCallStaticObjectMethod(env, sjm_getAccessibleDescription, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
   756     if (val == NULL) {
   799     if (val == NULL) {
   757         return @"unknown";
   800         return nil;
   758     }
   801     }
   759     NSString* str = JNFJavaToNSString(env, val);
   802     NSString* str = JNFJavaToNSString(env, val);
   760     (*env)->DeleteLocalRef(env, val);
   803     (*env)->DeleteLocalRef(env, val);
   761     return str;
   804     return str;
   762 }
   805 }
   763 
   806 
   764 - (BOOL)accessibilityIsHelpAttributeSettable
   807 - (BOOL)accessibilityIsHelpAttributeSettable
       
   808 {
       
   809     return NO;
       
   810 }
       
   811 
       
   812 - (NSValue *)accessibilityIndexAttribute
       
   813 {
       
   814     NSInteger index = fIndex;
       
   815     NSValue *returnValue = [NSValue value:&index withObjCType:@encode(NSInteger)];
       
   816     return returnValue;
       
   817 }
       
   818 
       
   819 - (BOOL)accessibilityIsIndexAttributeSettable
   765 {
   820 {
   766     return NO;
   821     return NO;
   767 }
   822 }
   768 
   823 
   769 // Element's maximum value (id)
   824 // Element's maximum value (id)
   935 }
   990 }
   936 
   991 
   937 - (BOOL)accessibilityIsSelectedChildrenAttributeSettable
   992 - (BOOL)accessibilityIsSelectedChildrenAttributeSettable
   938 {
   993 {
   939     return NO; // cmcnote: actually it should be. so need to write accessibilitySetSelectedChildrenAttribute also
   994     return NO; // cmcnote: actually it should be. so need to write accessibilitySetSelectedChildrenAttribute also
       
   995 }
       
   996 
       
   997 - (NSNumber *)accessibilitySelectedAttribute
       
   998 {
       
   999     return [NSNumber numberWithBool:[self isSelected:[ThreadUtilities getJNIEnv]]];
       
  1000 }
       
  1001 
       
  1002 - (BOOL)accessibilityIsSelectedAttributeSettable
       
  1003 {
       
  1004     if ([self isSelectable:[ThreadUtilities getJNIEnv]]) {
       
  1005         return YES;
       
  1006     } else {
       
  1007         return NO;
       
  1008     }
       
  1009 }
       
  1010 
       
  1011 - (void)accessibilitySetSelectedAttribute:(id)value
       
  1012 {
       
  1013     static JNF_STATIC_MEMBER_CACHE( jm_requestSelection,
       
  1014                                     sjc_CAccessibility,
       
  1015                                     "requestSelection",
       
  1016                                     "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)V" );
       
  1017     
       
  1018     if ([(NSNumber*)value boolValue]) {
       
  1019         JNIEnv* env = [ThreadUtilities getJNIEnv];
       
  1020         JNFCallStaticVoidMethod(env, jm_requestSelection, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
       
  1021     }
   940 }
  1022 }
   941 
  1023 
   942 // Element size (NSValue)
  1024 // Element size (NSValue)
   943 - (NSValue *)accessibilitySizeAttribute {
  1025 - (NSValue *)accessibilitySizeAttribute {
   944     JNIEnv* env = [ThreadUtilities getJNIEnv];
  1026     JNIEnv* env = [ThreadUtilities getJNIEnv];
  1003 
  1085 
  1004     JNIEnv* env = [ThreadUtilities getJNIEnv];
  1086     JNIEnv* env = [ThreadUtilities getJNIEnv];
  1005 
  1087 
  1006     jobject val = JNFCallStaticObjectMethod(env, sjm_getAccessibleName, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
  1088     jobject val = JNFCallStaticObjectMethod(env, sjm_getAccessibleName, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
  1007     if (val == NULL) {
  1089     if (val == NULL) {
  1008         return @"unknown";
  1090         return nil;
  1009     }
  1091     }
  1010     NSString* str = JNFJavaToNSString(env, val);
  1092     NSString* str = JNFJavaToNSString(env, val);
  1011     (*env)->DeleteLocalRef(env, val);
  1093     (*env)->DeleteLocalRef(env, val);
  1012     return str;
  1094     return str;
  1013 }
  1095 }
  1208  * Signature: ()V
  1290  * Signature: ()V
  1209  */
  1291  */
  1210 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CAccessibility_focusChanged
  1292 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CAccessibility_focusChanged
  1211 (JNIEnv *env, jobject jthis)
  1293 (JNIEnv *env, jobject jthis)
  1212 {
  1294 {
  1213 
       
  1214 JNF_COCOA_ENTER(env);
  1295 JNF_COCOA_ENTER(env);
  1215     [ThreadUtilities performOnMainThread:@selector(postFocusChanged:) on:[JavaComponentAccessibility class] withObject:nil waitUntilDone:NO];
  1296     [ThreadUtilities performOnMainThread:@selector(postFocusChanged:) on:[JavaComponentAccessibility class] withObject:nil waitUntilDone:NO];
  1216 JNF_COCOA_EXIT(env);
  1297 JNF_COCOA_EXIT(env);
  1217 }
  1298 }
  1218 
       
  1219 
       
  1220 
  1299 
  1221 /*
  1300 /*
  1222  * Class:     sun_lwawt_macosx_CAccessible
  1301  * Class:     sun_lwawt_macosx_CAccessible
  1223  * Method:    valueChanged
  1302  * Method:    valueChanged
  1224  * Signature: (I)V
  1303  * Signature: (I)V
  1231 JNF_COCOA_EXIT(env);
  1310 JNF_COCOA_EXIT(env);
  1232 }
  1311 }
  1233 
  1312 
  1234 /*
  1313 /*
  1235  * Class:     sun_lwawt_macosx_CAccessible
  1314  * Class:     sun_lwawt_macosx_CAccessible
       
  1315  * Method:    selectedTextChanged
       
  1316  * Signature: (I)V
       
  1317  */
       
  1318 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CAccessible_selectedTextChanged
       
  1319 (JNIEnv *env, jclass jklass, jlong element)
       
  1320 {
       
  1321 JNF_COCOA_ENTER(env);
       
  1322     [ThreadUtilities performOnMainThread:@selector(postSelectedTextChanged)
       
  1323                      on:(JavaComponentAccessibility *)jlong_to_ptr(element)
       
  1324                      withObject:nil
       
  1325                      waitUntilDone:NO];
       
  1326 JNF_COCOA_EXIT(env);
       
  1327 }
       
  1328 
       
  1329 /*
       
  1330  * Class:     sun_lwawt_macosx_CAccessible
  1236  * Method:    selectionChanged
  1331  * Method:    selectionChanged
  1237  * Signature: (I)V
  1332  * Signature: (I)V
  1238  */
  1333  */
  1239 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CAccessible_selectionChanged
  1334 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CAccessible_selectionChanged
  1240 (JNIEnv *env, jclass jklass, jlong element)
  1335 (JNIEnv *env, jclass jklass, jlong element)
  1241 {
  1336 {
  1242 JNF_COCOA_ENTER(env);
  1337 JNF_COCOA_ENTER(env);
  1243     [ThreadUtilities performOnMainThread:@selector(postSelectionChanged) on:(JavaComponentAccessibility *)jlong_to_ptr(element) withObject:nil waitUntilDone:NO];
  1338     [ThreadUtilities performOnMainThread:@selector(postSelectionChanged) on:(JavaComponentAccessibility *)jlong_to_ptr(element) withObject:nil waitUntilDone:NO];
  1244 JNF_COCOA_EXIT(env);
  1339 JNF_COCOA_EXIT(env);
  1245 }
  1340 }
  1246 
       
  1247 
  1341 
  1248 /*
  1342 /*
  1249  * Class:     sun_lwawt_macosx_CAccessible
  1343  * Class:     sun_lwawt_macosx_CAccessible
  1250  * Method:    unregisterFromCocoaAXSystem
  1344  * Method:    unregisterFromCocoaAXSystem
  1251  * Signature: (I)V
  1345  * Signature: (I)V