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 package sun.lwawt.macosx; 27 28 import sun.lwawt.LWWindowPeer; 29 30 import java.awt.*; 31 import java.beans.*; 32 import java.lang.reflect.Field; 33 import java.lang.reflect.InvocationTargetException; 34 import java.util.*; 35 import java.util.concurrent.Callable; 36 import sun.awt.AWTAccessor; 37 38 import javax.accessibility.*; 39 import javax.swing.*; 40 import sun.awt.AWTAccessor; 41 42 class CAccessibility implements PropertyChangeListener { 43 private static Set<String> ignoredRoles; 44 45 static { 46 // Need to load the native library for this code. 47 java.security.AccessController.doPrivileged( 48 new java.security.PrivilegedAction<Void>() { 49 public Void run() { 50 System.loadLibrary("awt"); 51 return null; 52 } 53 }); 54 } 55 56 static CAccessibility sAccessibility; 57 static synchronized CAccessibility getAccessibility(final String[] roles) { 58 if (sAccessibility != null) return sAccessibility; 59 sAccessibility = new CAccessibility(); 60 61 if (roles != null) { 62 ignoredRoles = new HashSet<String>(roles.length); 63 for (final String role : roles) ignoredRoles.add(role); 64 } else { 65 ignoredRoles = new HashSet<String>(); 66 } 67 68 return sAccessibility; 69 } 70 71 private CAccessibility() { 72 KeyboardFocusManager.getCurrentKeyboardFocusManager().addPropertyChangeListener("focusOwner", this); 73 } 74 75 public void propertyChange(final PropertyChangeEvent evt) { 76 if (evt.getNewValue() == null) return; 77 focusChanged(); 78 } 79 80 private native void focusChanged(); 81 82 static <T> T invokeAndWait(final Callable<T> callable, final Component c) { 83 try { 84 return LWCToolkit.invokeAndWait(callable, c); 85 } catch (final Exception e) { e.printStackTrace(); } 86 return null; 87 } 88 89 static void invokeLater(final Runnable runnable, final Component c) { 90 try { 91 LWCToolkit.invokeLater(runnable, c); 92 } catch (InvocationTargetException e) { e.printStackTrace(); } 93 } 94 95 public static String getAccessibleActionDescription(final AccessibleAction aa, final int index, final Component c) { 96 if (aa == null) return null; 97 98 return invokeAndWait(new Callable<String>() { 657 658 // Either gets the immediate children of a, or recursively gets all unignored children of a 659 private static void _addChildren(final Accessible a, final int whichChildren, final boolean allowIgnored, final ArrayList<Object> childrenAndRoles) { 660 if (a == null) return; 661 662 final AccessibleContext ac = a.getAccessibleContext(); 663 if (ac == null) return; 664 665 final int numChildren = ac.getAccessibleChildrenCount(); 666 667 // each child takes up two entries in the array: itself, and its role 668 // so the array holds alternating Accessible and AccessibleRole objects 669 for (int i = 0; i < numChildren; i++) { 670 final Accessible child = ac.getAccessibleChild(i); 671 if (child == null) continue; 672 673 final AccessibleContext context = child.getAccessibleContext(); 674 if (context == null) continue; 675 676 if (whichChildren == JAVA_AX_VISIBLE_CHILDREN) { 677 if (!context.getAccessibleComponent().isVisible()) continue; 678 } else if (whichChildren == JAVA_AX_SELECTED_CHILDREN) { 679 if (!ac.getAccessibleSelection().isAccessibleChildSelected(i)) continue; 680 } 681 682 if (!allowIgnored) { 683 final AccessibleRole role = context.getAccessibleRole(); 684 if (role != null && ignoredRoles != null && ignoredRoles.contains(roleKey(role))) { 685 // Get the child's unignored children. 686 _addChildren(child, whichChildren, false, childrenAndRoles); 687 } else { 688 childrenAndRoles.add(child); 689 childrenAndRoles.add(getAccessibleRole(child)); 690 } 691 } else { 692 childrenAndRoles.add(child); 693 childrenAndRoles.add(getAccessibleRole(child)); 694 } 695 696 // If there is an index, and we are beyond it, time to finish up 697 if ((whichChildren >= 0) && (childrenAndRoles.size() / 2) >= (whichChildren + 1)) { 698 return; 699 } | 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 package sun.lwawt.macosx; 27 28 import sun.lwawt.LWWindowPeer; 29 30 import java.awt.*; 31 import java.beans.*; 32 import java.lang.reflect.InvocationTargetException; 33 import java.util.*; 34 import java.util.concurrent.Callable; 35 36 import javax.accessibility.*; 37 import javax.swing.*; 38 import sun.awt.AWTAccessor; 39 40 class CAccessibility implements PropertyChangeListener { 41 private static Set<String> ignoredRoles; 42 43 static { 44 // Need to load the native library for this code. 45 java.security.AccessController.doPrivileged( 46 new java.security.PrivilegedAction<Void>() { 47 public Void run() { 48 System.loadLibrary("awt"); 49 return null; 50 } 51 }); 52 } 53 54 static CAccessibility sAccessibility; 55 static synchronized CAccessibility getAccessibility(final String[] roles) { 56 if (sAccessibility != null) return sAccessibility; 57 sAccessibility = new CAccessibility(); 58 59 if (roles != null) { 60 ignoredRoles = new HashSet<String>(roles.length); 61 for (final String role : roles) ignoredRoles.add(role); 62 } else { 63 ignoredRoles = new HashSet<String>(); 64 } 65 66 return sAccessibility; 67 } 68 69 private CAccessibility() { 70 KeyboardFocusManager.getCurrentKeyboardFocusManager().addPropertyChangeListener("focusOwner", this); 71 } 72 73 public void propertyChange(final PropertyChangeEvent evt) { 74 Object newValue = evt.getNewValue(); 75 if (newValue == null) return; 76 // Don't post focus on things that don't matter, i.e. alert, colorchooser, 77 // desktoppane, dialog, directorypane, filechooser, filler, fontchoose, 78 // frame, glasspane, layeredpane, optionpane, panel, rootpane, separator, 79 // tooltip, viewport, window. 80 // List taken from initializeRoles() in JavaComponentUtilities.m. 81 if (newValue instanceof Accessible) { 82 AccessibleContext nvAC = ((Accessible) newValue).getAccessibleContext(); 83 AccessibleRole nvRole = nvAC.getAccessibleRole(); 84 if (!ignoredRoles.contains(roleKey(nvRole))) { 85 focusChanged(); 86 } 87 } 88 } 89 90 private native void focusChanged(); 91 92 static <T> T invokeAndWait(final Callable<T> callable, final Component c) { 93 try { 94 return LWCToolkit.invokeAndWait(callable, c); 95 } catch (final Exception e) { e.printStackTrace(); } 96 return null; 97 } 98 99 static void invokeLater(final Runnable runnable, final Component c) { 100 try { 101 LWCToolkit.invokeLater(runnable, c); 102 } catch (InvocationTargetException e) { e.printStackTrace(); } 103 } 104 105 public static String getAccessibleActionDescription(final AccessibleAction aa, final int index, final Component c) { 106 if (aa == null) return null; 107 108 return invokeAndWait(new Callable<String>() { 667 668 // Either gets the immediate children of a, or recursively gets all unignored children of a 669 private static void _addChildren(final Accessible a, final int whichChildren, final boolean allowIgnored, final ArrayList<Object> childrenAndRoles) { 670 if (a == null) return; 671 672 final AccessibleContext ac = a.getAccessibleContext(); 673 if (ac == null) return; 674 675 final int numChildren = ac.getAccessibleChildrenCount(); 676 677 // each child takes up two entries in the array: itself, and its role 678 // so the array holds alternating Accessible and AccessibleRole objects 679 for (int i = 0; i < numChildren; i++) { 680 final Accessible child = ac.getAccessibleChild(i); 681 if (child == null) continue; 682 683 final AccessibleContext context = child.getAccessibleContext(); 684 if (context == null) continue; 685 686 if (whichChildren == JAVA_AX_VISIBLE_CHILDREN) { 687 AccessibleComponent acomp = context.getAccessibleComponent(); 688 if (acomp == null || !acomp.isVisible()) { 689 continue; 690 } 691 } else if (whichChildren == JAVA_AX_SELECTED_CHILDREN) { 692 AccessibleSelection sel = ac.getAccessibleSelection(); 693 if (sel == null || !sel.isAccessibleChildSelected(i)) { 694 continue; 695 } 696 } 697 698 if (!allowIgnored) { 699 final AccessibleRole role = context.getAccessibleRole(); 700 if (role != null && ignoredRoles != null && ignoredRoles.contains(roleKey(role))) { 701 // Get the child's unignored children. 702 _addChildren(child, whichChildren, false, childrenAndRoles); 703 } else { 704 childrenAndRoles.add(child); 705 childrenAndRoles.add(getAccessibleRole(child)); 706 } 707 } else { 708 childrenAndRoles.add(child); 709 childrenAndRoles.add(getAccessibleRole(child)); 710 } 711 712 // If there is an index, and we are beyond it, time to finish up 713 if ((whichChildren >= 0) && (childrenAndRoles.size() / 2) >= (whichChildren + 1)) { 714 return; 715 } |