Source Code Cross Referenced for Accessible.java in  » IDE-Eclipse » swt » org » eclipse » swt » accessibility » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE Eclipse » swt » org.eclipse.swt.accessibility 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*******************************************************************************
0002:         * Copyright (c) 2000, 2007 IBM Corporation and others.
0003:         * All rights reserved. This program and the accompanying materials
0004:         * are made available under the terms of the Eclipse Public License v1.0
0005:         * which accompanies this distribution, and is available at
0006:         * http://www.eclipse.org/legal/epl-v10.html
0007:         *
0008:         * Contributors:
0009:         *     IBM Corporation - initial API and implementation
0010:         *******************************************************************************/package org.eclipse.swt.accessibility;
0011:
0012:        import java.util.Vector;
0013:        import org.eclipse.swt.*;
0014:        import org.eclipse.swt.widgets.Control;
0015:        import org.eclipse.swt.internal.carbon.*;
0016:
0017:        /**
0018:         * Instances of this class provide a bridge between application
0019:         * code and assistive technology clients. Many platforms provide
0020:         * default accessible behavior for most widgets, and this class
0021:         * allows that default behavior to be overridden. Applications
0022:         * can get the default Accessible object for a control by sending
0023:         * it <code>getAccessible</code>, and then add an accessible listener
0024:         * to override simple items like the name and help string, or they
0025:         * can add an accessible control listener to override complex items.
0026:         * As a rule of thumb, an application would only want to use the
0027:         * accessible control listener to implement accessibility for a
0028:         * custom control.
0029:         * 
0030:         * @see Control#getAccessible
0031:         * @see AccessibleListener
0032:         * @see AccessibleEvent
0033:         * @see AccessibleControlListener
0034:         * @see AccessibleControlEvent
0035:         * 
0036:         * @since 2.0
0037:         */
0038:        public class Accessible {
0039:            static final String[] requiredAttributes = { OS.kAXRoleAttribute,
0040:                    OS.kAXSubroleAttribute, OS.kAXRoleDescriptionAttribute,
0041:                    OS.kAXHelpAttribute, OS.kAXTitleAttribute,
0042:                    OS.kAXValueAttribute, OS.kAXEnabledAttribute,
0043:                    OS.kAXFocusedAttribute, OS.kAXParentAttribute,
0044:                    OS.kAXChildrenAttribute, OS.kAXSelectedChildrenAttribute,
0045:                    OS.kAXVisibleChildrenAttribute, OS.kAXWindowAttribute,
0046:                    OS.kAXTopLevelUIElementAttribute, OS.kAXPositionAttribute,
0047:                    OS.kAXSizeAttribute, OS.kAXDescriptionAttribute, };
0048:            static final String[] textAttributes = {
0049:                    OS.kAXNumberOfCharactersAttribute,
0050:                    OS.kAXSelectedTextAttribute,
0051:                    OS.kAXSelectedTextRangeAttribute,
0052:                    OS.kAXInsertionPointLineNumberAttribute, };
0053:
0054:            Vector accessibleListeners = new Vector();
0055:            Vector accessibleControlListeners = new Vector();
0056:            Vector accessibleTextListeners = new Vector();
0057:            Control control;
0058:            int axuielementref = 0;
0059:            int[] osChildIDCache = new int[0];
0060:
0061:            Accessible(Control control) {
0062:                this .control = control;
0063:                axuielementref = OS.AXUIElementCreateWithHIObjectAndIdentifier(
0064:                        control.handle, 0);
0065:                OS.HIObjectSetAccessibilityIgnored(control.handle, false);
0066:            }
0067:
0068:            /**
0069:             * Invokes platform specific functionality to allocate a new accessible object.
0070:             * <p>
0071:             * <b>IMPORTANT:</b> This method is <em>not</em> part of the public
0072:             * API for <code>Accessible</code>. It is marked public only so that it
0073:             * can be shared within the packages provided by SWT. It is not
0074:             * available on all platforms, and should never be called from
0075:             * application code.
0076:             * </p>
0077:             *
0078:             * @param control the control to get the accessible object for
0079:             * @return the platform specific accessible object
0080:             */
0081:            public static Accessible internal_new_Accessible(Control control) {
0082:                return new Accessible(control);
0083:            }
0084:
0085:            /**
0086:             * Adds the listener to the collection of listeners who will
0087:             * be notified when an accessible client asks for certain strings,
0088:             * such as name, description, help, or keyboard shortcut. The
0089:             * listener is notified by sending it one of the messages defined
0090:             * in the <code>AccessibleListener</code> interface.
0091:             *
0092:             * @param listener the listener that should be notified when the receiver
0093:             * is asked for a name, description, help, or keyboard shortcut string
0094:             *
0095:             * @exception IllegalArgumentException <ul>
0096:             *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
0097:             * </ul>
0098:             * @exception SWTException <ul>
0099:             *    <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
0100:             *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
0101:             * </ul>
0102:             *
0103:             * @see AccessibleListener
0104:             * @see #removeAccessibleListener
0105:             */
0106:            public void addAccessibleListener(AccessibleListener listener) {
0107:                checkWidget();
0108:                if (listener == null)
0109:                    SWT.error(SWT.ERROR_NULL_ARGUMENT);
0110:                accessibleListeners.addElement(listener);
0111:            }
0112:
0113:            /**
0114:             * Adds the listener to the collection of listeners who will
0115:             * be notified when an accessible client asks for custom control
0116:             * specific information. The listener is notified by sending it
0117:             * one of the messages defined in the <code>AccessibleControlListener</code>
0118:             * interface.
0119:             *
0120:             * @param listener the listener that should be notified when the receiver
0121:             * is asked for custom control specific information
0122:             *
0123:             * @exception IllegalArgumentException <ul>
0124:             *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
0125:             * </ul>
0126:             * @exception SWTException <ul>
0127:             *    <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
0128:             *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
0129:             * </ul>
0130:             *
0131:             * @see AccessibleControlListener
0132:             * @see #removeAccessibleControlListener
0133:             */
0134:            public void addAccessibleControlListener(
0135:                    AccessibleControlListener listener) {
0136:                checkWidget();
0137:                if (listener == null)
0138:                    SWT.error(SWT.ERROR_NULL_ARGUMENT);
0139:                accessibleControlListeners.addElement(listener);
0140:            }
0141:
0142:            /**
0143:             * Adds the listener to the collection of listeners who will
0144:             * be notified when an accessible client asks for custom text control
0145:             * specific information. The listener is notified by sending it
0146:             * one of the messages defined in the <code>AccessibleTextListener</code>
0147:             * interface.
0148:             *
0149:             * @param listener the listener that should be notified when the receiver
0150:             * is asked for custom text control specific information
0151:             *
0152:             * @exception IllegalArgumentException <ul>
0153:             *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
0154:             * </ul>
0155:             * @exception SWTException <ul>
0156:             *    <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
0157:             *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
0158:             * </ul>
0159:             *
0160:             * @see AccessibleTextListener
0161:             * @see #removeAccessibleTextListener
0162:             * 
0163:             * @since 3.0
0164:             */
0165:            public void addAccessibleTextListener(
0166:                    AccessibleTextListener listener) {
0167:                checkWidget();
0168:                if (listener == null)
0169:                    SWT.error(SWT.ERROR_NULL_ARGUMENT);
0170:                accessibleTextListeners.addElement(listener);
0171:            }
0172:
0173:            /**
0174:             * Returns the control for this Accessible object. 
0175:             *
0176:             * @return the receiver's control
0177:             * @since 3.0
0178:             */
0179:            public Control getControl() {
0180:                return control;
0181:            }
0182:
0183:            /**
0184:             * Invokes platform specific functionality to dispose an accessible object.
0185:             * <p>
0186:             * <b>IMPORTANT:</b> This method is <em>not</em> part of the public
0187:             * API for <code>Accessible</code>. It is marked public only so that it
0188:             * can be shared within the packages provided by SWT. It is not
0189:             * available on all platforms, and should never be called from
0190:             * application code.
0191:             * </p>
0192:             */
0193:            public void internal_dispose_Accessible() {
0194:                if (axuielementref != 0) {
0195:                    OS.CFRelease(axuielementref);
0196:                    axuielementref = 0;
0197:                    for (int index = 1; index < osChildIDCache.length; index += 2) {
0198:                        OS.CFRelease(osChildIDCache[index]);
0199:                    }
0200:                    osChildIDCache = new int[0];
0201:                }
0202:            }
0203:
0204:            /**
0205:             * Invokes platform specific functionality to handle a window message.
0206:             * <p>
0207:             * <b>IMPORTANT:</b> This method is <em>not</em> part of the public
0208:             * API for <code>Accessible</code>. It is marked public only so that it
0209:             * can be shared within the packages provided by SWT. It is not
0210:             * available on all platforms, and should never be called from
0211:             * application code.
0212:             * </p>
0213:             */
0214:            public int internal_kEventAccessibleGetChildAtPoint(
0215:                    int nextHandler, int theEvent, int userData) {
0216:                if (axuielementref != 0) {
0217:                    int childID = getChildIDFromEvent(theEvent);
0218:                    CGPoint pt = new CGPoint();
0219:                    OS.GetEventParameter(theEvent, OS.kEventParamMouseLocation,
0220:                            OS.typeHIPoint, null, CGPoint.sizeof, null, pt);
0221:                    AccessibleControlEvent event = new AccessibleControlEvent(
0222:                            this );
0223:                    event.x = (int) pt.x;
0224:                    event.y = (int) pt.y;
0225:                    event.childID = ACC.CHILDID_SELF;
0226:                    for (int i = 0; i < accessibleControlListeners.size(); i++) {
0227:                        AccessibleControlListener listener = (AccessibleControlListener) accessibleControlListeners
0228:                                .elementAt(i);
0229:                        listener.getChildAtPoint(event);
0230:                    }
0231:                    if (event.accessible != null) {
0232:                        OS.SetEventParameter(theEvent,
0233:                                OS.kEventParamAccessibleChild,
0234:                                OS.typeCFTypeRef, 4,
0235:                                new int[] { event.accessible.axuielementref });
0236:                        return OS.noErr;
0237:                    }
0238:                    if (event.childID == ACC.CHILDID_SELF
0239:                            || event.childID == ACC.CHILDID_NONE
0240:                            || event.childID == childID) {
0241:                        /*
0242:                         * From the Carbon doc for kEventAccessibleGetChildAtPoint: "If there is no child at the given point,
0243:                         * you should still return noErr, but leave the parameter empty (do not call SetEventParameter)."
0244:                         */
0245:                        return OS.noErr;
0246:                    }
0247:                    OS.SetEventParameter(theEvent,
0248:                            OS.kEventParamAccessibleChild, OS.typeCFTypeRef, 4,
0249:                            new int[] { childIDToOs(event.childID) });
0250:                    return OS.noErr;
0251:                }
0252:                return OS.eventNotHandledErr;
0253:            }
0254:
0255:            /**
0256:             * Invokes platform specific functionality to handle a window message.
0257:             * <p>
0258:             * <b>IMPORTANT:</b> This method is <em>not</em> part of the public
0259:             * API for <code>Accessible</code>. It is marked public only so that it
0260:             * can be shared within the packages provided by SWT. It is not
0261:             * available on all platforms, and should never be called from
0262:             * application code.
0263:             * </p>
0264:             */
0265:            public int internal_kEventAccessibleGetFocusedChild(
0266:                    int nextHandler, int theEvent, int userData) {
0267:                if (axuielementref != 0) {
0268:                    int childID = getChildIDFromEvent(theEvent);
0269:                    if (childID != ACC.CHILDID_SELF) {
0270:                        /* From the Carbon doc for kEventAccessibleGetFocusedChild: "Only return immediate children;
0271:                         * do not return grandchildren of yourself."
0272:                         */
0273:                        return OS.noErr;
0274:                    }
0275:                    AccessibleControlEvent event = new AccessibleControlEvent(
0276:                            this );
0277:                    event.childID = ACC.CHILDID_MULTIPLE; // set to invalid value, to test if the application sets it in getFocus()
0278:                    event.accessible = null;
0279:                    for (int i = 0; i < accessibleControlListeners.size(); i++) {
0280:                        AccessibleControlListener listener = (AccessibleControlListener) accessibleControlListeners
0281:                                .elementAt(i);
0282:                        listener.getFocus(event);
0283:                    }
0284:
0285:                    /* The application can optionally answer an accessible. */
0286:                    if (event.accessible != null) {
0287:                        OS.SetEventParameter(theEvent,
0288:                                OS.kEventParamAccessibleChild,
0289:                                OS.typeCFTypeRef, 4,
0290:                                new int[] { event.accessible.axuielementref });
0291:                        return OS.noErr;
0292:                    }
0293:
0294:                    /* Or the application can answer a valid child ID, including CHILDID_SELF and CHILDID_NONE. */
0295:                    if (event.childID == ACC.CHILDID_SELF) {
0296:                        OS.SetEventParameter(theEvent,
0297:                                OS.kEventParamAccessibleChild,
0298:                                OS.typeCFTypeRef, 4,
0299:                                new int[] { axuielementref });
0300:                        return OS.noErr;
0301:                    }
0302:                    if (event.childID == ACC.CHILDID_NONE) {
0303:                        /*
0304:                         * From the Carbon doc for kEventAccessibleGetFocusedChild: "If there is no child in the 
0305:                         * focus chain, your handler should leave the kEventParamAccessibleChild parameter empty 
0306:                         * and return noErr."
0307:                         */
0308:                        return OS.noErr;
0309:                    }
0310:                    if (event.childID != ACC.CHILDID_MULTIPLE) {
0311:                        /* Other valid childID. */
0312:                        OS.SetEventParameter(theEvent,
0313:                                OS.kEventParamAccessibleChild,
0314:                                OS.typeCFTypeRef, 4,
0315:                                new int[] { childIDToOs(event.childID) });
0316:                        return OS.noErr;
0317:                    }
0318:
0319:                    /* Invalid childID means the application did not implement getFocus, so return the native focus. */
0320:                    if (control.isFocusControl()) {
0321:                        OS.SetEventParameter(theEvent,
0322:                                OS.kEventParamAccessibleChild,
0323:                                OS.typeCFTypeRef, 4,
0324:                                new int[] { axuielementref });
0325:                        return OS.noErr;
0326:                    }
0327:                }
0328:                return OS.noErr;
0329:            }
0330:
0331:            /**
0332:             * Invokes platform specific functionality to handle a window message.
0333:             * <p>
0334:             * <b>IMPORTANT:</b> This method is <em>not</em> part of the public
0335:             * API for <code>Accessible</code>. It is marked public only so that it
0336:             * can be shared within the packages provided by SWT. It is not
0337:             * available on all platforms, and should never be called from
0338:             * application code.
0339:             * </p>
0340:             */
0341:            public int internal_kEventAccessibleGetNamedAttribute(
0342:                    int nextHandler, int theEvent, int userData) {
0343:                if (axuielementref != 0) {
0344:                    int[] stringRef = new int[1];
0345:                    OS.GetEventParameter(theEvent,
0346:                            OS.kEventParamAccessibleAttributeName,
0347:                            OS.typeCFStringRef, null, 4, null, stringRef);
0348:                    int length = OS.CFStringGetLength(stringRef[0]);
0349:                    char[] buffer = new char[length];
0350:                    CFRange range = new CFRange();
0351:                    range.length = length;
0352:                    OS.CFStringGetCharacters(stringRef[0], range, buffer);
0353:                    String attributeName = new String(buffer);
0354:                    if (attributeName.equals(OS.kAXRoleAttribute))
0355:                        return getRoleAttribute(nextHandler, theEvent, userData);
0356:                    if (attributeName.equals(OS.kAXSubroleAttribute))
0357:                        return getSubroleAttribute(nextHandler, theEvent,
0358:                                userData);
0359:                    if (attributeName.equals(OS.kAXRoleDescriptionAttribute))
0360:                        return getRoleDescriptionAttribute(nextHandler,
0361:                                theEvent, userData);
0362:                    if (attributeName.equals(OS.kAXHelpAttribute))
0363:                        return getHelpAttribute(nextHandler, theEvent, userData);
0364:                    if (attributeName.equals(OS.kAXTitleAttribute))
0365:                        return getTitleAttribute(nextHandler, theEvent,
0366:                                userData);
0367:                    if (attributeName.equals(OS.kAXValueAttribute))
0368:                        return getValueAttribute(nextHandler, theEvent,
0369:                                userData);
0370:                    if (attributeName.equals(OS.kAXEnabledAttribute))
0371:                        return getEnabledAttribute(nextHandler, theEvent,
0372:                                userData);
0373:                    if (attributeName.equals(OS.kAXFocusedAttribute))
0374:                        return getFocusedAttribute(nextHandler, theEvent,
0375:                                userData);
0376:                    //if (attributeName.equals(OS.kAXFocusedUIElementAttribute)) return getFocusedAttribute(nextHandler, theEvent, userData);
0377:                    //if (attributeName.equals(OS.kAXFocusedWindowAttribute)) return getFocusedAttribute(nextHandler, theEvent, userData);
0378:                    if (attributeName.equals(OS.kAXParentAttribute))
0379:                        return getParentAttribute(nextHandler, theEvent,
0380:                                userData);
0381:                    if (attributeName.equals(OS.kAXChildrenAttribute))
0382:                        return getChildrenAttribute(nextHandler, theEvent,
0383:                                userData);
0384:                    if (attributeName.equals(OS.kAXSelectedChildrenAttribute))
0385:                        return getSelectedChildrenAttribute(nextHandler,
0386:                                theEvent, userData);
0387:                    if (attributeName.equals(OS.kAXVisibleChildrenAttribute))
0388:                        return getVisibleChildrenAttribute(nextHandler,
0389:                                theEvent, userData);
0390:                    if (attributeName.equals(OS.kAXWindowAttribute))
0391:                        return getWindowAttribute(nextHandler, theEvent,
0392:                                userData);
0393:                    if (attributeName.equals(OS.kAXTopLevelUIElementAttribute))
0394:                        return getTopLevelUIElementAttribute(nextHandler,
0395:                                theEvent, userData);
0396:                    if (attributeName.equals(OS.kAXPositionAttribute))
0397:                        return getPositionAttribute(nextHandler, theEvent,
0398:                                userData);
0399:                    if (attributeName.equals(OS.kAXSizeAttribute))
0400:                        return getSizeAttribute(nextHandler, theEvent, userData);
0401:                    if (attributeName.equals(OS.kAXDescriptionAttribute))
0402:                        return getDescriptionAttribute(nextHandler, theEvent,
0403:                                userData);
0404:                    if (attributeName.equals(OS.kAXNumberOfCharactersAttribute))
0405:                        return getNumberOfCharactersAttribute(nextHandler,
0406:                                theEvent, userData);
0407:                    if (attributeName.equals(OS.kAXSelectedTextAttribute))
0408:                        return getSelectedTextAttribute(nextHandler, theEvent,
0409:                                userData);
0410:                    if (attributeName.equals(OS.kAXSelectedTextRangeAttribute))
0411:                        return getSelectedTextRangeAttribute(nextHandler,
0412:                                theEvent, userData);
0413:                    if (attributeName
0414:                            .equals(OS.kAXInsertionPointLineNumberAttribute))
0415:                        return getInsertionPointLineNumberAttribute(
0416:                                nextHandler, theEvent, userData);
0417:                    return getAttribute(nextHandler, theEvent, userData);
0418:                }
0419:                return OS.eventNotHandledErr;
0420:            }
0421:
0422:            public int internal_kEventAccessibleGetAllAttributeNames(
0423:                    int nextHandler, int theEvent, int userData) {
0424:                if (axuielementref != 0) {
0425:                    int[] arrayRef = new int[1];
0426:                    OS.GetEventParameter(theEvent,
0427:                            OS.kEventParamAccessibleAttributeNames,
0428:                            OS.typeCFMutableArrayRef, null, 4, null, arrayRef);
0429:                    int stringArrayRef = arrayRef[0];
0430:                    // TODO make sure each attribute name is not a dup before appending?
0431:                    //			int length = OS.CFArrayGetCount(stringArrayRef);
0432:                    //			String [] osAllAttributes = new String [length];
0433:                    //			for (int i = 0; i < length; i++) {
0434:                    //				int stringRef = OS.CFArrayGetValueAtIndex(stringArrayRef, i);
0435:                    //				osAllAttributes[i] = stringRefToString (stringRef);
0436:                    //			}
0437:                    /* Add our list of supported attributes to the array. */
0438:                    for (int i = 0; i < requiredAttributes.length; i++) {
0439:                        int stringRef = stringToStringRef(requiredAttributes[i]);
0440:                        OS.CFArrayAppendValue(stringArrayRef, stringRef);
0441:                        OS.CFRelease(stringRef);
0442:                    }
0443:                    if (accessibleTextListeners.size() > 0) {
0444:                        for (int i = 0; i < textAttributes.length; i++) {
0445:                            int stringRef = stringToStringRef(textAttributes[i]);
0446:                            OS.CFArrayAppendValue(stringArrayRef, stringRef);
0447:                            OS.CFRelease(stringRef);
0448:                        }
0449:                    }
0450:                    return OS.noErr;
0451:                }
0452:                return OS.eventNotHandledErr;
0453:            }
0454:
0455:            int getAttribute(int nextHandler, int theEvent, int userData) {
0456:                int code = OS.CallNextEventHandler(nextHandler, theEvent);
0457:                if (code == OS.eventNotHandledErr) {
0458:                    /* If the childID was created by the application, delegate to the accessible for the control. */
0459:                    OS.SetEventParameter(theEvent,
0460:                            OS.kEventParamAccessibleObject, OS.typeCFTypeRef,
0461:                            4, new int[] { axuielementref });
0462:                    code = OS.CallNextEventHandler(nextHandler, theEvent);
0463:                }
0464:                return code;
0465:            }
0466:
0467:            int getHelpAttribute(int nextHandler, int theEvent, int userData) {
0468:                int code = OS.CallNextEventHandler(nextHandler, theEvent);
0469:                String osHelpAttribute = null;
0470:                int[] stringRef = new int[1];
0471:                if (code == OS.noErr) {
0472:                    OS.GetEventParameter(theEvent,
0473:                            OS.kEventParamAccessibleAttributeValue,
0474:                            OS.typeCFStringRef, null, 4, null, stringRef);
0475:                    osHelpAttribute = stringRefToString(stringRef[0]);
0476:                }
0477:                AccessibleEvent event = new AccessibleEvent(this );
0478:                event.childID = getChildIDFromEvent(theEvent);
0479:                event.result = osHelpAttribute;
0480:                for (int i = 0; i < accessibleListeners.size(); i++) {
0481:                    AccessibleListener listener = (AccessibleListener) accessibleListeners
0482:                            .elementAt(i);
0483:                    listener.getHelp(event);
0484:                }
0485:                if (event.result != null) {
0486:                    stringRef[0] = stringToStringRef(event.result);
0487:                    if (stringRef[0] != 0) {
0488:                        OS.SetEventParameter(theEvent,
0489:                                OS.kEventParamAccessibleAttributeValue,
0490:                                OS.typeCFStringRef, 4, stringRef);
0491:                        OS.CFRelease(stringRef[0]);
0492:                        return OS.noErr;
0493:                    }
0494:                }
0495:                return code;
0496:            }
0497:
0498:            int getRoleAttribute(int nextHandler, int theEvent, int userData) {
0499:                AccessibleControlEvent event = new AccessibleControlEvent(this );
0500:                event.childID = getChildIDFromEvent(theEvent);
0501:                event.detail = -1;
0502:                for (int i = 0; i < accessibleControlListeners.size(); i++) {
0503:                    AccessibleControlListener listener = (AccessibleControlListener) accessibleControlListeners
0504:                            .elementAt(i);
0505:                    listener.getRole(event);
0506:                }
0507:                if (event.detail != -1) {
0508:                    String appRole = roleToOs(event.detail);
0509:                    int index = appRole.indexOf(':');
0510:                    if (index != -1)
0511:                        appRole = appRole.substring(0, index);
0512:                    int stringRef = stringToStringRef(appRole);
0513:                    if (stringRef != 0) {
0514:                        OS.SetEventParameter(theEvent,
0515:                                OS.kEventParamAccessibleAttributeValue,
0516:                                OS.typeCFStringRef, 4, new int[] { stringRef });
0517:                        OS.CFRelease(stringRef);
0518:                        return OS.noErr;
0519:                    }
0520:                }
0521:                return OS.CallNextEventHandler(nextHandler, theEvent);
0522:            }
0523:
0524:            int getSubroleAttribute(int nextHandler, int theEvent, int userData) {
0525:                AccessibleControlEvent event = new AccessibleControlEvent(this );
0526:                event.childID = getChildIDFromEvent(theEvent);
0527:                event.detail = -1;
0528:                for (int i = 0; i < accessibleControlListeners.size(); i++) {
0529:                    AccessibleControlListener listener = (AccessibleControlListener) accessibleControlListeners
0530:                            .elementAt(i);
0531:                    listener.getRole(event);
0532:                }
0533:                if (event.detail != -1) {
0534:                    String appRole = roleToOs(event.detail);
0535:                    int index = appRole.indexOf(':');
0536:                    if (index != -1) {
0537:                        appRole = appRole.substring(index + 1);
0538:                        int stringRef = stringToStringRef(appRole);
0539:                        if (stringRef != 0) {
0540:                            OS.SetEventParameter(theEvent,
0541:                                    OS.kEventParamAccessibleAttributeValue,
0542:                                    OS.typeCFStringRef, 4,
0543:                                    new int[] { stringRef });
0544:                            OS.CFRelease(stringRef);
0545:                        }
0546:                    }
0547:                    return OS.noErr;
0548:                }
0549:                return OS.CallNextEventHandler(nextHandler, theEvent);
0550:            }
0551:
0552:            int getRoleDescriptionAttribute(int nextHandler, int theEvent,
0553:                    int userData) {
0554:                AccessibleControlEvent event = new AccessibleControlEvent(this );
0555:                event.childID = getChildIDFromEvent(theEvent);
0556:                event.detail = -1;
0557:                for (int i = 0; i < accessibleControlListeners.size(); i++) {
0558:                    AccessibleControlListener listener = (AccessibleControlListener) accessibleControlListeners
0559:                            .elementAt(i);
0560:                    listener.getRole(event);
0561:                }
0562:                if (event.detail != -1) {
0563:                    String appRole = roleToOs(event.detail);
0564:                    String appSubrole = null;
0565:                    int index = appRole.indexOf(':');
0566:                    if (index != -1) {
0567:                        appSubrole = appRole.substring(index + 1);
0568:                        appRole = appRole.substring(0, index);
0569:                    }
0570:                    int stringRef1 = stringToStringRef(appRole);
0571:                    if (stringRef1 != 0) {
0572:                        int stringRef2 = 0;
0573:                        if (appSubrole != null)
0574:                            stringRef2 = stringToStringRef(appSubrole);
0575:                        int stringRef3 = OS.HICopyAccessibilityRoleDescription(
0576:                                stringRef1, stringRef2);
0577:                        OS.CFRelease(stringRef1);
0578:                        if (stringRef2 != 0)
0579:                            OS.CFRelease(stringRef2);
0580:                        if (stringRef3 != 0) {
0581:                            OS.SetEventParameter(theEvent,
0582:                                    OS.kEventParamAccessibleAttributeValue,
0583:                                    OS.typeCFStringRef, 4,
0584:                                    new int[] { stringRef3 });
0585:                            OS.CFRelease(stringRef3);
0586:                            return OS.noErr;
0587:                        }
0588:                    }
0589:                }
0590:                return OS.CallNextEventHandler(nextHandler, theEvent);
0591:            }
0592:
0593:            int getTitleAttribute(int nextHandler, int theEvent, int userData) {
0594:                int code = OS.CallNextEventHandler(nextHandler, theEvent);
0595:                String osTitleAttribute = null;
0596:                int[] stringRef = new int[1];
0597:                if (code == OS.noErr) {
0598:                    int status = OS.GetEventParameter(theEvent,
0599:                            OS.kEventParamAccessibleAttributeValue,
0600:                            OS.typeCFStringRef, null, 4, null, stringRef);
0601:                    if (status == OS.noErr) {
0602:                        osTitleAttribute = stringRefToString(stringRef[0]);
0603:                    }
0604:                }
0605:                AccessibleEvent event = new AccessibleEvent(this );
0606:                event.childID = getChildIDFromEvent(theEvent);
0607:                event.result = osTitleAttribute;
0608:                for (int i = 0; i < accessibleListeners.size(); i++) {
0609:                    AccessibleListener listener = (AccessibleListener) accessibleListeners
0610:                            .elementAt(i);
0611:                    listener.getName(event);
0612:                }
0613:                if (event.result != null) {
0614:                    stringRef[0] = stringToStringRef(event.result);
0615:                    if (stringRef[0] != 0) {
0616:                        OS.SetEventParameter(theEvent,
0617:                                OS.kEventParamAccessibleAttributeValue,
0618:                                OS.typeCFStringRef, 4, stringRef);
0619:                        OS.CFRelease(stringRef[0]);
0620:                        return OS.noErr;
0621:                    }
0622:                }
0623:                //return OS.CallNextEventHandler (nextHandler, theEvent);
0624:                return code;
0625:            }
0626:
0627:            int getValueAttribute(int nextHandler, int theEvent, int userData) {
0628:                int code = OS.CallNextEventHandler(nextHandler, theEvent);
0629:                int childID = getChildIDFromEvent(theEvent);
0630:                AccessibleControlEvent event = new AccessibleControlEvent(this );
0631:                event.childID = childID;
0632:                event.detail = -1;
0633:                event.result = null;
0634:                for (int i = 0; i < accessibleControlListeners.size(); i++) {
0635:                    AccessibleControlListener listener = (AccessibleControlListener) accessibleControlListeners
0636:                            .elementAt(i);
0637:                    listener.getRole(event);
0638:                    listener.getValue(event);
0639:                }
0640:                int role = event.detail;
0641:                String value = event.result;
0642:                if (value != null || role == ACC.ROLE_LABEL) {
0643:                    int stringRef = 0;
0644:                    switch (role) {
0645:                    case ACC.ROLE_RADIOBUTTON: // 1 = on, 0 = off
0646:                    case ACC.ROLE_CHECKBUTTON: // 1 = checked, 0 = unchecked, 2 = mixed
0647:                    case ACC.ROLE_SCROLLBAR: // numeric value representing the position of the scroller
0648:                    case ACC.ROLE_TABITEM: // 1 = selected, 0 = not selected
0649:                    case ACC.ROLE_SLIDER: // the value associated with the position of the slider thumb
0650:                    case ACC.ROLE_PROGRESSBAR: // the value associated with the fill level of the progress bar
0651:                        try {
0652:                            int number = Integer.parseInt(value);
0653:                            OS.SetEventParameter(theEvent,
0654:                                    OS.kEventParamAccessibleAttributeValue,
0655:                                    OS.typeSInt32, 4, new int[] { number });
0656:                            return OS.noErr;
0657:                        } catch (NumberFormatException ex) {
0658:                            if (value.equalsIgnoreCase("true")) {
0659:                                OS.SetEventParameter(theEvent,
0660:                                        OS.kEventParamAccessibleAttributeValue,
0661:                                        OS.typeBoolean, 4,
0662:                                        new boolean[] { true });
0663:                                return OS.noErr;
0664:                            }
0665:                            if (value.equalsIgnoreCase("false")) {
0666:                                OS.SetEventParameter(theEvent,
0667:                                        OS.kEventParamAccessibleAttributeValue,
0668:                                        OS.typeBoolean, 4,
0669:                                        new boolean[] { false });
0670:                                return OS.noErr;
0671:                            }
0672:                        }
0673:                        break;
0674:                    case ACC.ROLE_TABFOLDER: // the accessibility object representing the currently selected tab item
0675:                        //break;
0676:                    case ACC.ROLE_COMBOBOX: // text of the currently selected item
0677:                    case ACC.ROLE_TEXT: // text in the text field
0678:                        stringRef = stringToStringRef(value);
0679:                        break;
0680:                    case ACC.ROLE_LABEL: // text in the label
0681:                        /* On a Mac, the 'value' of a label is the same as the 'name' of the label. */
0682:                        AccessibleEvent e = new AccessibleEvent(this );
0683:                        e.childID = childID;
0684:                        e.result = null;
0685:                        for (int i = 0; i < accessibleListeners.size(); i++) {
0686:                            AccessibleListener listener = (AccessibleListener) accessibleListeners
0687:                                    .elementAt(i);
0688:                            listener.getName(e);
0689:                        }
0690:                        if (e.result != null) {
0691:                            stringRef = stringToStringRef(e.result);
0692:                        } else {
0693:                            if (value != null)
0694:                                stringRef = stringToStringRef(value);
0695:                        }
0696:                        break;
0697:                    }
0698:                    if (stringRef != 0) {
0699:                        OS.SetEventParameter(theEvent,
0700:                                OS.kEventParamAccessibleAttributeValue,
0701:                                OS.typeCFStringRef, 4, new int[] { stringRef });
0702:                        OS.CFRelease(stringRef);
0703:                        return OS.noErr;
0704:                    }
0705:                }
0706:                return code;
0707:            }
0708:
0709:            int getEnabledAttribute(int nextHandler, int theEvent, int userData) {
0710:                return getAttribute(nextHandler, theEvent, userData);
0711:            }
0712:
0713:            int getFocusedAttribute(int nextHandler, int theEvent, int userData) {
0714:                int[] osChildID = new int[1];
0715:                OS.GetEventParameter(theEvent, OS.kEventParamAccessibleObject,
0716:                        OS.typeCFTypeRef, null, 4, null, osChildID);
0717:                AccessibleControlEvent event = new AccessibleControlEvent(this );
0718:                event.childID = ACC.CHILDID_MULTIPLE; // set to invalid value, to test if the application sets it in getFocus()
0719:                event.accessible = null;
0720:                for (int i = 0; i < accessibleControlListeners.size(); i++) {
0721:                    AccessibleControlListener listener = (AccessibleControlListener) accessibleControlListeners
0722:                            .elementAt(i);
0723:                    listener.getFocus(event);
0724:                }
0725:
0726:                /* The application can optionally answer an accessible. */
0727:                if (event.accessible != null) {
0728:                    boolean hasFocus = OS.CFEqual(
0729:                            event.accessible.axuielementref, osChildID[0]);
0730:                    OS.SetEventParameter(theEvent,
0731:                            OS.kEventParamAccessibleAttributeValue,
0732:                            OS.typeBoolean, 4, new boolean[] { hasFocus });
0733:                    return OS.noErr;
0734:                }
0735:
0736:                /* Or the application can answer a valid child ID, including CHILDID_SELF and CHILDID_NONE. */
0737:                if (event.childID == ACC.CHILDID_SELF) {
0738:                    boolean hasFocus = OS.CFEqual(axuielementref, osChildID[0]);
0739:                    OS.SetEventParameter(theEvent,
0740:                            OS.kEventParamAccessibleAttributeValue,
0741:                            OS.typeBoolean, 4, new boolean[] { hasFocus });
0742:                    return OS.noErr;
0743:                }
0744:                if (event.childID == ACC.CHILDID_NONE) {
0745:                    OS.SetEventParameter(theEvent,
0746:                            OS.kEventParamAccessibleAttributeValue,
0747:                            OS.typeBoolean, 4, new boolean[] { false });
0748:                    return OS.noErr;
0749:                }
0750:                if (event.childID != ACC.CHILDID_MULTIPLE) {
0751:                    /* Other valid childID. */
0752:                    int childID = osToChildID(osChildID[0]);
0753:                    OS.SetEventParameter(theEvent,
0754:                            OS.kEventParamAccessibleAttributeValue,
0755:                            OS.typeBoolean, 4,
0756:                            new boolean[] { event.childID == childID });
0757:                    return OS.noErr;
0758:                }
0759:
0760:                /* Invalid childID means the application did not implement getFocus, so return the native focus. */
0761:                if (OS.CFEqual(axuielementref, osChildID[0])) {
0762:                    boolean hasFocus = control.isFocusControl();
0763:                    OS.SetEventParameter(theEvent,
0764:                            OS.kEventParamAccessibleAttributeValue,
0765:                            OS.typeBoolean, 4, new boolean[] { hasFocus });
0766:                    return OS.noErr;
0767:                }
0768:                return OS.CallNextEventHandler(nextHandler, theEvent);
0769:            }
0770:
0771:            int getParentAttribute(int nextHandler, int theEvent, int userData) {
0772:                int code = OS.CallNextEventHandler(nextHandler, theEvent);
0773:                if (code == OS.eventNotHandledErr) {
0774:                    /* If the childID was created by the application, the parent is the accessible for the control. */
0775:                    // TODO: typeCFTypeRef?... should be AXUIElementRef
0776:                    OS.SetEventParameter(theEvent,
0777:                            OS.kEventParamAccessibleAttributeValue,
0778:                            OS.typeCFTypeRef, 4, new int[] { axuielementref });
0779:                    return OS.noErr;
0780:                }
0781:                return code;
0782:            }
0783:
0784:            int getChildrenAttribute(int nextHandler, int theEvent, int userData) {
0785:                int childID = getChildIDFromEvent(theEvent);
0786:                if (childID == ACC.CHILDID_SELF) {
0787:                    AccessibleControlEvent event = new AccessibleControlEvent(
0788:                            this );
0789:                    event.childID = childID;
0790:                    for (int i = 0; i < accessibleControlListeners.size(); i++) {
0791:                        AccessibleControlListener listener = (AccessibleControlListener) accessibleControlListeners
0792:                                .elementAt(i);
0793:                        listener.getChildren(event);
0794:                    }
0795:                    Object[] appChildren = event.children;
0796:                    if (appChildren != null && appChildren.length > 0) {
0797:                        /* return a CFArrayRef of AXUIElementRefs */
0798:                        int children = OS.CFArrayCreateMutable(
0799:                                OS.kCFAllocatorDefault, 0, 0);
0800:                        if (children != 0) {
0801:                            for (int i = 0; i < appChildren.length; i++) {
0802:                                Object child = appChildren[i];
0803:                                if (child instanceof  Integer) {
0804:                                    OS.CFArrayAppendValue(children,
0805:                                            childIDToOs(((Integer) child)
0806:                                                    .intValue()));
0807:                                } else {
0808:                                    OS
0809:                                            .CFArrayAppendValue(
0810:                                                    children,
0811:                                                    ((Accessible) child).axuielementref);
0812:                                }
0813:                            }
0814:                            OS.SetEventParameter(theEvent,
0815:                                    OS.kEventParamAccessibleAttributeValue,
0816:                                    OS.typeCFMutableArrayRef, 4,
0817:                                    new int[] { children });
0818:                            OS.CFRelease(children);
0819:                            return OS.noErr;
0820:                        }
0821:                    }
0822:                }
0823:                return OS.CallNextEventHandler(nextHandler, theEvent);
0824:            }
0825:
0826:            int getSelectedChildrenAttribute(int nextHandler, int theEvent,
0827:                    int userData) {
0828:                return getAttribute(nextHandler, theEvent, userData);
0829:            }
0830:
0831:            int getVisibleChildrenAttribute(int nextHandler, int theEvent,
0832:                    int userData) {
0833:                return getAttribute(nextHandler, theEvent, userData);
0834:            }
0835:
0836:            int getWindowAttribute(int nextHandler, int theEvent, int userData) {
0837:                return getAttribute(nextHandler, theEvent, userData);
0838:            }
0839:
0840:            int getTopLevelUIElementAttribute(int nextHandler, int theEvent,
0841:                    int userData) {
0842:                return getAttribute(nextHandler, theEvent, userData);
0843:            }
0844:
0845:            int getPositionAttribute(int nextHandler, int theEvent, int userData) {
0846:                int code = OS.CallNextEventHandler(nextHandler, theEvent);
0847:                CGPoint osPositionAttribute = new CGPoint();
0848:                if (code == OS.noErr) {
0849:                    OS.GetEventParameter(theEvent, OS.kEventParamMouseLocation,
0850:                            OS.typeHIPoint, null, CGPoint.sizeof, null,
0851:                            osPositionAttribute);
0852:                }
0853:                AccessibleControlEvent event = new AccessibleControlEvent(this );
0854:                event.childID = getChildIDFromEvent(theEvent);
0855:                event.x = (int) osPositionAttribute.x;
0856:                event.y = (int) osPositionAttribute.y;
0857:                for (int i = 0; i < accessibleControlListeners.size(); i++) {
0858:                    AccessibleControlListener listener = (AccessibleControlListener) accessibleControlListeners
0859:                            .elementAt(i);
0860:                    listener.getLocation(event);
0861:                }
0862:                osPositionAttribute.x = event.x;
0863:                osPositionAttribute.y = event.y;
0864:                OS.SetEventParameter(theEvent,
0865:                        OS.kEventParamAccessibleAttributeValue, OS.typeHIPoint,
0866:                        CGPoint.sizeof, osPositionAttribute);
0867:                return OS.noErr;
0868:            }
0869:
0870:            int getSizeAttribute(int nextHandler, int theEvent, int userData) {
0871:                int code = OS.CallNextEventHandler(nextHandler, theEvent);
0872:                CGPoint osSizeAttribute = new CGPoint();
0873:                if (code == OS.noErr) {
0874:                    OS.GetEventParameter(theEvent, OS.kEventParamMouseLocation,
0875:                            OS.typeHISize, null, CGPoint.sizeof, null,
0876:                            osSizeAttribute);
0877:                }
0878:                AccessibleControlEvent event = new AccessibleControlEvent(this );
0879:                event.childID = getChildIDFromEvent(theEvent);
0880:                event.width = (int) osSizeAttribute.x;
0881:                event.height = (int) osSizeAttribute.y;
0882:                for (int i = 0; i < accessibleControlListeners.size(); i++) {
0883:                    AccessibleControlListener listener = (AccessibleControlListener) accessibleControlListeners
0884:                            .elementAt(i);
0885:                    listener.getLocation(event);
0886:                }
0887:                osSizeAttribute.x = event.width;
0888:                osSizeAttribute.y = event.height;
0889:                OS.SetEventParameter(theEvent,
0890:                        OS.kEventParamAccessibleAttributeValue, OS.typeHISize,
0891:                        CGPoint.sizeof, osSizeAttribute);
0892:                return OS.noErr;
0893:            }
0894:
0895:            int getDescriptionAttribute(int nextHandler, int theEvent,
0896:                    int userData) {
0897:                return getAttribute(nextHandler, theEvent, userData);
0898:            }
0899:
0900:            int getNumberOfCharactersAttribute(int nextHandler, int theEvent,
0901:                    int userData) {
0902:                AccessibleControlEvent event = new AccessibleControlEvent(this );
0903:                event.childID = getChildIDFromEvent(theEvent);
0904:                event.result = null;
0905:                for (int i = 0; i < accessibleControlListeners.size(); i++) {
0906:                    AccessibleControlListener listener = (AccessibleControlListener) accessibleControlListeners
0907:                            .elementAt(i);
0908:                    listener.getValue(event);
0909:                }
0910:                String appValue = event.result;
0911:                if (appValue != null) {
0912:                    OS.SetEventParameter(theEvent,
0913:                            OS.kEventParamAccessibleAttributeValue,
0914:                            OS.typeSInt32, 4, new int[] { appValue.length() });
0915:                    return OS.noErr;
0916:                }
0917:                return OS.CallNextEventHandler(nextHandler, theEvent);
0918:            }
0919:
0920:            int getSelectedTextAttribute(int nextHandler, int theEvent,
0921:                    int userData) {
0922:                AccessibleTextEvent event = new AccessibleTextEvent(this );
0923:                event.childID = getChildIDFromEvent(theEvent);
0924:                event.offset = -1;
0925:                event.length = -1;
0926:                for (int i = 0; i < accessibleTextListeners.size(); i++) {
0927:                    AccessibleTextListener listener = (AccessibleTextListener) accessibleTextListeners
0928:                            .elementAt(i);
0929:                    listener.getSelectionRange(event);
0930:                }
0931:                int offset = event.offset;
0932:                int length = event.length;
0933:                if (offset != -1 && length != -1 && length != 0) { // TODO: do we need the && length != 0 ?
0934:                    AccessibleControlEvent event2 = new AccessibleControlEvent(
0935:                            this );
0936:                    event2.childID = event.childID;
0937:                    event2.result = null;
0938:                    for (int i = 0; i < accessibleControlListeners.size(); i++) {
0939:                        AccessibleControlListener listener = (AccessibleControlListener) accessibleControlListeners
0940:                                .elementAt(i);
0941:                        listener.getValue(event2);
0942:                    }
0943:                    String appValue = event2.result;
0944:                    if (appValue != null) {
0945:                        int stringRef = stringToStringRef(appValue.substring(
0946:                                offset, offset + length));
0947:                        if (stringRef != 0) {
0948:                            OS.SetEventParameter(theEvent,
0949:                                    OS.kEventParamAccessibleAttributeValue,
0950:                                    OS.typeCFStringRef, 4,
0951:                                    new int[] { stringRef });
0952:                            OS.CFRelease(stringRef);
0953:                            return OS.noErr;
0954:                        }
0955:                    }
0956:                }
0957:                return OS.CallNextEventHandler(nextHandler, theEvent);
0958:            }
0959:
0960:            int getSelectedTextRangeAttribute(int nextHandler, int theEvent,
0961:                    int userData) {
0962:                AccessibleTextEvent event = new AccessibleTextEvent(this );
0963:                event.childID = getChildIDFromEvent(theEvent);
0964:                event.offset = -1;
0965:                event.length = -1;
0966:                for (int i = 0; i < accessibleTextListeners.size(); i++) {
0967:                    AccessibleTextListener listener = (AccessibleTextListener) accessibleTextListeners
0968:                            .elementAt(i);
0969:                    listener.getSelectionRange(event);
0970:                }
0971:                if (event.offset != -1) {
0972:                    CFRange range = new CFRange();
0973:                    range.location = event.offset;
0974:                    range.length = event.length;
0975:                    int valueRef = OS.AXValueCreate(OS.kAXValueCFRangeType,
0976:                            range);
0977:                    OS.SetEventParameter(theEvent,
0978:                            OS.kEventParamAccessibleAttributeValue,
0979:                            OS.typeCFTypeRef, 4, new int[] { valueRef });
0980:                    OS.CFRelease(valueRef);
0981:                    return OS.noErr;
0982:                }
0983:                return OS.CallNextEventHandler(nextHandler, theEvent);
0984:            }
0985:
0986:            int getInsertionPointLineNumberAttribute(int nextHandler,
0987:                    int theEvent, int userData) {
0988:                AccessibleTextEvent event = new AccessibleTextEvent(this );
0989:                event.childID = getChildIDFromEvent(theEvent);
0990:                event.offset = -1;
0991:                for (int i = 0; i < accessibleTextListeners.size(); i++) {
0992:                    AccessibleTextListener listener = (AccessibleTextListener) accessibleTextListeners
0993:                            .elementAt(i);
0994:                    listener.getCaretOffset(event);
0995:                }
0996:                if (event.offset != -1) {
0997:                    OS.SetEventParameter(theEvent,
0998:                            OS.kEventParamAccessibleAttributeValue,
0999:                            OS.typeSInt32, 4, new int[] { event.offset });
1000:                    return OS.noErr;
1001:                }
1002:                return OS.CallNextEventHandler(nextHandler, theEvent);
1003:            }
1004:
1005:            /**
1006:             * Removes the listener from the collection of listeners who will
1007:             * be notified when an accessible client asks for certain strings,
1008:             * such as name, description, help, or keyboard shortcut.
1009:             *
1010:             * @param listener the listener that should no longer be notified when the receiver
1011:             * is asked for a name, description, help, or keyboard shortcut string
1012:             *
1013:             * @exception IllegalArgumentException <ul>
1014:             *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
1015:             * </ul>
1016:             * @exception SWTException <ul>
1017:             *    <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
1018:             *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
1019:             * </ul>
1020:             *
1021:             * @see AccessibleListener
1022:             * @see #addAccessibleListener
1023:             */
1024:            public void removeAccessibleListener(AccessibleListener listener) {
1025:                checkWidget();
1026:                if (listener == null)
1027:                    SWT.error(SWT.ERROR_NULL_ARGUMENT);
1028:                accessibleListeners.removeElement(listener);
1029:            }
1030:
1031:            /**
1032:             * Removes the listener from the collection of listeners who will
1033:             * be notified when an accessible client asks for custom control
1034:             * specific information.
1035:             *
1036:             * @param listener the listener that should no longer be notified when the receiver
1037:             * is asked for custom control specific information
1038:             *
1039:             * @exception IllegalArgumentException <ul>
1040:             *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
1041:             * </ul>
1042:             * @exception SWTException <ul>
1043:             *    <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
1044:             *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
1045:             * </ul>
1046:             *
1047:             * @see AccessibleControlListener
1048:             * @see #addAccessibleControlListener
1049:             */
1050:            public void removeAccessibleControlListener(
1051:                    AccessibleControlListener listener) {
1052:                checkWidget();
1053:                if (listener == null)
1054:                    SWT.error(SWT.ERROR_NULL_ARGUMENT);
1055:                accessibleControlListeners.removeElement(listener);
1056:            }
1057:
1058:            /**
1059:             * Removes the listener from the collection of listeners who will
1060:             * be notified when an accessible client asks for custom text control
1061:             * specific information.
1062:             *
1063:             * @param listener the listener that should no longer be notified when the receiver
1064:             * is asked for custom text control specific information
1065:             *
1066:             * @exception IllegalArgumentException <ul>
1067:             *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
1068:             * </ul>
1069:             * @exception SWTException <ul>
1070:             *    <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
1071:             *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
1072:             * </ul>
1073:             *
1074:             * @see AccessibleTextListener
1075:             * @see #addAccessibleTextListener
1076:             * 
1077:             * @since 3.0
1078:             */
1079:            public void removeAccessibleTextListener(
1080:                    AccessibleTextListener listener) {
1081:                checkWidget();
1082:                if (listener == null)
1083:                    SWT.error(SWT.ERROR_NULL_ARGUMENT);
1084:                accessibleTextListeners.removeElement(listener);
1085:            }
1086:
1087:            /**
1088:             * Sends a message to accessible clients that the child selection
1089:             * within a custom container control has changed.
1090:             *
1091:             * @exception SWTException <ul>
1092:             *    <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
1093:             *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
1094:             * </ul>
1095:             * 
1096:             * @since 3.0
1097:             */
1098:            public void selectionChanged() {
1099:                checkWidget();
1100:                int stringRef = stringToStringRef(OS.kAXSelectedChildrenChangedNotification);
1101:                OS.AXNotificationHIObjectNotify(stringRef, control.handle, 0);
1102:                OS.CFRelease(stringRef);
1103:            }
1104:
1105:            /**
1106:             * Sends a message to accessible clients indicating that the focus
1107:             * has changed within a custom control.
1108:             *
1109:             * @param childID an identifier specifying a child of the control
1110:             * 
1111:             * @exception SWTException <ul>
1112:             *    <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
1113:             *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
1114:             * </ul>
1115:             */
1116:            public void setFocus(int childID) {
1117:                checkWidget();
1118:                childIDToOs(childID); // Make sure the childID is cached
1119:                int stringRef = stringToStringRef(OS.kAXFocusedUIElementChangedNotification);
1120:                OS.AXNotificationHIObjectNotify(stringRef, control.handle, 0);
1121:                OS.CFRelease(stringRef);
1122:            }
1123:
1124:            /**
1125:             * Sends a message to accessible clients that the text
1126:             * caret has moved within a custom control.
1127:             *
1128:             * @param index the new caret index within the control
1129:             * 
1130:             * @exception SWTException <ul>
1131:             *    <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
1132:             *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
1133:             * </ul>
1134:             *
1135:             * @since 3.0
1136:             */
1137:            public void textCaretMoved(int index) {
1138:                checkWidget();
1139:                // TODO: Look at this in more depth
1140:                int stringRef = stringToStringRef(OS.kAXValueChangedNotification);
1141:                OS.AXNotificationHIObjectNotify(stringRef, control.handle, 0);
1142:                OS.CFRelease(stringRef);
1143:            }
1144:
1145:            /**
1146:             * Sends a message to accessible clients that the text
1147:             * within a custom control has changed.
1148:             *
1149:             * @param type the type of change, one of <code>ACC.NOTIFY_TEXT_INSERT</code>
1150:             * or <code>ACC.NOTIFY_TEXT_DELETE</code>
1151:             * @param startIndex the text index within the control where the insertion or deletion begins
1152:             * @param length the non-negative length in characters of the insertion or deletion
1153:             *
1154:             * @exception SWTException <ul>
1155:             *    <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
1156:             *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
1157:             * </ul>
1158:             * 
1159:             * @see ACC#TEXT_INSERT
1160:             * @see ACC#TEXT_DELETE
1161:             * 
1162:             * @since 3.0
1163:             */
1164:            public void textChanged(int type, int startIndex, int length) {
1165:                checkWidget();
1166:                // TODO: Look at this in more depth
1167:                int stringRef = stringToStringRef(OS.kAXValueChangedNotification);
1168:                OS.AXNotificationHIObjectNotify(stringRef, control.handle, 0);
1169:                OS.CFRelease(stringRef);
1170:            }
1171:
1172:            /**
1173:             * Sends a message to accessible clients that the text
1174:             * selection has changed within a custom control.
1175:             *
1176:             * @exception SWTException <ul>
1177:             *    <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
1178:             *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
1179:             * </ul>
1180:             *
1181:             * @since 3.0
1182:             */
1183:            public void textSelectionChanged() {
1184:                checkWidget();
1185:                int stringRef = stringToStringRef(OS.kAXSelectedChildrenChangedNotification);
1186:                OS.AXNotificationHIObjectNotify(stringRef, control.handle, 0);
1187:                OS.CFRelease(stringRef);
1188:            }
1189:
1190:            int getChildIDFromEvent(int theEvent) {
1191:                int[] ref = new int[1];
1192:                OS.GetEventParameter(theEvent, OS.kEventParamAccessibleObject,
1193:                        OS.typeCFTypeRef, null, 4, null, ref);
1194:                return osToChildID(ref[0]);
1195:            }
1196:
1197:            int childIDToOs(int childID) {
1198:                if (childID == ACC.CHILDID_SELF) {
1199:                    return axuielementref;
1200:                }
1201:                /* Check cache for childID, if found, return corresponding osChildID. */
1202:                int index;
1203:                for (index = 0; index < osChildIDCache.length; index += 2) {
1204:                    if (childID == osChildIDCache[index]) {
1205:                        return osChildIDCache[index + 1];
1206:                    }
1207:                }
1208:                /* If childID not in cache, create osChildID, grow cache by 2,
1209:                 * add childID/osChildID to cache, and return new osChildID. */
1210:                int osChildID = OS.AXUIElementCreateWithHIObjectAndIdentifier(
1211:                        control.handle, childID + 1);
1212:                int[] newCache = new int[osChildIDCache.length + 2];
1213:                System.arraycopy(osChildIDCache, 0, newCache, 0,
1214:                        osChildIDCache.length);
1215:                osChildIDCache = newCache;
1216:                osChildIDCache[index] = childID;
1217:                osChildIDCache[index + 1] = osChildID;
1218:                return osChildID;
1219:            }
1220:
1221:            int osToChildID(int osChildID) {
1222:                if (OS.CFEqual(osChildID, axuielementref)) {
1223:                    return ACC.CHILDID_SELF;
1224:                }
1225:
1226:                /* osChildID is an AXUIElementRef containing the control handle and a long identifier. */
1227:                long[] childID = new long[1];
1228:                OS.AXUIElementGetIdentifier(osChildID, childID);
1229:                if (childID[0] == 0) {
1230:                    return ACC.CHILDID_SELF;
1231:                }
1232:                return (int) childID[0] - 1;
1233:            }
1234:
1235:            int stateToOs(int state) {
1236:                //		int osState = 0;
1237:                //		if ((state & ACC.STATE_SELECTED) != 0) osState |= OS.;
1238:                //		return osState;
1239:                return state;
1240:            }
1241:
1242:            int osToState(int osState) {
1243:                //		int state = ACC.STATE_NORMAL;
1244:                //		if ((osState & OS.) != 0) state |= ACC.STATE_SELECTED;
1245:                //		return state;
1246:                return osState;
1247:            }
1248:
1249:            String roleToOs(int role) {
1250:                switch (role) {
1251:                case ACC.ROLE_CLIENT_AREA:
1252:                    return OS.kAXWindowRole;
1253:                case ACC.ROLE_WINDOW:
1254:                    return OS.kAXWindowRole;
1255:                case ACC.ROLE_MENUBAR:
1256:                    return OS.kAXMenuBarRole;
1257:                case ACC.ROLE_MENU:
1258:                    return OS.kAXMenuRole;
1259:                case ACC.ROLE_MENUITEM:
1260:                    return OS.kAXMenuItemRole;
1261:                case ACC.ROLE_SEPARATOR:
1262:                    return OS.kAXSplitterRole;
1263:                case ACC.ROLE_TOOLTIP:
1264:                    return OS.kAXHelpTagRole;
1265:                case ACC.ROLE_SCROLLBAR:
1266:                    return OS.kAXScrollBarRole;
1267:                case ACC.ROLE_DIALOG:
1268:                    return OS.kAXWindowRole + ':' + OS.kAXDialogSubrole;
1269:                case ACC.ROLE_LABEL:
1270:                    return OS.kAXStaticTextRole;
1271:                case ACC.ROLE_PUSHBUTTON:
1272:                    return OS.kAXButtonRole;
1273:                case ACC.ROLE_CHECKBUTTON:
1274:                    return OS.kAXCheckBoxRole;
1275:                case ACC.ROLE_RADIOBUTTON:
1276:                    return OS.kAXRadioButtonRole;
1277:                case ACC.ROLE_COMBOBOX:
1278:                    return OS.kAXComboBoxRole;
1279:                case ACC.ROLE_TEXT:
1280:                    return OS.kAXTextFieldRole;
1281:                case ACC.ROLE_TOOLBAR:
1282:                    return OS.kAXToolbarRole;
1283:                case ACC.ROLE_LIST:
1284:                    return OS.kAXOutlineRole;
1285:                case ACC.ROLE_LISTITEM:
1286:                    return OS.kAXStaticTextRole;
1287:                case ACC.ROLE_TABLE:
1288:                    return OS.kAXTableRole;
1289:                case ACC.ROLE_TABLECELL:
1290:                    return OS.kAXRowRole + ':' + OS.kAXTableRowSubrole;
1291:                case ACC.ROLE_TABLECOLUMNHEADER:
1292:                    return OS.kAXButtonRole + ':' + OS.kAXSortButtonSubrole;
1293:                case ACC.ROLE_TABLEROWHEADER:
1294:                    return OS.kAXRowRole + ':' + OS.kAXTableRowSubrole;
1295:                case ACC.ROLE_TREE:
1296:                    return OS.kAXOutlineRole;
1297:                case ACC.ROLE_TREEITEM:
1298:                    return OS.kAXOutlineRole + ':' + OS.kAXOutlineRowSubrole;
1299:                case ACC.ROLE_TABFOLDER:
1300:                    return OS.kAXTabGroupRole;
1301:                case ACC.ROLE_TABITEM:
1302:                    return OS.kAXRadioButtonRole;
1303:                case ACC.ROLE_PROGRESSBAR:
1304:                    return OS.kAXProgressIndicatorRole;
1305:                case ACC.ROLE_SLIDER:
1306:                    return OS.kAXSliderRole;
1307:                case ACC.ROLE_LINK:
1308:                    return OS.kAXLinkRole;
1309:                }
1310:                return OS.kAXUnknownRole;
1311:            }
1312:
1313:            int osToRole(String osRole) {
1314:                if (osRole == null)
1315:                    return 0;
1316:                if (osRole.equals(OS.kAXWindowRole))
1317:                    return ACC.ROLE_WINDOW;
1318:                if (osRole.equals(OS.kAXMenuBarRole))
1319:                    return ACC.ROLE_MENUBAR;
1320:                if (osRole.equals(OS.kAXMenuRole))
1321:                    return ACC.ROLE_MENU;
1322:                if (osRole.equals(OS.kAXMenuItemRole))
1323:                    return ACC.ROLE_MENUITEM;
1324:                if (osRole.equals(OS.kAXSplitterRole))
1325:                    return ACC.ROLE_SEPARATOR;
1326:                if (osRole.equals(OS.kAXHelpTagRole))
1327:                    return ACC.ROLE_TOOLTIP;
1328:                if (osRole.equals(OS.kAXScrollBarRole))
1329:                    return ACC.ROLE_SCROLLBAR;
1330:                if (osRole.equals(OS.kAXScrollAreaRole))
1331:                    return ACC.ROLE_LIST;
1332:                if (osRole.equals(OS.kAXWindowRole + ':' + OS.kAXDialogSubrole))
1333:                    return ACC.ROLE_DIALOG;
1334:                if (osRole.equals(OS.kAXWindowRole + ':'
1335:                        + OS.kAXSystemDialogSubrole))
1336:                    return ACC.ROLE_DIALOG;
1337:                if (osRole.equals(OS.kAXStaticTextRole))
1338:                    return ACC.ROLE_LABEL;
1339:                if (osRole.equals(OS.kAXButtonRole))
1340:                    return ACC.ROLE_PUSHBUTTON;
1341:                if (osRole.equals(OS.kAXCheckBoxRole))
1342:                    return ACC.ROLE_CHECKBUTTON;
1343:                if (osRole.equals(OS.kAXRadioButtonRole))
1344:                    return ACC.ROLE_RADIOBUTTON;
1345:                if (osRole.equals(OS.kAXComboBoxRole))
1346:                    return ACC.ROLE_COMBOBOX;
1347:                if (osRole.equals(OS.kAXTextFieldRole))
1348:                    return ACC.ROLE_TEXT;
1349:                if (osRole.equals(OS.kAXTextAreaRole))
1350:                    return ACC.ROLE_TEXT;
1351:                if (osRole.equals(OS.kAXToolbarRole))
1352:                    return ACC.ROLE_TOOLBAR;
1353:                if (osRole.equals(OS.kAXListRole))
1354:                    return ACC.ROLE_LIST;
1355:                if (osRole.equals(OS.kAXTableRole))
1356:                    return ACC.ROLE_TABLE;
1357:                if (osRole.equals(OS.kAXColumnRole))
1358:                    return ACC.ROLE_TABLECOLUMNHEADER;
1359:                if (osRole.equals(OS.kAXButtonRole + ':'
1360:                        + OS.kAXSortButtonSubrole))
1361:                    return ACC.ROLE_TABLECOLUMNHEADER;
1362:                if (osRole.equals(OS.kAXRowRole + ':' + OS.kAXTableRowSubrole))
1363:                    return ACC.ROLE_TABLEROWHEADER;
1364:                if (osRole.equals(OS.kAXOutlineRole))
1365:                    return ACC.ROLE_TREE;
1366:                if (osRole.equals(OS.kAXOutlineRole + ':'
1367:                        + OS.kAXOutlineRowSubrole))
1368:                    return ACC.ROLE_TREEITEM;
1369:                if (osRole.equals(OS.kAXTabGroupRole))
1370:                    return ACC.ROLE_TABFOLDER;
1371:                if (osRole.equals(OS.kAXProgressIndicatorRole))
1372:                    return ACC.ROLE_PROGRESSBAR;
1373:                if (osRole.equals(OS.kAXSliderRole))
1374:                    return ACC.ROLE_SLIDER;
1375:                if (osRole.equals(OS.kAXLinkRole))
1376:                    return ACC.ROLE_LINK;
1377:                return ACC.ROLE_CLIENT_AREA;
1378:            }
1379:
1380:            /* Return a CFStringRef representing the given java String.
1381:             * Note that the caller is responsible for calling OS.CFRelease
1382:             * when they are done with the stringRef.
1383:             */
1384:            int stringToStringRef(String string) {
1385:                char[] buffer = new char[string.length()];
1386:                string.getChars(0, buffer.length, buffer, 0);
1387:                return OS.CFStringCreateWithCharacters(OS.kCFAllocatorDefault,
1388:                        buffer, buffer.length);
1389:            }
1390:
1391:            /* Return a Java String representing the given CFStringRef.
1392:             * Note that this method does not call OS.CFRelease(stringRef).
1393:             */
1394:            String stringRefToString(int stringRef) {
1395:                int length = OS.CFStringGetLength(stringRef);
1396:                char[] buffer = new char[length];
1397:                CFRange range = new CFRange();
1398:                range.length = length;
1399:                OS.CFStringGetCharacters(stringRef, range, buffer);
1400:                return new String(buffer);
1401:            }
1402:
1403:            /* checkWidget was copied from Widget, and rewritten to work in this package */
1404:            void checkWidget() {
1405:                if (!isValidThread())
1406:                    SWT.error(SWT.ERROR_THREAD_INVALID_ACCESS);
1407:                if (control.isDisposed())
1408:                    SWT.error(SWT.ERROR_WIDGET_DISPOSED);
1409:            }
1410:
1411:            /* isValidThread was copied from Widget, and rewritten to work in this package */
1412:            boolean isValidThread() {
1413:                return control.getDisplay().getThread() == Thread
1414:                        .currentThread();
1415:            }
1416:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.