1 /*******************************************************************************
2 * Copyright (c) 2000, 2017 IBM Corporation and others.
4 * This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License 2.0
6 * which accompanies this distribution, and is available at
7 * https://www.eclipse.org/legal/epl-2.0/
9 * SPDX-License-Identifier: EPL-2.0
12 * IBM Corporation - initial API and implementation
13 *******************************************************************************/
14 package org.eclipse.swt.accessibility;
17 import java.util.List;
19 import org.eclipse.swt.*;
20 import org.eclipse.swt.graphics.*;
21 import org.eclipse.swt.internal.*;
22 import org.eclipse.swt.internal.ole.win32.*;
23 import org.eclipse.swt.internal.win32.*;
24 import org.eclipse.swt.ole.win32.*;
25 import org.eclipse.swt.widgets.*;
28 * Instances of this class provide a bridge between application
29 * code and assistive technology clients. Many platforms provide
30 * default accessible behavior for most widgets, and this class
31 * allows that default behavior to be overridden. Applications
32 * can get the default Accessible object for a control by sending
33 * it <code>getAccessible</code>, and then add an accessible listener
34 * to override simple items like the name and help string, or they
35 * can add an accessible control listener to override complex items.
36 * As a rule of thumb, an application would only want to use the
37 * accessible control listener to implement accessibility for a
40 * @see Control#getAccessible
41 * @see AccessibleListener
42 * @see AccessibleEvent
43 * @see AccessibleControlListener
44 * @see AccessibleControlEvent
45 * @see <a href="http://www.eclipse.org/swt/snippets/#accessibility">Accessibility snippets</a>
46 * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
50 public class Accessible {
51 static final int MAX_RELATION_TYPES = 15;
52 static final int TABLE_MODEL_CHANGE_SIZE = 5;
53 static final int TEXT_CHANGE_SIZE = 4;
54 static final int SCROLL_RATE = 100;
55 static final boolean DEBUG = false;
56 static final String PROPERTY_USEIA2 = "org.eclipse.swt.accessibility.UseIA2"; //$NON-NLS-1$
57 static boolean UseIA2 = true;
58 static int UniqueID = -0x10;
59 int refCount = 0, enumIndex = 0;
61 COMObject objIAccessible, objIEnumVARIANT, objIServiceProvider,
62 objIAccessibleApplication, /*objIAccessibleComponent,*/ objIAccessibleEditableText, objIAccessibleHyperlink,
63 objIAccessibleHypertext, /*objIAccessibleImage,*/ objIAccessibleTable2, objIAccessibleTableCell,
64 objIAccessibleValue; /* objIAccessibleRelation is defined in Relation class */
65 IAccessible iaccessible;
66 List<AccessibleListener> accessibleListeners;
67 List<AccessibleControlListener> accessibleControlListeners;
68 List<AccessibleTextListener> accessibleTextListeners;
69 List<AccessibleActionListener> accessibleActionListeners;
70 List<AccessibleEditableTextListener> accessibleEditableTextListeners;
71 List<AccessibleHyperlinkListener> accessibleHyperlinkListeners;
72 List<AccessibleTableListener> accessibleTableListeners;
73 List<AccessibleTableCellListener> accessibleTableCellListeners;
74 List<AccessibleTextExtendedListener> accessibleTextExtendedListeners;
75 List<AccessibleValueListener> accessibleValueListeners;
76 List<AccessibleAttributeListener> accessibleAttributeListeners;
77 Relation relations[] = new Relation[MAX_RELATION_TYPES];
80 List<Accessible> children = new ArrayList<>();
83 int [] tableChange; // type, rowStart, rowCount, columnStart, columnCount
84 Object [] textDeleted; // type, start, end, text
85 Object [] textInserted; // type, start, end, text
89 String property = System.getProperty (PROPERTY_USEIA2);
90 if (property != null && property.equalsIgnoreCase ("false")) { //$NON-NLS-1$
96 * Constructs a new instance of this class given its parent.
98 * @param parent the Accessible parent, which must not be null
100 * @exception IllegalArgumentException <ul>
101 * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
105 * @see Control#getAccessible
109 public Accessible(Accessible parent) {
110 this.parent = checkNull(parent);
111 this.control = parent.control;
112 parent.children.add(this);
121 protected Accessible() {
124 Accessible(Control control) {
125 this.control = control;
126 long[] ppvObject = new long[1];
127 /* CreateStdAccessibleObject([in] hwnd, [in] idObject, [in] riidInterface, [out] ppvObject).
128 * AddRef has already been called on ppvObject by the callee and must be released by the caller.
130 int result = (int)COM.CreateStdAccessibleObject(control.handle, OS.OBJID_CLIENT, COM.IIDIAccessible, ppvObject);
131 /* The object needs to be checked, because if the CreateStdAccessibleObject()
132 * symbol is not found, the return value is S_OK.
134 if (ppvObject[0] == 0) return;
135 if (result != COM.S_OK) OLE.error(OLE.ERROR_CANNOT_CREATE_OBJECT, result);
136 iaccessible = new IAccessible(ppvObject[0]);
141 Accessible(Accessible parent, long iaccessible_address) {
143 iaccessible = new IAccessible(iaccessible_address);
146 static Accessible checkNull (Accessible parent) {
147 if (parent == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
151 void createIAccessible() {
152 objIAccessible = new COMObject(new int[] {2,0,0,/*IA>>*/1,3,5,8,1,1,2,2,2,2,2,2,2,3,2,1,1,2,2,5,3,3,1,2,2,/*<<IA*/1,2,3,1,1,3,3,1,1,1,1,3,3,1,1,1,1,1}) {
154 public long method0(long[] args) {return QueryInterface(args[0], args[1]);}
156 public long method1(long[] args) {return AddRef();}
158 public long method2(long[] args) {return Release();}
159 // method3 GetTypeInfoCount - not implemented
160 // method4 GetTypeInfo - not implemented
161 // method5 GetIDsOfNames - not implemented
162 // method6 Invoke - not implemented
164 public long method7(long[] args) {return get_accParent(args[0]);}
166 public long method8(long[] args) {return get_accChildCount(args[0]);}
168 public long method9(long[] args) {return get_accChild(args[0], args[1]);}
170 public long method10(long[] args) {return get_accName(args[0], args[1]);}
172 public long method11(long[] args) {return get_accValue(args[0], args[1]);}
174 public long method12(long[] args) {return get_accDescription(args[0], args[1]);}
176 public long method13(long[] args) {return get_accRole(args[0], args[1]);}
178 public long method14(long[] args) {return get_accState(args[0], args[1]);}
180 public long method15(long[] args) {return get_accHelp(args[0], args[1]);}
182 public long method16(long[] args) {return get_accHelpTopic(args[0], args[1], args[2]);}
184 public long method17(long[] args) {return get_accKeyboardShortcut(args[0], args[1]);}
186 public long method18(long[] args) {return get_accFocus(args[0]);}
188 public long method19(long[] args) {return get_accSelection(args[0]);}
190 public long method20(long[] args) {return get_accDefaultAction(args[0], args[1]);}
192 public long method21(long[] args) {return accSelect((int)args[0], args[1]);}
194 public long method22(long[] args) {return accLocation(args[0], args[1], args[2], args[3], args[4]);}
196 public long method23(long[] args) {return accNavigate((int)args[0], args[1], args[2]);}
198 public long method24(long[] args) {return accHitTest((int)args[0], (int)args[1], args[2]);}
200 public long method25(long[] args) {return accDoDefaultAction(args[0]);}
202 public long method26(long[] args) {return put_accName(args[0], args[1]);}
204 public long method27(long[] args) {return put_accValue(args[0], args[1]);}
206 // IAccessible2 methods
208 public long method28(long[] args) {return get_nRelations(args[0]);}
210 public long method29(long[] args) {return get_relation((int)args[0], args[1]);}
212 public long method30(long[] args) {return get_relations((int)args[0], args[1], args[2]);}
214 public long method31(long[] args) {return get_role(args[0]);}
216 public long method32(long[] args) {return scrollTo((int)args[0]);}
218 public long method33(long[] args) {return scrollToPoint((int)args[0], (int)args[1], (int)args[2]);}
220 public long method34(long[] args) {return get_groupPosition(args[0], args[1], args[2]);}
222 public long method35(long[] args) {return get_states(args[0]);}
224 public long method36(long[] args) {return get_extendedRole(args[0]);}
226 public long method37(long[] args) {return get_localizedExtendedRole(args[0]);}
228 public long method38(long[] args) {return get_nExtendedStates(args[0]);}
230 public long method39(long[] args) {return get_extendedStates((int)args[0], args[1], args[2]);}
232 public long method40(long[] args) {return get_localizedExtendedStates((int)args[0], args[1], args[2]);}
234 public long method41(long[] args) {return get_uniqueID(args[0]);}
236 public long method42(long[] args) {return get_windowHandle(args[0]);}
238 public long method43(long[] args) {return get_indexInParent(args[0]);}
240 public long method44(long[] args) {return get_locale(args[0]);}
242 public long method45(long[] args) {return get_attributes(args[0]);}
246 void createIAccessibleApplication() {
247 objIAccessibleApplication = new COMObject(new int[] {2,0,0,1,1,1,1}) {
249 public long method0(long[] args) {return QueryInterface(args[0], args[1]);}
251 public long method1(long[] args) {return AddRef();}
253 public long method2(long[] args) {return Release();}
255 public long method3(long[] args) {return get_appName(args[0]);}
257 public long method4(long[] args) {return get_appVersion(args[0]);}
259 public long method5(long[] args) {return get_toolkitName(args[0]);}
261 public long method6(long[] args) {return get_toolkitVersion(args[0]);}
265 // This method is intentionally commented. We are not providing IAccessibleComponent at this time.
266 // void createIAccessibleComponent() {
267 // objIAccessibleComponent = new COMObject(new int[] {2,0,0,2,1,1}) {
268 // public long method0(long[] args) {return QueryInterface(args[0], args[1]);}
269 // public long method1(long[] args) {return AddRef();}
270 // public long method2(long[] args) {return Release();}
271 // public long method3(long[] args) {return get_locationInParent(args[0], args[1]);}
272 // public long method4(long[] args) {return get_foreground(args[0]);}
273 // public long method5(long[] args) {return get_background(args[0]);}
277 void createIAccessibleEditableText() {
278 objIAccessibleEditableText = new COMObject(new int[] {2,0,0,2,2,2,2,1,3,3}) {
280 public long method0(long[] args) {return QueryInterface(args[0], args[1]);}
282 public long method1(long[] args) {return AddRef();}
284 public long method2(long[] args) {return Release();}
286 public long method3(long[] args) {return copyText((int)args[0], (int)args[1]);}
288 public long method4(long[] args) {return deleteText((int)args[0], (int)args[1]);}
290 public long method5(long[] args) {return insertText((int)args[0], args[1]);}
292 public long method6(long[] args) {return cutText((int)args[0], (int)args[1]);}
294 public long method7(long[] args) {return pasteText((int)args[0]);}
296 public long method8(long[] args) {return replaceText((int)args[0], (int)args[1], args[2]);}
298 public long method9(long[] args) {return setAttributes((int)args[0], (int)args[1], args[2]);}
302 void createIAccessibleHyperlink() {
303 objIAccessibleHyperlink = new COMObject(new int[] {2,0,0,/*IAA>>*/1,1,2,4,2,2,/*<<IAA*/2,2,1,1,1}) {
305 public long method0(long[] args) {return QueryInterface(args[0], args[1]);}
307 public long method1(long[] args) {return AddRef();}
309 public long method2(long[] args) {return Release();}
312 public long method3(long[] args) {return get_nActions(args[0]);}
314 public long method4(long[] args) {return doAction((int)args[0]);}
316 public long method5(long[] args) {return get_description((int)args[0], args[1]);}
318 public long method6(long[] args) {return get_keyBinding((int)args[0], (int)args[1], args[2], args[3]);}
320 public long method7(long[] args) {return get_name((int)args[0], args[1]);}
322 public long method8(long[] args) {return get_localizedName((int)args[0], args[1]);}
323 // IAccessibleHyperlink
325 public long method9(long[] args) {return get_anchor((int)args[0], args[1]);}
327 public long method10(long[] args) {return get_anchorTarget((int)args[0], args[1]);}
329 public long method11(long[] args) {return get_startIndex(args[0]);}
331 public long method12(long[] args) {return get_endIndex(args[0]);}
333 public long method13(long[] args) {return get_valid(args[0]);}
337 void createIAccessibleHypertext() {
338 objIAccessibleHypertext = new COMObject(new int[] {2,0,0,/*IAT>>*/2,4,1,6,1,4,3,3,5,5,5,1,1,3,1,3,5,1,1,/*<<IAT*/1,2,2}) {
340 public long method0(long[] args) {return QueryInterface(args[0], args[1]);}
342 public long method1(long[] args) {return AddRef();}
344 public long method2(long[] args) {return Release();}
347 public long method3(long[] args) {return addSelection((int)args[0], (int)args[1]);}
349 public long method4(long[] args) {return get_attributes((int)args[0], args[1], args[2], args[3]);}
351 public long method5(long[] args) {return get_caretOffset(args[0]);}
353 public long method6(long[] args) {return get_characterExtents((int)args[0], (int)args[1], args[2], args[3], args[4], args[5]);}
355 public long method7(long[] args) {return get_nSelections(args[0]);}
357 public long method8(long[] args) {return get_offsetAtPoint((int)args[0], (int)args[1], (int)args[2], args[3]);}
359 public long method9(long[] args) {return get_selection((int)args[0], args[1], args[2]);}
361 public long method10(long[] args) {return get_text((int)args[0], (int)args[1], args[2]);}
363 public long method11(long[] args) {return get_textBeforeOffset((int)args[0], (int)args[1], args[2], args[3], args[4]);}
365 public long method12(long[] args) {return get_textAfterOffset((int)args[0], (int)args[1], args[2], args[3], args[4]);}
367 public long method13(long[] args) {return get_textAtOffset((int)args[0], (int)args[1], args[2], args[3], args[4]);}
369 public long method14(long[] args) {return removeSelection((int)args[0]);}
371 public long method15(long[] args) {return setCaretOffset((int)args[0]);}
373 public long method16(long[] args) {return setSelection((int)args[0], (int)args[1], (int)args[2]);}
375 public long method17(long[] args) {return get_nCharacters(args[0]);}
377 public long method18(long[] args) {return scrollSubstringTo((int)args[0], (int)args[1], (int)args[2]);}
379 public long method19(long[] args) {return scrollSubstringToPoint((int)args[0], (int)args[1], (int)args[2], (int)args[3], (int)args[4]);}
381 public long method20(long[] args) {return get_newText(args[0]);}
383 public long method21(long[] args) {return get_oldText(args[0]);}
384 // IAccessibleHypertext
386 public long method22(long[] args) {return get_nHyperlinks(args[0]);}
388 public long method23(long[] args) {return get_hyperlink((int)args[0], args[1]);}
390 public long method24(long[] args) {return get_hyperlinkIndex((int)args[0], args[1]);}
394 // This method is intentionally commented. We are not providing IAccessibleImage at this time.
395 // void createIAccessibleImage() {
396 // objIAccessibleImage = new COMObject(new int[] {2,0,0,1,3,2}) {
397 // public long method0(long[] args) {return QueryInterface(args[0], args[1]);}
398 // public long method1(long[] args) {return AddRef();}
399 // public long method2(long[] args) {return Release();}
400 // public long method3(long[] args) {return get_description(args[0]);}
401 // public long method4(long[] args) {return get_imagePosition((int)args[0], args[1], args[2]);}
402 // public long method5(long[] args) {return get_imageSize(args[0], args[1]);}
406 void createIAccessibleTable2() {
407 objIAccessibleTable2 = new COMObject(new int[] {2,0,0,3,1,2,1,1,1,1,1,2,2,2,2,1,2,2,1,1,1,1,1}) {
409 public long method0(long[] args) {return QueryInterface(args[0], args[1]);}
411 public long method1(long[] args) {return AddRef();}
413 public long method2(long[] args) {return Release();}
415 public long method3(long[] args) {return get_cellAt((int)args[0], (int)args[1], args[2]);}
417 public long method4(long[] args) {return get_caption(args[0]);}
419 public long method5(long[] args) {return get_columnDescription((int)args[0], args[1]);}
421 public long method6(long[] args) {return get_nColumns(args[0]);}
423 public long method7(long[] args) {return get_nRows(args[0]);}
425 public long method8(long[] args) {return get_nSelectedCells(args[0]);}
427 public long method9(long[] args) {return get_nSelectedColumns(args[0]);}
429 public long method10(long[] args) {return get_nSelectedRows(args[0]);}
431 public long method11(long[] args) {return get_rowDescription((int)args[0], args[1]);}
433 public long method12(long[] args) {return get_selectedCells(args[0], args[1]);}
435 public long method13(long[] args) {return get_selectedColumns(args[0], args[1]);}
437 public long method14(long[] args) {return get_selectedRows(args[0], args[1]);}
439 public long method15(long[] args) {return get_summary(args[0]);}
441 public long method16(long[] args) {return get_isColumnSelected((int)args[0], args[1]);}
443 public long method17(long[] args) {return get_isRowSelected((int)args[0], args[1]);}
445 public long method18(long[] args) {return selectRow((int)args[0]);}
447 public long method19(long[] args) {return selectColumn((int)args[0]);}
449 public long method20(long[] args) {return unselectRow((int)args[0]);}
451 public long method21(long[] args) {return unselectColumn((int)args[0]);}
453 public long method22(long[] args) {return get_modelChange(args[0]);}
457 void createIAccessibleTableCell() {
458 objIAccessibleTableCell = new COMObject(new int[] {2,0,0,1,2,1,1,2,1,1,5,1}) {
460 public long method0(long[] args) {return QueryInterface(args[0], args[1]);}
462 public long method1(long[] args) {return AddRef();}
464 public long method2(long[] args) {return Release();}
466 public long method3(long[] args) {return get_columnExtent(args[0]);}
468 public long method4(long[] args) {return get_columnHeaderCells(args[0], args[1]);}
470 public long method5(long[] args) {return get_columnIndex(args[0]);}
472 public long method6(long[] args) {return get_rowExtent(args[0]);}
474 public long method7(long[] args) {return get_rowHeaderCells(args[0], args[1]);}
476 public long method8(long[] args) {return get_rowIndex(args[0]);}
478 public long method9(long[] args) {return get_isSelected(args[0]);}
480 public long method10(long[] args) {return get_rowColumnExtents(args[0], args[1], args[2], args[3], args[4]);}
482 public long method11(long[] args) {return get_table(args[0]);}
486 void createIAccessibleValue() {
487 objIAccessibleValue = new COMObject(new int[] {2,0,0,1,1,1,1}) {
489 public long method0(long[] args) {return QueryInterface(args[0], args[1]);}
491 public long method1(long[] args) {return AddRef();}
493 public long method2(long[] args) {return Release();}
495 public long method3(long[] args) {return get_currentValue(args[0]);}
497 public long method4(long[] args) {return setCurrentValue(args[0]);}
499 public long method5(long[] args) {return get_maximumValue(args[0]);}
501 public long method6(long[] args) {return get_minimumValue(args[0]);}
505 void createIEnumVARIANT() {
506 objIEnumVARIANT = new COMObject(new int[] {2,0,0,3,1,0,1}) {
508 public long method0(long[] args) {return QueryInterface(args[0], args[1]);}
510 public long method1(long[] args) {return AddRef();}
512 public long method2(long[] args) {return Release();}
514 public long method3(long[] args) {return Next((int)args[0], args[1], args[2]);}
516 public long method4(long[] args) {return Skip((int)args[0]);}
518 public long method5(long[] args) {return Reset();}
520 public long method6(long[] args) {return Clone(args[0]);}
524 void createIServiceProvider() {
525 objIServiceProvider = new COMObject(new int[] {2,0,0,3}) {
527 public long method0(long[] args) {return QueryInterface(args[0], args[1]);}
529 public long method1(long[] args) {return AddRef();}
531 public long method2(long[] args) {return Release();}
533 public long method3(long[] args) {return QueryService(args[0], args[1], args[2]);}
538 * Invokes platform specific functionality to allocate a new accessible object.
540 * <b>IMPORTANT:</b> This method is <em>not</em> part of the public
541 * API for <code>Accessible</code>. It is marked public only so that it
542 * can be shared within the packages provided by SWT. It is not
543 * available on all platforms, and should never be called from
547 * @param control the control to get the accessible object for
548 * @return the platform specific accessible object
550 * @noreference This method is not intended to be referenced by clients.
552 public static Accessible internal_new_Accessible(Control control) {
553 return new Accessible(control);
557 * Adds the listener to the collection of listeners who will
558 * be notified when an accessible client asks for certain strings,
559 * such as name, description, help, or keyboard shortcut. The
560 * listener is notified by sending it one of the messages defined
561 * in the <code>AccessibleListener</code> interface.
563 * @param listener the listener that should be notified when the receiver
564 * is asked for a name, description, help, or keyboard shortcut string
566 * @exception IllegalArgumentException <ul>
567 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
569 * @exception SWTException <ul>
570 * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
571 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
574 * @see AccessibleListener
575 * @see #removeAccessibleListener
577 public void addAccessibleListener(AccessibleListener listener) {
579 if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
580 if (accessibleListeners == null) accessibleListeners = new ArrayList<>();
581 accessibleListeners.add(listener);
585 * Adds the listener to the collection of listeners who will
586 * be notified when an accessible client asks for custom control
587 * specific information. The listener is notified by sending it
588 * one of the messages defined in the <code>AccessibleControlListener</code>
591 * @param listener the listener that should be notified when the receiver
592 * is asked for custom control specific information
594 * @exception IllegalArgumentException <ul>
595 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
597 * @exception SWTException <ul>
598 * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
599 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
602 * @see AccessibleControlListener
603 * @see #removeAccessibleControlListener
605 public void addAccessibleControlListener(AccessibleControlListener listener) {
607 if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
608 if (accessibleControlListeners == null) accessibleControlListeners = new ArrayList<>();
609 accessibleControlListeners.add(listener);
613 * Adds the listener to the collection of listeners who will
614 * be notified when an accessible client asks for custom text control
615 * specific information. The listener is notified by sending it
616 * one of the messages defined in the <code>AccessibleTextListener</code>
617 * and <code>AccessibleTextExtendedListener</code> interfaces.
619 * @param listener the listener that should be notified when the receiver
620 * is asked for custom text control specific information
622 * @exception IllegalArgumentException <ul>
623 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
625 * @exception SWTException <ul>
626 * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
627 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
630 * @see AccessibleTextListener
631 * @see AccessibleTextExtendedListener
632 * @see #removeAccessibleTextListener
636 public void addAccessibleTextListener (AccessibleTextListener listener) {
638 if (listener == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
639 if (listener instanceof AccessibleTextExtendedListener) {
640 if (accessibleTextExtendedListeners == null) accessibleTextExtendedListeners = new ArrayList<>();
641 accessibleTextExtendedListeners.add ((AccessibleTextExtendedListener) listener);
643 if (accessibleTextListeners == null) accessibleTextListeners = new ArrayList<>();
644 accessibleTextListeners.add (listener);
649 * Adds the listener to the collection of listeners that will be
650 * notified when an accessible client asks for any of the properties
651 * defined in the <code>AccessibleActionListener</code> interface.
653 * @param listener the listener that should be notified when the receiver
654 * is asked for <code>AccessibleActionListener</code> interface properties
656 * @exception IllegalArgumentException <ul>
657 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
659 * @exception SWTException <ul>
660 * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
661 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
664 * @see AccessibleActionListener
665 * @see #removeAccessibleActionListener
669 public void addAccessibleActionListener(AccessibleActionListener listener) {
671 if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
672 if (accessibleActionListeners == null) accessibleActionListeners = new ArrayList<>();
673 accessibleActionListeners.add(listener);
677 * Adds the listener to the collection of listeners that will be
678 * notified when an accessible client asks for any of the properties
679 * defined in the <code>AccessibleEditableTextListener</code> interface.
681 * @param listener the listener that should be notified when the receiver
682 * is asked for <code>AccessibleEditableTextListener</code> interface properties
684 * @exception IllegalArgumentException <ul>
685 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
687 * @exception SWTException <ul>
688 * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
689 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
692 * @see AccessibleEditableTextListener
693 * @see #removeAccessibleEditableTextListener
697 public void addAccessibleEditableTextListener(AccessibleEditableTextListener listener) {
699 if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
700 if (accessibleEditableTextListeners == null) accessibleEditableTextListeners = new ArrayList<>();
701 accessibleEditableTextListeners.add(listener);
705 * Adds the listener to the collection of listeners that will be
706 * notified when an accessible client asks for any of the properties
707 * defined in the <code>AccessibleHyperlinkListener</code> interface.
709 * @param listener the listener that should be notified when the receiver
710 * is asked for <code>AccessibleHyperlinkListener</code> interface properties
712 * @exception IllegalArgumentException <ul>
713 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
715 * @exception SWTException <ul>
716 * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
717 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
720 * @see AccessibleHyperlinkListener
721 * @see #removeAccessibleHyperlinkListener
725 public void addAccessibleHyperlinkListener(AccessibleHyperlinkListener listener) {
727 if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
728 if (accessibleHyperlinkListeners == null) accessibleHyperlinkListeners = new ArrayList<>();
729 accessibleHyperlinkListeners.add(listener);
733 * Adds the listener to the collection of listeners that will be
734 * notified when an accessible client asks for any of the properties
735 * defined in the <code>AccessibleTableListener</code> interface.
737 * @param listener the listener that should be notified when the receiver
738 * is asked for <code>AccessibleTableListener</code> interface properties
740 * @exception IllegalArgumentException <ul>
741 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
743 * @exception SWTException <ul>
744 * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
745 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
748 * @see AccessibleTableListener
749 * @see #removeAccessibleTableListener
753 public void addAccessibleTableListener(AccessibleTableListener listener) {
755 if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
756 if (accessibleTableListeners == null) accessibleTableListeners = new ArrayList<>();
757 accessibleTableListeners.add(listener);
761 * Adds the listener to the collection of listeners that will be
762 * notified when an accessible client asks for any of the properties
763 * defined in the <code>AccessibleTableCellListener</code> interface.
765 * @param listener the listener that should be notified when the receiver
766 * is asked for <code>AccessibleTableCellListener</code> interface properties
768 * @exception IllegalArgumentException <ul>
769 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
771 * @exception SWTException <ul>
772 * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
773 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
776 * @see AccessibleTableCellListener
777 * @see #removeAccessibleTableCellListener
781 public void addAccessibleTableCellListener(AccessibleTableCellListener listener) {
783 if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
784 if (accessibleTableCellListeners == null) accessibleTableCellListeners = new ArrayList<>();
785 accessibleTableCellListeners.add(listener);
789 * Adds the listener to the collection of listeners that will be
790 * notified when an accessible client asks for any of the properties
791 * defined in the <code>AccessibleValueListener</code> interface.
793 * @param listener the listener that should be notified when the receiver
794 * is asked for <code>AccessibleValueListener</code> interface properties
796 * @exception IllegalArgumentException <ul>
797 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
799 * @exception SWTException <ul>
800 * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
801 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
804 * @see AccessibleValueListener
805 * @see #removeAccessibleValueListener
809 public void addAccessibleValueListener(AccessibleValueListener listener) {
811 if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
812 if (accessibleValueListeners == null) accessibleValueListeners = new ArrayList<>();
813 accessibleValueListeners.add(listener);
817 * Adds the listener to the collection of listeners that will be
818 * notified when an accessible client asks for any of the properties
819 * defined in the <code>AccessibleAttributeListener</code> interface.
821 * @param listener the listener that should be notified when the receiver
822 * is asked for <code>AccessibleAttributeListener</code> interface properties
824 * @exception IllegalArgumentException <ul>
825 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
827 * @exception SWTException <ul>
828 * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
829 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
832 * @see AccessibleAttributeListener
833 * @see #removeAccessibleAttributeListener
837 public void addAccessibleAttributeListener(AccessibleAttributeListener listener) {
839 if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
840 if (accessibleAttributeListeners == null) accessibleAttributeListeners = new ArrayList<>();
841 accessibleAttributeListeners.add(listener);
845 * Adds a relation with the specified type and target
846 * to the receiver's set of relations.
848 * @param type an <code>ACC</code> constant beginning with RELATION_* indicating the type of relation
849 * @param target the accessible that is the target for this relation
850 * @exception IllegalArgumentException ERROR_NULL_ARGUMENT - if the Accessible target is null
853 public void addRelation(int type, Accessible target) {
855 if (target == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
856 if (relations[type] == null) {
857 relations[type] = new Relation(this, type);
859 relations[type].addTarget(target);
863 * Disposes of the operating system resources associated with
864 * the receiver, and removes the receiver from its parent's
867 * This method should be called when an accessible that was created
868 * with the public constructor <code>Accessible(Accessible parent)</code>
869 * is no longer needed. You do not need to call this when the receiver's
870 * control is disposed, because all <code>Accessible</code> instances
871 * associated with a control are released when the control is disposed.
872 * It is also not necessary to call this for instances of <code>Accessible</code>
873 * that were retrieved with <code>Control.getAccessible()</code>.
878 public void dispose () {
879 if (parent == null) return;
881 parent.children.remove(this);
886 /* The address of an Accessible is the address of its IAccessible COMObject. */
887 if (objIAccessible == null) createIAccessible();
888 return objIAccessible.getAddress();
892 * Returns the control for this Accessible object.
894 * @return the receiver's control
897 public Control getControl() {
902 * Invokes platform specific functionality to dispose an accessible object.
904 * <b>IMPORTANT:</b> This method is <em>not</em> part of the public
905 * API for <code>Accessible</code>. It is marked public only so that it
906 * can be shared within the packages provided by SWT. It is not
907 * available on all platforms, and should never be called from
911 * @noreference This method is not intended to be referenced by clients.
913 public void internal_dispose_Accessible() {
914 if (iaccessible != null) {
915 iaccessible.Release();
919 for (int i = 0; i < children.size(); i++) {
920 Accessible child = children.get(i);
926 * Invokes platform specific functionality to handle a window message.
928 * <b>IMPORTANT:</b> This method is <em>not</em> part of the public
929 * API for <code>Accessible</code>. It is marked public only so that it
930 * can be shared within the packages provided by SWT. It is not
931 * available on all platforms, and should never be called from
935 * @noreference This method is not intended to be referenced by clients.
937 public long internal_WM_GETOBJECT (long wParam, long lParam) {
938 if (objIAccessible == null) return 0;
939 if ((int)lParam == OS.OBJID_CLIENT) {
940 /* LresultFromObject([in] riid, [in] wParam, [in] pAcc)
941 * The argument pAcc is owned by the caller so reference count does not
942 * need to be incremented.
944 return COM.LresultFromObject(COM.IIDIAccessible, wParam, objIAccessible.getAddress());
950 * Removes the listener from the collection of listeners who will
951 * be notified when an accessible client asks for certain strings,
952 * such as name, description, help, or keyboard shortcut.
954 * @param listener the listener that should no longer be notified when the receiver
955 * is asked for a name, description, help, or keyboard shortcut string
957 * @exception IllegalArgumentException <ul>
958 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
960 * @exception SWTException <ul>
961 * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
962 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
965 * @see AccessibleListener
966 * @see #addAccessibleListener
968 public void removeAccessibleListener(AccessibleListener listener) {
970 if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
971 if (accessibleListeners != null) {
972 accessibleListeners.remove(listener);
973 if (accessibleListeners.isEmpty()) accessibleListeners = null;
978 * Removes the listener from the collection of listeners who will
979 * be notified when an accessible client asks for custom control
980 * specific information.
982 * @param listener the listener that should no longer be notified when the receiver
983 * is asked for custom control specific information
985 * @exception IllegalArgumentException <ul>
986 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
988 * @exception SWTException <ul>
989 * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
990 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
993 * @see AccessibleControlListener
994 * @see #addAccessibleControlListener
996 public void removeAccessibleControlListener(AccessibleControlListener listener) {
998 if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
999 if (accessibleControlListeners != null) {
1000 accessibleControlListeners.remove(listener);
1001 if (accessibleControlListeners.isEmpty()) accessibleControlListeners = null;
1006 * Removes the listener from the collection of listeners who will
1007 * be notified when an accessible client asks for custom text control
1008 * specific information.
1010 * @param listener the listener that should no longer be notified when the receiver
1011 * is asked for custom text control specific information
1013 * @exception IllegalArgumentException <ul>
1014 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
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>
1021 * @see AccessibleTextListener
1022 * @see AccessibleTextExtendedListener
1023 * @see #addAccessibleTextListener
1027 public void removeAccessibleTextListener (AccessibleTextListener listener) {
1029 if (listener == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
1030 if (listener instanceof AccessibleTextExtendedListener) {
1031 if (accessibleTextExtendedListeners != null) {
1032 accessibleTextExtendedListeners.remove (listener);
1033 if (accessibleTextExtendedListeners.isEmpty()) accessibleTextExtendedListeners = null;
1036 if (accessibleTextListeners != null) {
1037 accessibleTextListeners.remove (listener);
1038 if (accessibleTextListeners.isEmpty()) accessibleTextListeners = null;
1044 * Removes the listener from the collection of listeners that will be
1045 * notified when an accessible client asks for any of the properties
1046 * defined in the <code>AccessibleActionListener</code> interface.
1048 * @param listener the listener that should no longer be notified when the receiver
1049 * is asked for <code>AccessibleActionListener</code> interface properties
1051 * @exception IllegalArgumentException <ul>
1052 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
1054 * @exception SWTException <ul>
1055 * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
1056 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
1059 * @see AccessibleActionListener
1060 * @see #addAccessibleActionListener
1064 public void removeAccessibleActionListener(AccessibleActionListener listener) {
1066 if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
1067 if (accessibleActionListeners != null) {
1068 accessibleActionListeners.remove(listener);
1069 if (accessibleActionListeners.isEmpty()) accessibleActionListeners = null;
1074 * Removes the listener from the collection of listeners that will be
1075 * notified when an accessible client asks for any of the properties
1076 * defined in the <code>AccessibleEditableTextListener</code> interface.
1078 * @param listener the listener that should no longer be notified when the receiver
1079 * is asked for <code>AccessibleEditableTextListener</code> interface properties
1081 * @exception IllegalArgumentException <ul>
1082 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
1084 * @exception SWTException <ul>
1085 * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
1086 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
1089 * @see AccessibleEditableTextListener
1090 * @see #addAccessibleEditableTextListener
1094 public void removeAccessibleEditableTextListener(AccessibleEditableTextListener listener) {
1096 if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
1097 if (accessibleEditableTextListeners != null) {
1098 accessibleEditableTextListeners.remove(listener);
1099 if (accessibleEditableTextListeners.isEmpty()) accessibleEditableTextListeners = null;
1104 * Removes the listener from the collection of listeners that will be
1105 * notified when an accessible client asks for any of the properties
1106 * defined in the <code>AccessibleHyperlinkListener</code> interface.
1108 * @param listener the listener that should no longer be notified when the receiver
1109 * is asked for <code>AccessibleHyperlinkListener</code> interface properties
1111 * @exception IllegalArgumentException <ul>
1112 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
1114 * @exception SWTException <ul>
1115 * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
1116 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
1119 * @see AccessibleHyperlinkListener
1120 * @see #addAccessibleHyperlinkListener
1124 public void removeAccessibleHyperlinkListener(AccessibleHyperlinkListener listener) {
1126 if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
1127 if (accessibleHyperlinkListeners != null) {
1128 accessibleHyperlinkListeners.remove(listener);
1129 if (accessibleHyperlinkListeners.isEmpty()) accessibleHyperlinkListeners = null;
1134 * Removes the listener from the collection of listeners that will be
1135 * notified when an accessible client asks for any of the properties
1136 * defined in the <code>AccessibleTableListener</code> interface.
1138 * @param listener the listener that should no longer be notified when the receiver
1139 * is asked for <code>AccessibleTableListener</code> interface properties
1141 * @exception IllegalArgumentException <ul>
1142 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
1144 * @exception SWTException <ul>
1145 * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
1146 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
1149 * @see AccessibleTableListener
1150 * @see #addAccessibleTableListener
1154 public void removeAccessibleTableListener(AccessibleTableListener listener) {
1156 if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
1157 if (accessibleTableListeners != null) {
1158 accessibleTableListeners.remove(listener);
1159 if (accessibleTableListeners.isEmpty()) accessibleTableListeners = null;
1164 * Removes the listener from the collection of listeners that will be
1165 * notified when an accessible client asks for any of the properties
1166 * defined in the <code>AccessibleTableCellListener</code> interface.
1168 * @param listener the listener that should no longer be notified when the receiver
1169 * is asked for <code>AccessibleTableCellListener</code> interface properties
1171 * @exception IllegalArgumentException <ul>
1172 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
1174 * @exception SWTException <ul>
1175 * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
1176 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
1179 * @see AccessibleTableCellListener
1180 * @see #addAccessibleTableCellListener
1184 public void removeAccessibleTableCellListener(AccessibleTableCellListener listener) {
1186 if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
1187 if (accessibleTableCellListeners != null) {
1188 accessibleTableCellListeners.remove(listener);
1189 if (accessibleTableCellListeners.isEmpty()) accessibleTableCellListeners = null;
1194 * Removes the listener from the collection of listeners that will be
1195 * notified when an accessible client asks for any of the properties
1196 * defined in the <code>AccessibleValueListener</code> interface.
1198 * @param listener the listener that should no longer be notified when the receiver
1199 * is asked for <code>AccessibleValueListener</code> interface properties
1201 * @exception IllegalArgumentException <ul>
1202 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
1204 * @exception SWTException <ul>
1205 * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
1206 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
1209 * @see AccessibleValueListener
1210 * @see #addAccessibleValueListener
1214 public void removeAccessibleValueListener(AccessibleValueListener listener) {
1216 if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
1217 if (accessibleValueListeners != null) {
1218 accessibleValueListeners.remove(listener);
1219 if (accessibleValueListeners.isEmpty()) accessibleValueListeners = null;
1224 * Removes the listener from the collection of listeners that will be
1225 * notified when an accessible client asks for any of the properties
1226 * defined in the <code>AccessibleAttributeListener</code> interface.
1228 * @param listener the listener that should no longer be notified when the receiver
1229 * is asked for <code>AccessibleAttributeListener</code> interface properties
1231 * @exception IllegalArgumentException <ul>
1232 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
1234 * @exception SWTException <ul>
1235 * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
1236 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
1239 * @see AccessibleAttributeListener
1240 * @see #addAccessibleAttributeListener
1244 public void removeAccessibleAttributeListener(AccessibleAttributeListener listener) {
1246 if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
1247 if (accessibleAttributeListeners != null) {
1248 accessibleAttributeListeners.remove(listener);
1249 if (accessibleAttributeListeners.isEmpty()) accessibleAttributeListeners = null;
1254 * Removes the relation with the specified type and target
1255 * from the receiver's set of relations.
1257 * @param type an <code>ACC</code> constant beginning with RELATION_* indicating the type of relation
1258 * @param target the accessible that is the target for this relation
1259 * @exception IllegalArgumentException ERROR_NULL_ARGUMENT - if the Accessible target is null
1262 public void removeRelation(int type, Accessible target) {
1264 if (target == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
1265 Relation relation = relations[type];
1266 if (relation != null) {
1267 relation.removeTarget(target);
1268 if (!relation.hasTargets()) {
1269 relations[type].Release();
1270 relations[type] = null;
1276 * Sends a message with event-specific data to accessible clients
1277 * indicating that something has changed within a custom control.
1279 * @param event an <code>ACC</code> constant beginning with EVENT_* indicating the message to send
1280 * @param eventData an object containing event-specific data, or null if there is no event-specific data
1281 * (eventData is specified in the documentation for individual ACC.EVENT_* constants)
1283 * @exception SWTException <ul>
1284 * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
1285 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
1288 * @see ACC#EVENT_ACTION_CHANGED
1289 * @see ACC#EVENT_ATTRIBUTE_CHANGED
1290 * @see ACC#EVENT_DESCRIPTION_CHANGED
1291 * @see ACC#EVENT_DOCUMENT_LOAD_COMPLETE
1292 * @see ACC#EVENT_DOCUMENT_LOAD_STOPPED
1293 * @see ACC#EVENT_DOCUMENT_RELOAD
1294 * @see ACC#EVENT_HYPERLINK_ACTIVATED
1295 * @see ACC#EVENT_HYPERLINK_ANCHOR_COUNT_CHANGED
1296 * @see ACC#EVENT_HYPERLINK_END_INDEX_CHANGED
1297 * @see ACC#EVENT_HYPERLINK_SELECTED_LINK_CHANGED
1298 * @see ACC#EVENT_HYPERLINK_START_INDEX_CHANGED
1299 * @see ACC#EVENT_HYPERTEXT_LINK_COUNT_CHANGED
1300 * @see ACC#EVENT_HYPERTEXT_LINK_SELECTED
1301 * @see ACC#EVENT_LOCATION_CHANGED
1302 * @see ACC#EVENT_NAME_CHANGED
1303 * @see ACC#EVENT_PAGE_CHANGED
1304 * @see ACC#EVENT_SECTION_CHANGED
1305 * @see ACC#EVENT_SELECTION_CHANGED
1306 * @see ACC#EVENT_STATE_CHANGED
1307 * @see ACC#EVENT_TABLE_CAPTION_CHANGED
1308 * @see ACC#EVENT_TABLE_CHANGED
1309 * @see ACC#EVENT_TABLE_COLUMN_DESCRIPTION_CHANGED
1310 * @see ACC#EVENT_TABLE_COLUMN_HEADER_CHANGED
1311 * @see ACC#EVENT_TABLE_ROW_DESCRIPTION_CHANGED
1312 * @see ACC#EVENT_TABLE_ROW_HEADER_CHANGED
1313 * @see ACC#EVENT_TABLE_SUMMARY_CHANGED
1314 * @see ACC#EVENT_TEXT_ATTRIBUTE_CHANGED
1315 * @see ACC#EVENT_TEXT_CARET_MOVED
1316 * @see ACC#EVENT_TEXT_CHANGED
1317 * @see ACC#EVENT_TEXT_COLUMN_CHANGED
1318 * @see ACC#EVENT_TEXT_SELECTION_CHANGED
1319 * @see ACC#EVENT_VALUE_CHANGED
1323 public void sendEvent(int event, Object eventData) {
1325 if (!isATRunning ()) return;
1326 if (!UseIA2) return;
1327 if (DEBUG) print(this + ".NotifyWinEvent " + getEventString(event) + " hwnd=" + control.handle + " childID=" + eventChildID());
1329 case ACC.EVENT_TABLE_CHANGED: {
1330 if (!(eventData instanceof int[] && ((int[])eventData).length == TABLE_MODEL_CHANGE_SIZE)) break;
1331 tableChange = (int[])eventData;
1332 OS.NotifyWinEvent (COM.IA2_EVENT_TABLE_CHANGED, control.handle, OS.OBJID_CLIENT, eventChildID());
1335 case ACC.EVENT_TEXT_CHANGED: {
1336 if (!(eventData instanceof Object[] && ((Object[])eventData).length == TEXT_CHANGE_SIZE)) break;
1337 Object[] data = (Object[])eventData;
1338 int type = ((Integer)data[0]).intValue();
1341 textDeleted = (Object[])eventData;
1342 OS.NotifyWinEvent (COM.IA2_EVENT_TEXT_REMOVED, control.handle, OS.OBJID_CLIENT, eventChildID());
1345 textInserted = (Object[])eventData;
1346 OS.NotifyWinEvent (COM.IA2_EVENT_TEXT_INSERTED, control.handle, OS.OBJID_CLIENT, eventChildID());
1351 case ACC.EVENT_HYPERTEXT_LINK_SELECTED: {
1352 if (!(eventData instanceof Integer)) break;
1353 // int index = ((Integer)eventData).intValue();
1354 // TODO: IA2 currently does not use the index, however the plan is to use it in future
1355 OS.NotifyWinEvent (COM.IA2_EVENT_HYPERTEXT_LINK_SELECTED, control.handle, OS.OBJID_CLIENT, eventChildID());
1358 case ACC.EVENT_VALUE_CHANGED:
1359 OS.NotifyWinEvent (COM.EVENT_OBJECT_VALUECHANGE, control.handle, OS.OBJID_CLIENT, eventChildID()); break;
1360 case ACC.EVENT_STATE_CHANGED:
1361 OS.NotifyWinEvent (COM.EVENT_OBJECT_STATECHANGE, control.handle, OS.OBJID_CLIENT, eventChildID()); break;
1362 case ACC.EVENT_SELECTION_CHANGED:
1363 OS.NotifyWinEvent (COM.EVENT_OBJECT_SELECTIONWITHIN, control.handle, OS.OBJID_CLIENT, eventChildID()); break;
1364 case ACC.EVENT_TEXT_SELECTION_CHANGED:
1365 OS.NotifyWinEvent (COM.EVENT_OBJECT_TEXTSELECTIONCHANGED, control.handle, OS.OBJID_CLIENT, eventChildID()); break;
1366 case ACC.EVENT_LOCATION_CHANGED:
1367 OS.NotifyWinEvent (COM.EVENT_OBJECT_LOCATIONCHANGE, control.handle, OS.OBJID_CLIENT, eventChildID()); break;
1368 case ACC.EVENT_NAME_CHANGED:
1369 OS.NotifyWinEvent (COM.EVENT_OBJECT_NAMECHANGE, control.handle, OS.OBJID_CLIENT, eventChildID()); break;
1370 case ACC.EVENT_DESCRIPTION_CHANGED:
1371 OS.NotifyWinEvent (COM.EVENT_OBJECT_DESCRIPTIONCHANGE, control.handle, OS.OBJID_CLIENT, eventChildID()); break;
1372 case ACC.EVENT_DOCUMENT_LOAD_COMPLETE:
1373 OS.NotifyWinEvent (COM.IA2_EVENT_DOCUMENT_LOAD_COMPLETE, control.handle, OS.OBJID_CLIENT, eventChildID()); break;
1374 case ACC.EVENT_DOCUMENT_LOAD_STOPPED:
1375 OS.NotifyWinEvent (COM.IA2_EVENT_DOCUMENT_LOAD_STOPPED, control.handle, OS.OBJID_CLIENT, eventChildID()); break;
1376 case ACC.EVENT_DOCUMENT_RELOAD:
1377 OS.NotifyWinEvent (COM.IA2_EVENT_DOCUMENT_RELOAD, control.handle, OS.OBJID_CLIENT, eventChildID()); break;
1378 case ACC.EVENT_PAGE_CHANGED:
1379 OS.NotifyWinEvent (COM.IA2_EVENT_PAGE_CHANGED, control.handle, OS.OBJID_CLIENT, eventChildID()); break;
1380 case ACC.EVENT_SECTION_CHANGED:
1381 OS.NotifyWinEvent (COM.IA2_EVENT_SECTION_CHANGED, control.handle, OS.OBJID_CLIENT, eventChildID()); break;
1382 case ACC.EVENT_ACTION_CHANGED:
1383 OS.NotifyWinEvent (COM.IA2_EVENT_ACTION_CHANGED, control.handle, OS.OBJID_CLIENT, eventChildID()); break;
1384 case ACC.EVENT_HYPERLINK_START_INDEX_CHANGED:
1385 OS.NotifyWinEvent (COM.IA2_EVENT_HYPERLINK_START_INDEX_CHANGED, control.handle, OS.OBJID_CLIENT, eventChildID()); break;
1386 case ACC.EVENT_HYPERLINK_END_INDEX_CHANGED:
1387 OS.NotifyWinEvent (COM.IA2_EVENT_HYPERLINK_END_INDEX_CHANGED, control.handle, OS.OBJID_CLIENT, eventChildID()); break;
1388 case ACC.EVENT_HYPERLINK_ANCHOR_COUNT_CHANGED:
1389 OS.NotifyWinEvent (COM.IA2_EVENT_HYPERLINK_ANCHOR_COUNT_CHANGED, control.handle, OS.OBJID_CLIENT, eventChildID()); break;
1390 case ACC.EVENT_HYPERLINK_SELECTED_LINK_CHANGED:
1391 OS.NotifyWinEvent (COM.IA2_EVENT_HYPERLINK_SELECTED_LINK_CHANGED, control.handle, OS.OBJID_CLIENT, eventChildID()); break;
1392 case ACC.EVENT_HYPERLINK_ACTIVATED:
1393 OS.NotifyWinEvent (COM.IA2_EVENT_HYPERLINK_ACTIVATED, control.handle, OS.OBJID_CLIENT, eventChildID()); break;
1394 case ACC.EVENT_HYPERTEXT_LINK_COUNT_CHANGED:
1395 OS.NotifyWinEvent (COM.IA2_EVENT_HYPERTEXT_LINK_COUNT_CHANGED, control.handle, OS.OBJID_CLIENT, eventChildID()); break;
1396 case ACC.EVENT_ATTRIBUTE_CHANGED:
1397 OS.NotifyWinEvent (COM.IA2_EVENT_ATTRIBUTE_CHANGED, control.handle, OS.OBJID_CLIENT, eventChildID()); break;
1398 case ACC.EVENT_TABLE_CAPTION_CHANGED:
1399 OS.NotifyWinEvent (COM.IA2_EVENT_TABLE_CAPTION_CHANGED, control.handle, OS.OBJID_CLIENT, eventChildID()); break;
1400 case ACC.EVENT_TABLE_COLUMN_DESCRIPTION_CHANGED:
1401 OS.NotifyWinEvent (COM.IA2_EVENT_TABLE_COLUMN_DESCRIPTION_CHANGED, control.handle, OS.OBJID_CLIENT, eventChildID()); break;
1402 case ACC.EVENT_TABLE_COLUMN_HEADER_CHANGED:
1403 OS.NotifyWinEvent (COM.IA2_EVENT_TABLE_COLUMN_HEADER_CHANGED, control.handle, OS.OBJID_CLIENT, eventChildID()); break;
1404 case ACC.EVENT_TABLE_ROW_DESCRIPTION_CHANGED:
1405 OS.NotifyWinEvent (COM.IA2_EVENT_TABLE_ROW_DESCRIPTION_CHANGED, control.handle, OS.OBJID_CLIENT, eventChildID()); break;
1406 case ACC.EVENT_TABLE_ROW_HEADER_CHANGED:
1407 OS.NotifyWinEvent (COM.IA2_EVENT_TABLE_ROW_HEADER_CHANGED, control.handle, OS.OBJID_CLIENT, eventChildID()); break;
1408 case ACC.EVENT_TABLE_SUMMARY_CHANGED:
1409 OS.NotifyWinEvent (COM.IA2_EVENT_TABLE_SUMMARY_CHANGED, control.handle, OS.OBJID_CLIENT, eventChildID()); break;
1410 case ACC.EVENT_TEXT_ATTRIBUTE_CHANGED:
1411 OS.NotifyWinEvent (COM.IA2_EVENT_TEXT_ATTRIBUTE_CHANGED, control.handle, OS.OBJID_CLIENT, eventChildID()); break;
1412 case ACC.EVENT_TEXT_CARET_MOVED:
1413 OS.NotifyWinEvent (COM.IA2_EVENT_TEXT_CARET_MOVED, control.handle, OS.OBJID_CLIENT, eventChildID()); break;
1414 case ACC.EVENT_TEXT_COLUMN_CHANGED:
1415 OS.NotifyWinEvent (COM.IA2_EVENT_TEXT_COLUMN_CHANGED, control.handle, OS.OBJID_CLIENT, eventChildID()); break;
1420 * Sends a message with event-specific data and a childID
1421 * to accessible clients, indicating that something has changed
1422 * within a custom control.
1424 * NOTE: This API is intended for applications that are still using childIDs.
1425 * Moving forward, applications should use accessible objects instead of childIDs.
1427 * @param event an <code>ACC</code> constant beginning with EVENT_* indicating the message to send
1428 * @param eventData an object containing event-specific data, or null if there is no event-specific data
1429 * (eventData is specified in the documentation for individual ACC.EVENT_* constants)
1430 * @param childID an identifier specifying a child of the control
1432 * @exception SWTException <ul>
1433 * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
1434 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
1437 * @see ACC#EVENT_DESCRIPTION_CHANGED
1438 * @see ACC#EVENT_LOCATION_CHANGED
1439 * @see ACC#EVENT_NAME_CHANGED
1440 * @see ACC#EVENT_SELECTION_CHANGED
1441 * @see ACC#EVENT_STATE_CHANGED
1442 * @see ACC#EVENT_TEXT_SELECTION_CHANGED
1443 * @see ACC#EVENT_VALUE_CHANGED
1447 public void sendEvent(int event, Object eventData, int childID) {
1449 if (!isATRunning ()) return;
1450 if (!UseIA2) return;
1451 int osChildID = childID == ACC.CHILDID_SELF ? eventChildID() : childIDToOs(childID);
1452 if (DEBUG) print(this + ".NotifyWinEvent " + getEventString(event) + " hwnd=" + control.handle + " childID=" + osChildID);
1454 case ACC.EVENT_STATE_CHANGED:
1455 OS.NotifyWinEvent (COM.EVENT_OBJECT_STATECHANGE, control.handle, OS.OBJID_CLIENT, osChildID); break;
1456 case ACC.EVENT_NAME_CHANGED:
1457 OS.NotifyWinEvent (COM.EVENT_OBJECT_NAMECHANGE, control.handle, OS.OBJID_CLIENT, osChildID); break;
1458 case ACC.EVENT_VALUE_CHANGED:
1459 OS.NotifyWinEvent (COM.EVENT_OBJECT_VALUECHANGE, control.handle, OS.OBJID_CLIENT, osChildID); break;
1460 case ACC.EVENT_LOCATION_CHANGED:
1461 OS.NotifyWinEvent (COM.EVENT_OBJECT_LOCATIONCHANGE, control.handle, OS.OBJID_CLIENT, osChildID); break;
1462 case ACC.EVENT_SELECTION_CHANGED:
1463 OS.NotifyWinEvent (COM.EVENT_OBJECT_SELECTIONWITHIN, control.handle, OS.OBJID_CLIENT, osChildID); break;
1464 case ACC.EVENT_TEXT_SELECTION_CHANGED:
1465 OS.NotifyWinEvent (COM.EVENT_OBJECT_TEXTSELECTIONCHANGED, control.handle, OS.OBJID_CLIENT, osChildID); break;
1466 case ACC.EVENT_DESCRIPTION_CHANGED:
1467 OS.NotifyWinEvent (COM.EVENT_OBJECT_DESCRIPTIONCHANGE, control.handle, OS.OBJID_CLIENT, osChildID); break;
1473 * Sends a message to accessible clients that the child selection
1474 * within a custom container control has changed.
1476 * @exception SWTException <ul>
1477 * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
1478 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
1483 public void selectionChanged () {
1485 if (!isATRunning ()) return;
1486 if (DEBUG) print(this + ".NotifyWinEvent EVENT_OBJECT_SELECTIONWITHIN hwnd=" + control.handle + " childID=" + eventChildID());
1487 OS.NotifyWinEvent (COM.EVENT_OBJECT_SELECTIONWITHIN, control.handle, OS.OBJID_CLIENT, eventChildID());
1491 * Sends a message to accessible clients indicating that the focus
1492 * has changed within a custom control.
1494 * @param childID an identifier specifying a child of the control
1496 * @exception SWTException <ul>
1497 * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
1498 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
1501 public void setFocus(int childID) {
1503 if (!isATRunning ()) return;
1504 int osChildID = childID == ACC.CHILDID_SELF ? eventChildID() : childIDToOs(childID);
1505 if (DEBUG) print(this + ".NotifyWinEvent EVENT_OBJECT_FOCUS hwnd=" + control.handle + " childID=" + osChildID);
1506 OS.NotifyWinEvent (OS.EVENT_OBJECT_FOCUS, control.handle, OS.OBJID_CLIENT, osChildID);
1510 * Sends a message to accessible clients that the text
1511 * caret has moved within a custom control.
1513 * @param index the new caret index within the control
1515 * @exception SWTException <ul>
1516 * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
1517 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
1522 public void textCaretMoved (int index) {
1524 if (timer == null) {
1525 timer = new Runnable() {
1528 if (!isATRunning ()) return;
1529 if (DEBUG) print(this + ".NotifyWinEvent EVENT_OBJECT_LOCATIONCHANGE hwnd=" + control.handle + " childID=" + eventChildID());
1530 OS.NotifyWinEvent (COM.EVENT_OBJECT_LOCATIONCHANGE, control.handle, OS.OBJID_CARET, eventChildID());
1531 if (!UseIA2) return;
1532 if (DEBUG) print(this + ".NotifyWinEvent IA2_EVENT_TEXT_CARET_MOVED hwnd=" + control.handle + " childID=" + eventChildID());
1533 OS.NotifyWinEvent (COM.IA2_EVENT_TEXT_CARET_MOVED, control.handle, OS.OBJID_CLIENT, eventChildID());
1537 control.getDisplay ().timerExec(SCROLL_RATE, timer);
1541 * Sends a message to accessible clients that the text
1542 * within a custom control has changed.
1544 * @param type the type of change, one of <code>ACC.TEXT_INSERT</code>
1545 * or <code>ACC.TEXT_DELETE</code>
1546 * @param startIndex the text index within the control where the insertion or deletion begins
1547 * @param length the non-negative length in characters of the insertion or deletion
1549 * @exception SWTException <ul>
1550 * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
1551 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
1554 * @see ACC#TEXT_INSERT
1555 * @see ACC#TEXT_DELETE
1559 public void textChanged (int type, int startIndex, int length) {
1561 if (!isATRunning ()) return;
1562 AccessibleTextEvent event = new AccessibleTextEvent(this);
1563 event.start = startIndex;
1564 event.end = startIndex + length;
1566 event.type = ACC.TEXT_BOUNDARY_ALL;
1567 for (int i = 0; i < accessibleTextExtendedListenersSize(); i++) {
1568 AccessibleTextExtendedListener listener = accessibleTextExtendedListeners.get(i);
1569 listener.getText(event);
1571 if (event.result != null) {
1572 Object[] eventData = new Object[] {
1573 Integer.valueOf(type),
1574 Integer.valueOf(startIndex),
1575 Integer.valueOf(startIndex + length),
1577 sendEvent(ACC.EVENT_TEXT_CHANGED, eventData);
1580 if (DEBUG) print(this + ".NotifyWinEvent EVENT_OBJECT_VALUECHANGE hwnd=" + control.handle + " childID=" + eventChildID());
1581 OS.NotifyWinEvent (COM.EVENT_OBJECT_VALUECHANGE, control.handle, OS.OBJID_CLIENT, eventChildID());
1585 * Sends a message to accessible clients that the text
1586 * selection has changed within a custom control.
1588 * @exception SWTException <ul>
1589 * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
1590 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
1595 public void textSelectionChanged () {
1597 if (!isATRunning ()) return;
1598 if (DEBUG) print(this + ".NotifyWinEvent EVENT_OBJECT_TEXTSELECTIONCHANGED hwnd=" + control.handle + " childID=" + eventChildID());
1599 OS.NotifyWinEvent (COM.EVENT_OBJECT_TEXTSELECTIONCHANGED, control.handle, OS.OBJID_CLIENT, eventChildID());
1602 /* QueryInterface([in] iid, [out] ppvObject)
1603 * Ownership of ppvObject transfers from callee to caller so reference count on ppvObject
1604 * must be incremented before returning. Caller is responsible for releasing ppvObject.
1606 int QueryInterface(long iid, long ppvObject) {
1607 if (control != null && control.isDisposed()) return COM.CO_E_OBJNOTCONNECTED;
1608 OS.MoveMemory(ppvObject, new long[] { 0 }, C.PTR_SIZEOF);
1609 GUID guid = new GUID();
1610 COM.MoveMemory(guid, iid, GUID.sizeof);
1612 if (COM.IsEqualGUID(guid, COM.IIDIUnknown) || COM.IsEqualGUID(guid, COM.IIDIDispatch) || COM.IsEqualGUID(guid, COM.IIDIAccessible)) {
1613 if (objIAccessible == null) createIAccessible();
1614 OS.MoveMemory(ppvObject, new long[] { objIAccessible.getAddress() }, C.PTR_SIZEOF);
1616 if (DEBUG) print(this + ".QueryInterface guid=" + guidString(guid) + " returning " + objIAccessible.getAddress() + hresult(COM.S_OK));
1620 if (COM.IsEqualGUID(guid, COM.IIDIEnumVARIANT)) {
1621 if (objIEnumVARIANT == null) createIEnumVARIANT();
1622 OS.MoveMemory(ppvObject, new long[] { objIEnumVARIANT.getAddress() }, C.PTR_SIZEOF);
1625 if (DEBUG) print(this + ".QueryInterface guid=" + guidString(guid) + " returning " + objIEnumVARIANT.getAddress() + hresult(COM.S_OK));
1629 if (COM.IsEqualGUID(guid, COM.IIDIServiceProvider)) {
1630 if (!UseIA2) return COM.E_NOINTERFACE;
1631 if (accessibleActionListenersSize() > 0 || accessibleAttributeListenersSize() > 0 ||
1632 accessibleHyperlinkListenersSize() > 0 || accessibleTableListenersSize() > 0 ||
1633 accessibleTableCellListenersSize() > 0 || accessibleTextExtendedListenersSize() > 0 ||
1634 accessibleValueListenersSize() > 0 || accessibleControlListenersSize() > 0 || getRelationCount() > 0
1635 || (control instanceof Button && ((control.getStyle() & SWT.RADIO) != 0)) || (control instanceof Composite)) {
1636 if (objIServiceProvider == null) createIServiceProvider();
1637 OS.MoveMemory(ppvObject, new long[] { objIServiceProvider.getAddress() }, C.PTR_SIZEOF);
1639 if (DEBUG) print(this + ".QueryInterface guid=" + guidString(guid) + " returning " + objIServiceProvider.getAddress() + hresult(COM.S_OK));
1642 if (DEBUG) if (interesting(guid)) print("QueryInterface guid=" + guidString(guid) + " returning" + hresult(COM.E_NOINTERFACE));
1643 return COM.E_NOINTERFACE;
1646 int code = queryAccessible2Interfaces(guid, ppvObject);
1647 if (code != COM.S_FALSE) {
1648 if (DEBUG) print(this + ".QueryInterface guid=" + guidString(guid) + " returning" + hresult(code));
1652 if (iaccessible != null) {
1653 /* Forward any other GUIDs to the OS proxy. */
1654 long[] ppv = new long[1];
1655 code = iaccessible.QueryInterface(guid, ppv);
1656 OS.MoveMemory(ppvObject, ppv, C.PTR_SIZEOF);
1657 if (DEBUG) if (interesting(guid)) print("QueryInterface guid=" + guidString(guid) + " returning super" + hresult(code));
1661 if (DEBUG) if (interesting(guid)) print("QueryInterface guid=" + guidString(guid) + " returning" + hresult(COM.E_NOINTERFACE));
1662 return COM.E_NOINTERFACE;
1665 int accessibleListenersSize() {
1666 return accessibleListeners == null ? 0 : accessibleListeners.size();
1669 int accessibleControlListenersSize() {
1670 return accessibleControlListeners == null ? 0 : accessibleControlListeners.size();
1673 int accessibleValueListenersSize() {
1674 return accessibleValueListeners == null ? 0 : accessibleValueListeners.size();
1677 int accessibleTextExtendedListenersSize() {
1678 return accessibleTextExtendedListeners == null ? 0 : accessibleTextExtendedListeners.size();
1681 int accessibleTextListenersSize() {
1682 return accessibleTextListeners == null ? 0 : accessibleTextListeners.size();
1685 int accessibleTableCellListenersSize() {
1686 return accessibleTableCellListeners == null ? 0 : accessibleTableCellListeners.size();
1689 int accessibleTableListenersSize() {
1690 return accessibleTableListeners == null ? 0 : accessibleTableListeners.size();
1693 int accessibleHyperlinkListenersSize() {
1694 return accessibleHyperlinkListeners == null ? 0 : accessibleHyperlinkListeners.size();
1697 int accessibleEditableTextListenersSize() {
1698 return accessibleEditableTextListeners == null ? 0 : accessibleEditableTextListeners.size();
1701 int accessibleAttributeListenersSize() {
1702 return accessibleAttributeListeners == null ? 0 : accessibleAttributeListeners.size();
1705 int accessibleActionListenersSize() {
1706 return accessibleActionListeners == null ? 0 : accessibleActionListeners.size();
1717 if (refCount == 0) {
1718 if (objIAccessible != null)
1719 objIAccessible.dispose();
1720 objIAccessible = null;
1722 if (objIEnumVARIANT != null)
1723 objIEnumVARIANT.dispose();
1724 objIEnumVARIANT = null;
1726 if (objIServiceProvider != null)
1727 objIServiceProvider.dispose();
1728 objIServiceProvider = null;
1730 if (objIAccessibleApplication != null)
1731 objIAccessibleApplication.dispose();
1732 objIAccessibleApplication = null;
1734 // The following lines are intentionally commented. We are not providing IAccessibleComponent at this time.
1735 // if (objIAccessibleComponent != null)
1736 // objIAccessibleComponent.dispose();
1737 // objIAccessibleComponent = null;
1739 if (objIAccessibleEditableText != null)
1740 objIAccessibleEditableText.dispose();
1741 objIAccessibleEditableText = null;
1743 if (objIAccessibleHyperlink != null)
1744 objIAccessibleHyperlink.dispose();
1745 objIAccessibleHyperlink = null;
1747 if (objIAccessibleHypertext != null)
1748 objIAccessibleHypertext.dispose();
1749 objIAccessibleHypertext = null;
1751 // The following lines are intentionally commented. We are not providing IAccessibleImage at this time.
1752 // if (objIAccessibleImage != null)
1753 // objIAccessibleImage.dispose();
1754 // objIAccessibleImage = null;
1756 if (objIAccessibleTable2 != null)
1757 objIAccessibleTable2.dispose();
1758 objIAccessibleTable2 = null;
1760 if (objIAccessibleTableCell != null)
1761 objIAccessibleTableCell.dispose();
1762 objIAccessibleTableCell = null;
1764 if (objIAccessibleValue != null)
1765 objIAccessibleValue.dispose();
1766 objIAccessibleValue = null;
1768 for (int i = 0; i < relations.length; i++) {
1769 if (relations[i] != null) relations[i].Release();
1771 // TODO: also remove all relations for which 'this' is a target??
1776 /* QueryService([in] guidService, [in] riid, [out] ppvObject) */
1777 int QueryService(long guidService, long riid, long ppvObject) {
1778 OS.MoveMemory(ppvObject, new long[] { 0 }, C.PTR_SIZEOF);
1779 GUID service = new GUID();
1780 COM.MoveMemory(service, guidService, GUID.sizeof);
1781 GUID guid = new GUID();
1782 COM.MoveMemory(guid, riid, GUID.sizeof);
1784 if (COM.IsEqualGUID(service, COM.IIDIAccessible)) {
1785 if (COM.IsEqualGUID(guid, COM.IIDIUnknown) || COM.IsEqualGUID(guid, COM.IIDIDispatch) || COM.IsEqualGUID(guid, COM.IIDIAccessible)) {
1786 if (objIAccessible == null) createIAccessible();
1787 if (DEBUG) print(this + ".QueryService service=" + guidString(service) + " guid=" + guidString(guid) + " returning " + objIAccessible.getAddress() + hresult(COM.S_OK));
1788 OS.MoveMemory(ppvObject, new long[] { objIAccessible.getAddress() }, C.PTR_SIZEOF);
1792 int code = queryAccessible2Interfaces(guid, ppvObject);
1793 if (code != COM.S_FALSE) {
1794 if (DEBUG) print(this + ".QueryService service=" + guidString(service) + " guid=" + guidString(guid) + " returning" + hresult(code));
1799 if (COM.IsEqualGUID(service, COM.IIDIAccessible2)) {
1800 int code = queryAccessible2Interfaces(guid, ppvObject);
1801 if (code != COM.S_FALSE) {
1802 if (DEBUG) print(this + ".*QueryService service=" + guidString(service) + " guid=" + guidString(guid) + " returning" + hresult(code));
1807 if (iaccessible != null) {
1808 /* Forward any other GUIDs to the OS proxy. */
1809 long [] ppv = new long [1];
1810 int code = iaccessible.QueryInterface(COM.IIDIServiceProvider, ppv);
1811 if (code == COM.S_OK) {
1812 IServiceProvider iserviceProvider = new IServiceProvider(ppv[0]);
1813 long [] ppvx = new long [1];
1814 code = iserviceProvider.QueryService(service, guid, ppvx);
1815 OS.MoveMemory(ppvObject, ppvx, C.PTR_SIZEOF);
1816 if (DEBUG) if (interesting(service) && interesting(guid)) print("QueryService service=" + guidString(service) + " guid=" + guidString(guid) + " returning super" + hresult(code));
1821 if (DEBUG) if (interesting(service) && interesting(guid)) print("QueryService service=" + guidString(service) + " guid=" + guidString(guid) + " returning" + hresult(COM.E_NOINTERFACE));
1822 return COM.E_NOINTERFACE;
1825 int queryAccessible2Interfaces(GUID guid, long ppvObject) {
1826 if (control != null && control.isDisposed()) return COM.CO_E_OBJNOTCONNECTED;
1827 if (COM.IsEqualGUID(guid, COM.IIDIAccessible2)) {
1828 if (accessibleActionListenersSize() > 0 || accessibleAttributeListenersSize() > 0 ||
1829 accessibleHyperlinkListenersSize() > 0 || accessibleTableListenersSize() > 0 ||
1830 accessibleTableCellListenersSize() > 0 || accessibleTextExtendedListenersSize() > 0 ||
1831 accessibleValueListenersSize() > 0 || accessibleControlListenersSize() > 0 || getRelationCount() > 0
1832 || (control instanceof Button && ((control.getStyle() & SWT.RADIO) != 0)) || (control instanceof Composite)) {
1833 // NOTE: IAccessible2 vtable is shared with IAccessible
1834 if (objIAccessible == null) createIAccessible();
1835 OS.MoveMemory(ppvObject, new long[] { objIAccessible.getAddress() }, C.PTR_SIZEOF);
1839 return COM.E_NOINTERFACE;
1842 if (COM.IsEqualGUID(guid, COM.IIDIAccessibleAction)) {
1843 if (accessibleActionListenersSize() > 0) {
1844 // NOTE: IAccessibleAction vtable is shared with IAccessibleHyperlink
1845 if (objIAccessibleHyperlink == null) createIAccessibleHyperlink();
1846 OS.MoveMemory(ppvObject, new long[] { objIAccessibleHyperlink.getAddress() }, C.PTR_SIZEOF);
1850 return COM.E_NOINTERFACE;
1853 if (COM.IsEqualGUID(guid, COM.IIDIAccessibleApplication)) {
1854 if (objIAccessibleApplication == null) createIAccessibleApplication();
1855 OS.MoveMemory(ppvObject, new long[] { objIAccessibleApplication.getAddress() }, C.PTR_SIZEOF);
1860 if (COM.IsEqualGUID(guid, COM.IIDIAccessibleComponent)) {
1861 // The following lines are intentionally commented. We are not supporting IAccessibleComponent at this time.
1862 // if (accessibleControlListenersSize() > 0) { // TO DO: can we reduce the scope of this somehow?
1863 // if (objIAccessibleComponent == null) createIAccessibleComponent();
1864 // COM.MoveMemory(ppvObject, new long[] { objIAccessibleComponent.getAddress() }, OS.PTR_SIZEOF);
1868 return COM.E_NOINTERFACE;
1871 if (COM.IsEqualGUID(guid, COM.IIDIAccessibleEditableText)) {
1872 if (accessibleEditableTextListenersSize() > 0) {
1873 if (objIAccessibleEditableText == null) createIAccessibleEditableText();
1874 OS.MoveMemory(ppvObject, new long[] { objIAccessibleEditableText.getAddress() }, C.PTR_SIZEOF);
1878 return COM.E_NOINTERFACE;
1881 if (COM.IsEqualGUID(guid, COM.IIDIAccessibleHyperlink)) {
1882 if (accessibleHyperlinkListenersSize() > 0) {
1883 if (objIAccessibleHyperlink == null) createIAccessibleHyperlink();
1884 OS.MoveMemory(ppvObject, new long[] { objIAccessibleHyperlink.getAddress() }, C.PTR_SIZEOF);
1888 return COM.E_NOINTERFACE;
1891 if (COM.IsEqualGUID(guid, COM.IIDIAccessibleHypertext)) {
1892 if (accessibleTextExtendedListenersSize() > 0) {
1893 if (objIAccessibleHypertext == null) createIAccessibleHypertext();
1894 OS.MoveMemory(ppvObject, new long[] { objIAccessibleHypertext.getAddress() }, C.PTR_SIZEOF);
1898 return COM.E_NOINTERFACE;
1901 if (COM.IsEqualGUID(guid, COM.IIDIAccessibleImage)) {
1902 // The following lines are intentionally commented. We are not supporting IAccessibleImage at this time.
1903 // if (getRole() == ACC.ROLE_GRAPHIC && (accessibleAccessibleListenersSize() > 0 || accessibleControlListenersSize() > 0)) {
1904 // if (objIAccessibleImage == null) createIAccessibleImage();
1905 // COM.MoveMemory(ppvObject, new long[] { objIAccessibleImage.getAddress() }, OS.PTR_SIZEOF);
1909 return COM.E_NOINTERFACE;
1912 if (COM.IsEqualGUID(guid, COM.IIDIAccessibleTable)) {
1913 // We are not supporting IAccessibleTable at this time.
1914 return COM.E_NOINTERFACE;
1917 if (COM.IsEqualGUID(guid, COM.IIDIAccessibleTable2)) {
1918 if (accessibleTableListenersSize() > 0) {
1919 if (objIAccessibleTable2 == null) createIAccessibleTable2();
1920 OS.MoveMemory(ppvObject, new long[] { objIAccessibleTable2.getAddress() }, C.PTR_SIZEOF);
1924 return COM.E_NOINTERFACE;
1927 if (COM.IsEqualGUID(guid, COM.IIDIAccessibleTableCell)) {
1928 if (accessibleTableCellListenersSize() > 0) {
1929 if (objIAccessibleTableCell == null) createIAccessibleTableCell();
1930 OS.MoveMemory(ppvObject, new long[] { objIAccessibleTableCell.getAddress() }, C.PTR_SIZEOF);
1934 return COM.E_NOINTERFACE;
1937 if (COM.IsEqualGUID(guid, COM.IIDIAccessibleText)) {
1938 if (accessibleTextExtendedListenersSize() > 0 || accessibleAttributeListenersSize() > 0) {
1939 // NOTE: IAccessibleText vtable is shared with IAccessibleHypertext
1940 if (objIAccessibleHypertext == null) createIAccessibleHypertext();
1941 OS.MoveMemory(ppvObject, new long[] { objIAccessibleHypertext.getAddress() }, C.PTR_SIZEOF);
1945 return COM.E_NOINTERFACE;
1948 if (COM.IsEqualGUID(guid, COM.IIDIAccessibleValue)) {
1949 if (accessibleValueListenersSize() > 0) {
1950 if (objIAccessibleValue == null) createIAccessibleValue();
1951 OS.MoveMemory(ppvObject, new long[] { objIAccessibleValue.getAddress() }, C.PTR_SIZEOF);
1955 return COM.E_NOINTERFACE;
1961 /* IAccessible::accDoDefaultAction([in] varChild) */
1962 int accDoDefaultAction(long varChild) {
1963 if (DEBUG) print(this + ".IAccessible::accDoDefaultAction");
1964 if (accessibleActionListenersSize() > 0) {
1965 VARIANT v = getVARIANT(varChild);
1966 if (v.vt != COM.VT_I4) return COM.E_INVALIDARG;
1967 if (v.lVal == COM.CHILDID_SELF) return doAction(0);
1969 int code = COM.DISP_E_MEMBERNOTFOUND;
1970 if (iaccessible != null) {
1971 /* If there were no action listeners, forward to the proxy. */
1972 code = iaccessible.accDoDefaultAction(varChild);
1973 if (code == COM.E_INVALIDARG) code = COM.DISP_E_MEMBERNOTFOUND; // proxy doesn't know about app childID
1978 /* IAccessible::accHitTest([in] xLeft, [in] yTop, [out] pvarChild) */
1979 int accHitTest(int xLeft, int yTop, long pvarChild) {
1980 int osChild = ACC.CHILDID_NONE;
1981 long osChildObject = 0;
1982 if (iaccessible != null) {
1983 /* Get the default child at point (left, top) from the OS. */
1984 int code = iaccessible.accHitTest(xLeft, yTop, pvarChild);
1985 if (code == COM.S_OK) {
1986 VARIANT v = getVARIANT(pvarChild);
1987 if (v.vt == COM.VT_I4) osChild = v.lVal;
1988 else if (v.vt == COM.VT_DISPATCH) {
1989 osChildObject = v.lVal; // TODO: don't use struct. lVal is an int.
1990 if (DEBUG) print(this + ".IAccessible::accHitTest() super returned VT_DISPATCH");
1993 if (accessibleControlListenersSize() == 0) {
1994 if (DEBUG) print(this + ".IAccessible::accHitTest returning childID=" + osChild + " from super" + hresult(code));
1999 AccessibleControlEvent event = new AccessibleControlEvent(this);
2000 event.childID = osChild == ACC.CHILDID_NONE ? ACC.CHILDID_NONE : osToChildID(osChild);
2001 // TODO: event.accessible = Accessible for osChildObject;
2004 for (int i = 0; i < accessibleControlListenersSize(); i++) {
2005 AccessibleControlListener listener = accessibleControlListeners.get(i);
2006 listener.getChildAtPoint(event);
2008 Accessible accessible = event.accessible;
2009 if (accessible != null) {
2010 if (DEBUG) print(this + ".IAccessible::accHitTest returning " + accessible.getAddress() + hresult(COM.S_OK));
2011 accessible.AddRef();
2012 setPtrVARIANT(pvarChild, COM.VT_DISPATCH, accessible.getAddress());
2015 int childID = event.childID;
2016 if (childID == ACC.CHILDID_NONE) {
2017 if (osChildObject != 0) {
2018 if (DEBUG) print(this + ".IAccessible::accHitTest returning osChildObject " + osChildObject + " from super" + hresult(COM.S_OK));
2021 if (DEBUG) print(this + ".IAccessible::accHitTest returning VT_EMPTY" + hresult(COM.S_FALSE));
2022 setIntVARIANT(pvarChild, COM.VT_EMPTY, 0);
2025 if (DEBUG) print(this + ".IAccessible::accHitTest returning " + childIDToOs(childID) + hresult(COM.S_OK));
2026 setIntVARIANT(pvarChild, COM.VT_I4, childIDToOs(childID));
2030 /* IAccessible::accLocation([out] pxLeft, [out] pyTop, [out] pcxWidth, [out] pcyHeight, [in] varChild) */
2031 int accLocation(long pxLeft, long pyTop, long pcxWidth, long pcyHeight, long varChild) {
2032 VARIANT v = getVARIANT(varChild);
2033 if (v.vt != COM.VT_I4) return COM.E_INVALIDARG;
2034 int osLeft = 0, osTop = 0, osWidth = 0, osHeight = 0;
2035 if (iaccessible != null) {
2036 /* Get the default location from the OS. */
2037 int code = iaccessible.accLocation(pxLeft, pyTop, pcxWidth, pcyHeight, varChild);
2038 if (code == COM.E_INVALIDARG) code = COM.DISP_E_MEMBERNOTFOUND; // proxy doesn't know about app childID
2039 if (accessibleControlListenersSize() == 0) {
2040 if (DEBUG) print(this + ".IAccessible::accLocation returning from super" + hresult(code));
2043 if (code == COM.S_OK) {
2044 int[] pLeft = new int[1], pTop = new int[1], pWidth = new int[1], pHeight = new int[1];
2045 OS.MoveMemory(pLeft, pxLeft, 4);
2046 OS.MoveMemory(pTop, pyTop, 4);
2047 OS.MoveMemory(pWidth, pcxWidth, 4);
2048 OS.MoveMemory(pHeight, pcyHeight, 4);
2049 osLeft = pLeft[0]; osTop = pTop[0]; osWidth = pWidth[0]; osHeight = pHeight[0];
2053 AccessibleControlEvent event = new AccessibleControlEvent(this);
2054 event.childID = osToChildID(v.lVal);
2057 event.width = osWidth;
2058 event.height = osHeight;
2059 for (int i = 0; i < accessibleControlListenersSize(); i++) {
2060 AccessibleControlListener listener = accessibleControlListeners.get(i);
2061 listener.getLocation(event);
2063 if (DEBUG) print(this + ".IAccessible::accLocation(" + v.lVal + ") returning x=" + event.x + " y=" + event.y + "w=" + event.width + "h=" + event.height + hresult(COM.S_OK));
2064 OS.MoveMemory(pxLeft, new int[] { event.x }, 4);
2065 OS.MoveMemory(pyTop, new int[] { event.y }, 4);
2066 OS.MoveMemory(pcxWidth, new int[] { event.width }, 4);
2067 OS.MoveMemory(pcyHeight, new int[] { event.height }, 4);
2071 /* IAccessible::accNavigate([in] navDir, [in] varStart, [out] pvarEndUpAt) */
2072 int accNavigate(int navDir, long varStart, long pvarEndUpAt) {
2073 if (DEBUG) print(this + ".IAccessible::accNavigate");
2074 /* MSAA: "The accNavigate method is deprecated and should not be used." */
2075 int code = COM.DISP_E_MEMBERNOTFOUND;
2076 if (iaccessible != null) {
2077 /* Since many of the native controls still handle accNavigate,
2078 * we will continue to send this through to the proxy. */
2079 code = iaccessible.accNavigate(navDir, varStart, pvarEndUpAt);
2080 if (code == COM.E_INVALIDARG) code = COM.DISP_E_MEMBERNOTFOUND; // proxy doesn't know about app childID
2085 // TODO: Consider supporting this in future.
2086 /* IAccessible::accSelect([in] flagsSelect, [in] varChild) */
2087 int accSelect(int flagsSelect, long varChild) {
2088 int code = COM.DISP_E_MEMBERNOTFOUND;
2089 if (iaccessible != null) {
2090 /* Currently, we don't expose this as API. Forward to the proxy. */
2091 code = iaccessible.accSelect(flagsSelect, varChild);
2092 if (code == COM.E_INVALIDARG) code = COM.DISP_E_MEMBERNOTFOUND; // proxy doesn't know about app childID
2094 if (DEBUG) print(this + ".IAccessible::accSelect(" + flagsSelect + ") returning" + hresult(code));
2098 /* IAccessible::get_accChild([in] varChild, [out] ppdispChild)
2099 * Ownership of ppdispChild transfers from callee to caller so reference count on ppdispChild
2100 * must be incremented before returning. The caller is responsible for releasing ppdispChild.
2102 int get_accChild(long varChild, long ppdispChild) {
2103 VARIANT v = getVARIANT(varChild);
2104 if (v.vt != COM.VT_I4) return COM.E_INVALIDARG;
2105 if (v.lVal == COM.CHILDID_SELF) {
2106 if (DEBUG) print(this + ".IAccessible::get_accChild(" + v.lVal + ") returning " + getAddress() + hresult(COM.S_OK));
2108 OS.MoveMemory(ppdispChild, new long[] { getAddress() }, C.PTR_SIZEOF);
2111 final int childID = osToChildID(v.lVal);
2112 int code = COM.S_FALSE;
2113 Accessible osAccessible = null;
2114 if (iaccessible != null) {
2115 /* Get the default child from the OS. */
2116 code = iaccessible.get_accChild(varChild, ppdispChild);
2117 if (code == COM.E_INVALIDARG) code = COM.S_FALSE; // proxy doesn't know about app childID
2118 if (code == COM.S_OK && control instanceof ToolBar) {
2119 ToolBar toolBar = (ToolBar) control;
2120 final ToolItem item = toolBar.getItem(childID);
2121 if (item != null && (item.getStyle() & SWT.DROP_DOWN) != 0) {
2122 long[] addr = new long[1];
2123 OS.MoveMemory(addr, ppdispChild, C.PTR_SIZEOF);
2124 boolean found = false;
2125 for (int i = 0; i < children.size(); i++) {
2126 Accessible accChild = children.get(i);
2127 if (accChild.item == item) {
2129 * MSAA uses a new accessible for the child
2130 * so we dispose the old and use the new.
2133 accChild.item = null;
2138 osAccessible = new Accessible(this, addr[0]);
2139 osAccessible.item = item;
2141 item.addListener(SWT.Dispose, e -> {
2142 for (int i = 0; i < children.size(); i++) {
2143 Accessible accChild = children.get(i);
2144 if (accChild.item == item) {
2150 osAccessible.addAccessibleListener(new AccessibleAdapter() {
2152 public void getName(AccessibleEvent e) {
2153 if (e.childID == ACC.CHILDID_SELF) {
2154 AccessibleEvent event = new AccessibleEvent(Accessible.this);
2155 event.childID = childID;
2156 for (int i = 0; i < accessibleListenersSize(); i++) {
2157 AccessibleListener listener = accessibleListeners.get(i);
2158 listener.getName(event);
2160 e.result = event.result;
2168 AccessibleControlEvent event = new AccessibleControlEvent(this);
2169 event.childID = childID;
2170 for (int i = 0; i < accessibleControlListenersSize(); i++) {
2171 AccessibleControlListener listener = accessibleControlListeners.get(i);
2172 listener.getChild(event);
2174 Accessible accessible = event.accessible;
2175 if (accessible == null) accessible = osAccessible;
2176 if (accessible != null) {
2177 if (DEBUG) print(this + ".IAccessible::get_accChild(" + v.lVal + ") returning " + accessible.getAddress() + hresult(COM.S_OK));
2178 accessible.AddRef();
2179 OS.MoveMemory(ppdispChild, new long[] { accessible.getAddress() }, C.PTR_SIZEOF);
2182 if (DEBUG) print(this + ".IAccessible::get_accChild(" + v.lVal + ") returning from super" + hresult(code));
2186 /* IAccessible::get_accChildCount([out] pcountChildren) */
2187 int get_accChildCount(long pcountChildren) {
2188 int osChildCount = 0;
2189 if (iaccessible != null) {
2190 /* Get the default child count from the OS. */
2191 int code = iaccessible.get_accChildCount(pcountChildren);
2192 if (code == COM.S_OK) {
2193 int[] pChildCount = new int[1];
2194 OS.MoveMemory(pChildCount, pcountChildren, 4);
2195 osChildCount = pChildCount[0];
2197 if (accessibleControlListenersSize() == 0) {
2198 if (DEBUG) print(this + ".IAccessible::get_accChildCount() returning " + osChildCount + " from super" + hresult(code));
2203 AccessibleControlEvent event = new AccessibleControlEvent(this);
2204 event.childID = ACC.CHILDID_SELF;
2205 event.detail = osChildCount;
2206 for (int i = 0; i < accessibleControlListenersSize(); i++) {
2207 AccessibleControlListener listener = accessibleControlListeners.get(i);
2208 listener.getChildCount(event);
2210 if (DEBUG) print(this + ".IAccessible::get_accChildCount() returning " + event.detail + hresult(COM.S_OK));
2211 OS.MoveMemory(pcountChildren, new int[] { event.detail }, 4);
2215 /* IAccessible::get_accDefaultAction([in] varChild, [out] pszDefaultAction) */
2216 int get_accDefaultAction(long varChild, long pszDefaultAction) {
2217 if (DEBUG) print(this + ".IAccessible::get_accDefaultAction");
2218 VARIANT v = getVARIANT(varChild);
2219 if (v.vt != COM.VT_I4) return COM.E_INVALIDARG;
2220 int code = COM.DISP_E_MEMBERNOTFOUND;
2221 String osDefaultAction = null;
2222 if (iaccessible != null) {
2223 /* Get the default defaultAction from the OS. */
2224 code = iaccessible.get_accDefaultAction(varChild, pszDefaultAction);
2225 if (code == COM.E_INVALIDARG) code = COM.S_FALSE; // proxy doesn't know about app childID
2226 if (accessibleControlListenersSize() == 0) return code;
2227 if (code == COM.S_OK) {
2228 long[] pDefaultAction = new long[1];
2229 OS.MoveMemory(pDefaultAction, pszDefaultAction, C.PTR_SIZEOF);
2230 int size = COM.SysStringByteLen(pDefaultAction[0]);
2232 char[] buffer = new char[(size + 1) /2];
2233 OS.MoveMemory(buffer, pDefaultAction[0], size);
2234 osDefaultAction = new String(buffer);
2239 AccessibleControlEvent event = new AccessibleControlEvent(this);
2240 event.childID = osToChildID(v.lVal);
2241 event.result = osDefaultAction;
2242 for (int i = 0; i < accessibleControlListenersSize(); i++) {
2243 AccessibleControlListener listener = accessibleControlListeners.get(i);
2244 listener.getDefaultAction(event);
2246 if ((event.result == null || event.result.length() == 0) && v.lVal == COM.CHILDID_SELF) {
2247 code = get_name(0, pszDefaultAction);
2249 if (event.result == null) return code;
2250 if (event.result.length() == 0) return COM.S_FALSE;
2251 setString(pszDefaultAction, event.result);
2255 /* IAccessible::get_accDescription([in] varChild, [out] pszDescription) */
2256 int get_accDescription(long varChild, long pszDescription) {
2258 * MSAA: "The accDescription property is not supported in the transition to
2259 * UI Automation. MSAA servers and applications should not use it."
2261 * TODO: Description was exposed as SWT API. We will need to either deprecate this (?),
2262 * or find a suitable replacement. Also, check description property on other platforms.
2263 * If it is truly deprecated for MSAA, then perhaps it can be reused for IAccessibleImage.
2264 * Note that the trick to expose tree columns (below) was not supported by screen readers,
2265 * so it should be replaced.
2267 VARIANT v = getVARIANT(varChild);
2268 if (v.vt != COM.VT_I4) return COM.E_INVALIDARG;
2269 int code = COM.DISP_E_MEMBERNOTFOUND;
2270 String osDescription = null;
2271 if (iaccessible != null) {
2272 /* Get the default description from the OS. */
2273 code = iaccessible.get_accDescription(varChild, pszDescription);
2274 if (code == COM.E_INVALIDARG) code = COM.S_FALSE; // proxy doesn't know about app childID
2275 // TEMPORARY CODE - process tree even if there are no apps listening
2276 if (accessibleListenersSize() == 0 && !(control instanceof Tree)) {
2277 if (DEBUG) print(this + ".IAccessible::get_accDescription(" + v.lVal + ") returning super" + hresult(code));
2280 if (code == COM.S_OK) {
2281 long[] pDescription = new long[1];
2282 OS.MoveMemory(pDescription, pszDescription, C.PTR_SIZEOF);
2283 int size = COM.SysStringByteLen(pDescription[0]);
2285 char[] buffer = new char[(size + 1) /2];
2286 OS.MoveMemory(buffer, pDescription[0], size);
2287 osDescription = new String(buffer);
2292 AccessibleEvent event = new AccessibleEvent(this);
2293 event.childID = osToChildID(v.lVal);
2294 event.result = osDescription;
2297 /* Currently our tree columns are emulated using custom draw,
2298 * so we need to create the description using the tree column
2299 * header text and tree item text. */
2300 if (v.lVal != COM.CHILDID_SELF) {
2301 if (control instanceof Tree) {
2302 Tree tree = (Tree) control;
2303 int columnCount = tree.getColumnCount ();
2304 if (columnCount > 1) {
2305 long hwnd = control.handle, hItem = 0;
2306 hItem = OS.SendMessage (hwnd, OS.TVM_MAPACCIDTOHTREEITEM, v.lVal, 0);
2307 Widget widget = tree.getDisplay ().findWidget (hwnd, hItem);
2309 if (widget != null && widget instanceof TreeItem) {
2310 TreeItem item = (TreeItem) widget;
2311 for (int i = 1; i < columnCount; i++) {
2312 if (tree.isDisposed() || item.isDisposed()) {
2316 event.result += tree.getColumn(i).getText() + ": " + item.getText(i);
2317 if (i + 1 < columnCount) event.result += ", ";
2323 for (int i = 0; i < accessibleListenersSize(); i++) {
2324 AccessibleListener listener = accessibleListeners.get(i);
2325 listener.getDescription(event);
2327 if (DEBUG) print(this + ".IAccessible::get_accDescription(" + v.lVal + ") returning " + event.result + hresult(event.result == null ? code : event.result.length() == 0 ? COM.S_FALSE : COM.S_OK));
2328 if (event.result == null) return code;
2329 if (event.result.length() == 0) return COM.S_FALSE;
2330 setString(pszDescription, event.result);
2334 /* IAccessible::get_accFocus([out] pvarChild)
2335 * Ownership of pvarChild transfers from callee to caller so reference count on pvarChild
2336 * must be incremented before returning. The caller is responsible for releasing pvarChild.
2338 int get_accFocus(long pvarChild) {
2339 int osChild = ACC.CHILDID_NONE;
2340 if (iaccessible != null) {
2341 /* Get the default focus child from the OS. */
2342 int code = iaccessible.get_accFocus(pvarChild);
2343 if (code == COM.S_OK) {
2344 VARIANT v = getVARIANT(pvarChild);
2345 if (v.vt == COM.VT_I4) osChild = v.lVal;
2346 // TODO: need to check VT_DISPATCH (don't use struct)
2347 if (DEBUG) if (v.vt == COM.VT_DISPATCH) print("IAccessible::get_accFocus() super returned VT_DISPATCH");
2349 if (accessibleControlListenersSize() == 0) {
2350 if (DEBUG) print(this + ".IAccessible::get_accFocus() returning childID=" + osChild + " from super" + hresult(code));
2355 AccessibleControlEvent event = new AccessibleControlEvent(this);
2356 event.childID = osChild == ACC.CHILDID_NONE ? ACC.CHILDID_NONE : osToChildID(osChild);
2357 for (int i = 0; i < accessibleControlListenersSize(); i++) {
2358 AccessibleControlListener listener = accessibleControlListeners.get(i);
2359 listener.getFocus(event);
2361 Accessible accessible = event.accessible;
2362 if (accessible != null) {
2363 if (DEBUG) print(this + ".IAccessible::get_accFocus() returning accessible " + accessible.getAddress() + hresult(COM.S_OK));
2364 accessible.AddRef();
2365 setPtrVARIANT(pvarChild, COM.VT_DISPATCH, accessible.getAddress());
2368 int childID = event.childID;
2369 if (childID == ACC.CHILDID_NONE) {
2370 if (DEBUG) print(this + ".IAccessible::get_accFocus() returning VT_EMPTY" + hresult(COM.S_FALSE));
2371 setIntVARIANT(pvarChild, COM.VT_EMPTY, 0);
2374 if (childID == ACC.CHILDID_SELF) {
2375 if (DEBUG) print(this + ".IAccessible::get_accFocus() returning CHILDID_SELF " + hresult(COM.S_OK));
2377 setIntVARIANT(pvarChild, COM.VT_I4, COM.CHILDID_SELF);
2380 if (DEBUG) print(this + ".IAccessible::get_accFocus() returning childID " + childIDToOs(childID) + hresult(COM.S_OK));
2381 setIntVARIANT(pvarChild, COM.VT_I4, childIDToOs(childID));
2385 /* IAccessible::get_accHelp([in] varChild, [out] pszHelp) */
2386 int get_accHelp(long varChild, long pszHelp) {
2387 if (DEBUG) print(this + ".IAccessible::get_accHelp");
2388 VARIANT v = getVARIANT(varChild);
2389 if (v.vt != COM.VT_I4) return COM.E_INVALIDARG;
2390 int code = COM.DISP_E_MEMBERNOTFOUND;
2391 String osHelp = null;
2392 if (iaccessible != null) {
2393 /* Get the default help string from the OS. */
2394 code = iaccessible.get_accHelp(varChild, pszHelp);
2395 if (code == COM.E_INVALIDARG) code = COM.S_FALSE; // proxy doesn't know about app childID
2396 if (accessibleListenersSize() == 0) return code;
2397 if (code == COM.S_OK) {
2398 long[] pHelp = new long[1];
2399 OS.MoveMemory(pHelp, pszHelp, C.PTR_SIZEOF);
2400 int size = COM.SysStringByteLen(pHelp[0]);
2402 char[] buffer = new char[(size + 1) /2];
2403 OS.MoveMemory(buffer, pHelp[0], size);
2404 osHelp = new String(buffer);
2409 AccessibleEvent event = new AccessibleEvent(this);
2410 event.childID = osToChildID(v.lVal);
2411 event.result = osHelp;
2412 for (int i = 0; i < accessibleListenersSize(); i++) {
2413 AccessibleListener listener = accessibleListeners.get(i);
2414 listener.getHelp(event);
2416 if (event.result == null) return code;
2417 if (event.result.length() == 0) return COM.S_FALSE;
2418 setString(pszHelp, event.result);
2422 /* IAccessible::get_accHelpTopic([out] pszHelpFile, [in] varChild, [out] pidTopic) */
2423 int get_accHelpTopic(long pszHelpFile, long varChild, long pidTopic) {
2424 if (DEBUG) print(this + ".IAccessible::get_accHelpTopic");
2425 /* MSAA: "The accHelpTopic property is deprecated and should not be used." */
2426 int code = COM.DISP_E_MEMBERNOTFOUND;
2427 if (iaccessible != null) {
2428 /* Since it is possible that a native control might still handle get_accHelpTopic,
2429 * we will continue to send this through to the proxy. */
2430 code = iaccessible.get_accHelpTopic(pszHelpFile, varChild, pidTopic);
2431 if (code == COM.E_INVALIDARG) code = COM.DISP_E_MEMBERNOTFOUND; // proxy doesn't know about app childID
2436 /* IAccessible::get_accKeyboardShortcut([in] varChild, [out] pszKeyboardShortcut) */
2437 int get_accKeyboardShortcut(long varChild, long pszKeyboardShortcut) {
2438 if (DEBUG) print(this + ".IAccessible::get_accKeyboardShortcut");
2439 VARIANT v = getVARIANT(varChild);
2440 if (v.vt != COM.VT_I4) return COM.E_INVALIDARG;
2441 int code = COM.DISP_E_MEMBERNOTFOUND;
2442 String osKeyboardShortcut = null;
2443 if (iaccessible != null) {
2444 /* Get the default keyboard shortcut from the OS. */
2445 code = iaccessible.get_accKeyboardShortcut(varChild, pszKeyboardShortcut);
2446 if (code == COM.E_INVALIDARG) code = COM.S_FALSE; // proxy doesn't know about app childID
2447 /* Process TabFolder even if there are no apps listening. */
2448 if (accessibleListenersSize() == 0 && !(control instanceof TabFolder)) return code;
2449 if (code == COM.S_OK) {
2450 long[] pKeyboardShortcut = new long[1];
2451 OS.MoveMemory(pKeyboardShortcut, pszKeyboardShortcut, C.PTR_SIZEOF);
2452 int size = COM.SysStringByteLen(pKeyboardShortcut[0]);
2454 char[] buffer = new char[(size + 1) /2];
2455 OS.MoveMemory(buffer, pKeyboardShortcut[0], size);
2456 osKeyboardShortcut = new String(buffer);
2461 AccessibleEvent event = new AccessibleEvent(this);
2462 event.childID = osToChildID(v.lVal);
2463 event.result = osKeyboardShortcut;
2464 /* SWT TabFolders use Ctrl+PageDown to switch pages (not Ctrl+Tab). */
2465 if (v.lVal == COM.CHILDID_SELF && control instanceof TabFolder) {
2466 event.result = SWT.getMessage ("SWT_SwitchPage_Shortcut"); //$NON-NLS-1$
2468 for (int i = 0; i < accessibleListenersSize(); i++) {
2469 AccessibleListener listener = accessibleListeners.get(i);
2470 listener.getKeyboardShortcut(event);
2472 if (event.result == null) return code;
2473 if (event.result.length() == 0) return COM.S_FALSE;
2474 setString(pszKeyboardShortcut, event.result);
2478 /* IAccessible::get_accName([in] varChild, [out] pszName) */
2479 int get_accName(long varChild, long pszName) {
2480 if (control != null && control.isDisposed()) return COM.CO_E_OBJNOTCONNECTED;
2481 VARIANT v = getVARIANT(varChild);
2482 if (v.vt != COM.VT_I4) return COM.E_INVALIDARG;
2483 int code = COM.S_FALSE;
2484 String osName = null;
2485 if (iaccessible != null) {
2486 /* Get the default name from the OS. */
2487 code = iaccessible.get_accName(varChild, pszName);
2488 if (code == COM.S_OK) {
2489 long[] pName = new long[1];
2490 OS.MoveMemory(pName, pszName, C.PTR_SIZEOF);
2491 int size = COM.SysStringByteLen(pName[0]);
2493 char[] buffer = new char[(size + 1) /2];
2494 OS.MoveMemory(buffer, pName[0], size);
2495 osName = new String(buffer);
2498 if (code == COM.E_INVALIDARG) code = COM.S_FALSE; // proxy doesn't know about app childID
2499 /* Process Text even if there are no apps listening. */
2500 if (accessibleListenersSize() == 0 && !(control instanceof Text)) {
2501 if (DEBUG) print(this + ".IAccessible::get_accName(" + v.lVal + ") returning name=" + osName + " from super" + hresult(code));
2506 AccessibleEvent event = new AccessibleEvent(this);
2507 event.childID = osToChildID(v.lVal);
2508 event.result = osName;
2510 * Bug in Windows: A Text with SWT.SEARCH style uses EM_SETCUEBANNER
2511 * to set the message text. This text should be used as the control's
2512 * accessible name, however it is not. The fix is to return the message
2513 * text here as the accName (unless there is a preceding label).
2515 if (control instanceof Text && (control.getStyle() & SWT.SEARCH) != 0 && osName == null) {
2516 event.result = ((Text) control).getMessage();
2518 for (int i = 0; i < accessibleListenersSize(); i++) {
2519 AccessibleListener listener = accessibleListeners.get(i);
2520 listener.getName(event);
2522 if (DEBUG) print(this + ".IAccessible::get_accName(" + v.lVal + ") returning " + event.result + hresult(event.result == null ? code : event.result.length() == 0 ? COM.S_FALSE : COM.S_OK));
2523 if (event.result == null) return code;
2524 if (event.result.length() == 0) return COM.S_FALSE;
2525 setString(pszName, event.result);
2529 /* IAccessible::get_accParent([out] ppdispParent)
2530 * Ownership of ppdispParent transfers from callee to caller so reference count on ppdispParent
2531 * must be incremented before returning. The caller is responsible for releasing ppdispParent.
2533 int get_accParent(long ppdispParent) {
2534 int code = COM.DISP_E_MEMBERNOTFOUND;
2535 if (iaccessible != null) {
2536 /* Currently, we don't expose this as API. Forward to the proxy. */
2537 code = iaccessible.get_accParent(ppdispParent);
2539 if (parent != null) {
2540 /* For lightweight accessibles, return the accessible's parent. */
2542 OS.MoveMemory(ppdispParent, new long[] { parent.getAddress() }, C.PTR_SIZEOF);
2545 if (DEBUG) print(this + ".IAccessible::get_accParent() returning" + (parent != null ? " " + parent.getAddress() : " from super") + hresult(code));
2549 /* IAccessible::get_accRole([in] varChild, [out] pvarRole) */
2550 int get_accRole(long varChild, long pvarRole) {
2551 if (control != null && control.isDisposed()) return COM.CO_E_OBJNOTCONNECTED;
2552 VARIANT v = getVARIANT(varChild);
2553 if (v.vt != COM.VT_I4) return COM.E_INVALIDARG;
2554 int osRole = COM.ROLE_SYSTEM_CLIENT;
2555 if (iaccessible != null) {
2556 /* Get the default role from the OS. */
2557 int code = iaccessible.get_accRole(varChild, pvarRole);
2558 if (code == COM.S_OK) {
2559 VARIANT v2 = getVARIANT(pvarRole);
2560 if (v2.vt == COM.VT_I4) osRole = v2.lVal;
2564 AccessibleControlEvent event = new AccessibleControlEvent(this);
2565 event.childID = osToChildID(v.lVal);
2566 event.detail = osToRole(osRole);
2568 /* Currently our checkbox table and tree are emulated using state mask images,
2569 * so we need to specify 'checkbox' role for the items. */
2570 if (control instanceof Tree || control instanceof Table) {
2571 if (v.lVal != COM.CHILDID_SELF && (control.getStyle() & SWT.CHECK) != 0) event.detail = ACC.ROLE_CHECKBUTTON;
2573 for (int i = 0; i < accessibleControlListenersSize(); i++) {
2574 AccessibleControlListener listener = accessibleControlListeners.get(i);
2575 listener.getRole(event);
2577 if (DEBUG) print(this + ".IAccessible::get_accRole(" + v.lVal + ") returning " + getRoleString(roleToOs(event.detail)) + hresult(COM.S_OK));
2578 setIntVARIANT(pvarRole, COM.VT_I4, roleToOs(event.detail));
2582 /* IAccessible::get_accSelection([out] pvarChildren)
2583 * Ownership of pvarChildren transfers from callee to caller so reference count on pvarChildren
2584 * must be incremented before returning. The caller is responsible for releasing pvarChildren.
2586 int get_accSelection(long pvarChildren) {
2587 if (DEBUG) print(this + ".IAccessible::get_accSelection");
2588 int osChild = ACC.CHILDID_NONE;
2589 long osChildObject = 0;
2590 if (iaccessible != null) {
2591 /* Get the default selection from the OS. */
2592 int code = iaccessible.get_accSelection(pvarChildren);
2593 if (accessibleControlListenersSize() == 0) return code;
2594 if (code == COM.S_OK) {
2595 VARIANT v = getVARIANT(pvarChildren);
2596 if (v.vt == COM.VT_I4) {
2597 osChild = osToChildID(v.lVal);
2598 } else if (v.vt == COM.VT_DISPATCH) {
2599 osChildObject = v.lVal; // TODO: don't use struct; lVal is an int
2600 } else if (v.vt == COM.VT_UNKNOWN) {
2601 osChild = ACC.CHILDID_MULTIPLE;
2602 // TODO: Should get IEnumVARIANT from punkVal field, and enumerate children...
2607 AccessibleControlEvent event = new AccessibleControlEvent(this);
2608 event.childID = osChild;
2609 for (int i = 0; i < accessibleControlListenersSize(); i++) {
2610 AccessibleControlListener listener = accessibleControlListeners.get(i);
2611 listener.getSelection(event);
2613 Accessible accessible = event.accessible;
2614 if (accessible != null) {
2615 accessible.AddRef();
2616 setPtrVARIANT(pvarChildren, COM.VT_DISPATCH, accessible.getAddress());
2619 int childID = event.childID;
2620 if (childID == ACC.CHILDID_NONE) {
2621 if (osChildObject != 0) return COM.S_OK;
2622 setIntVARIANT(pvarChildren, COM.VT_EMPTY, 0);
2625 if (childID == ACC.CHILDID_MULTIPLE) {
2626 // TODO: return an enumeration for event.children (currently just returns enumeration from proxy)
2628 //setPtrVARIANT(pvarChildren, COM.VT_UNKNOWN, getAddress());
2631 if (childID == ACC.CHILDID_SELF) {
2633 setPtrVARIANT(pvarChildren, COM.VT_DISPATCH, getAddress());
2636 setIntVARIANT(pvarChildren, COM.VT_I4, childIDToOs(childID));
2640 /* IAccessible::get_accState([in] varChild, [out] pvarState) */
2641 int get_accState(long varChild, long pvarState) {
2642 if (control != null && control.isDisposed()) return COM.CO_E_OBJNOTCONNECTED;
2643 VARIANT v = getVARIANT(varChild);
2644 if (v.vt != COM.VT_I4) return COM.E_INVALIDARG;
2646 if (iaccessible != null) {
2647 /* Get the default state from the OS. */
2648 int code = iaccessible.get_accState(varChild, pvarState);
2649 if (code == COM.S_OK) {
2650 VARIANT v2 = getVARIANT(pvarState);
2651 if (v2.vt == COM.VT_I4) osState = v2.lVal;
2655 boolean grayed = false;
2656 AccessibleControlEvent event = new AccessibleControlEvent(this);
2657 event.childID = osToChildID(v.lVal);
2658 event.detail = osToState(osState);
2660 /* Currently our checkbox table and tree are emulated using state mask
2661 * images, so we need to determine if the item state is 'checked'. */
2662 if (v.lVal != COM.CHILDID_SELF) {
2663 if (control instanceof Tree && (control.getStyle() & SWT.CHECK) != 0) {
2664 long hwnd = control.handle;
2665 TVITEM tvItem = new TVITEM ();
2666 tvItem.mask = OS.TVIF_HANDLE | OS.TVIF_STATE;
2667 tvItem.stateMask = OS.TVIS_STATEIMAGEMASK;
2668 tvItem.hItem = OS.SendMessage (hwnd, OS.TVM_MAPACCIDTOHTREEITEM, v.lVal, 0);
2669 long result = OS.SendMessage (hwnd, OS.TVM_GETITEM, 0, tvItem);
2670 boolean checked = (result != 0) && (((tvItem.state >> 12) & 1) == 0);
2671 if (checked) event.detail |= ACC.STATE_CHECKED;
2672 grayed = tvItem.state >> 12 > 2;
2673 } else if (control instanceof Table && (control.getStyle() & SWT.CHECK) != 0) {
2674 Table table = (Table) control;
2675 int index = event.childID;
2676 if (0 <= index && index < table.getItemCount()) {
2677 TableItem item = table.getItem(index);
2678 if (item.getChecked()) event.detail |= ACC.STATE_CHECKED;
2679 if (item.getGrayed()) grayed = true;
2683 for (int i = 0; i < accessibleControlListenersSize(); i++) {
2684 AccessibleControlListener listener = accessibleControlListeners.get(i);
2685 listener.getState(event);
2687 int state = stateToOs(event.detail);
2688 if ((state & ACC.STATE_CHECKED) != 0 && grayed) {
2689 state &= ~ COM.STATE_SYSTEM_CHECKED;
2690 state |= COM.STATE_SYSTEM_MIXED;
2692 if (DEBUG) print(this + ".IAccessible::get_accState(" + v.lVal + ") returning" + getStateString(state) + hresult(COM.S_OK));
2693 setIntVARIANT(pvarState, COM.VT_I4, state);
2697 /* IAccessible::get_accValue([in] varChild, [out] pszValue) */
2698 int get_accValue(long varChild, long pszValue) {
2699 if (control != null && control.isDisposed()) return COM.CO_E_OBJNOTCONNECTED;
2700 VARIANT v = getVARIANT(varChild);
2701 if (v.vt != COM.VT_I4) return COM.E_INVALIDARG;
2702 int code = COM.DISP_E_MEMBERNOTFOUND;
2703 String osValue = null;
2704 if (iaccessible != null) {
2705 /* Get the default value string from the OS. */
2706 code = iaccessible.get_accValue(varChild, pszValue);
2707 if (code == COM.S_OK) {
2708 long[] pValue = new long[1];
2709 OS.MoveMemory(pValue, pszValue, C.PTR_SIZEOF);
2710 int size = COM.SysStringByteLen(pValue[0]);
2712 char[] buffer = new char[(size + 1) /2];
2713 OS.MoveMemory(buffer, pValue[0], size);
2714 osValue = new String(buffer);
2717 if (code == COM.E_INVALIDARG) code = COM.DISP_E_MEMBERNOTFOUND; // proxy doesn't know about app childID
2718 /* Process Text even if there are no apps listening. */
2719 if (accessibleControlListenersSize() == 0 && !(control instanceof Text)) {
2720 if (DEBUG) print(this + ".IAccessible::get_accValue(" + v.lVal + ") returning value=" + osValue + " from super" + hresult(code));
2725 AccessibleControlEvent event = new AccessibleControlEvent(this);
2726 event.childID = osToChildID(v.lVal);
2727 event.result = osValue;
2729 * Bug in Windows: A Text with SWT.SEARCH style uses EM_SETCUEBANNER
2730 * to set the message text. This text should be used as the control's
2731 * accessible value when the control does not have focus, however it
2732 * is not. The fix is to return the message text here as the accValue.
2734 if (control instanceof Text && (control.getStyle() & SWT.SEARCH) != 0 && !control.isFocusControl()) {
2735 event.result = ((Text) control).getMessage();
2737 for (int i = 0; i < accessibleControlListenersSize(); i++) {
2738 AccessibleControlListener listener = accessibleControlListeners.get(i);
2739 listener.getValue(event);
2741 if (DEBUG) print(this + ".IAccessible::get_accValue(" + v.lVal + ") returning " + event.result + hresult(event.result == null ? code : COM.S_OK));
2742 if (event.result == null) return code;
2743 // empty string is a valid value, so do not test for it
2744 setString(pszValue, event.result);
2748 /* put_accName([in] varChild, [in] szName) */
2749 int put_accName(long varChild, long szName) {
2750 /* MSAA: "The IAccessible::put_accName method is no longer supported. Servers should return E_NOTIMPL." */
2751 return COM.E_NOTIMPL;
2754 /* put_accValue([in] varChild, [in] szValue) */
2755 int put_accValue(long varChild, long szValue) {
2756 /* MSAA: this method is supported for some UI elements (usually edit controls). */
2757 VARIANT v = getVARIANT(varChild);
2758 if (v.vt != COM.VT_I4) return COM.E_INVALIDARG;
2759 int code = COM.DISP_E_MEMBERNOTFOUND;
2760 if (v.lVal == COM.CHILDID_SELF && accessibleEditableTextListenersSize() > 0) {
2762 * If the object supports AccessibleEditableTextListener.replaceText,
2763 * then give the object a chance to handle this event.
2765 AccessibleEditableTextEvent event = new AccessibleEditableTextEvent(this);
2767 event.end = getCharacterCount();
2768 if (event.end >= 0) {
2769 int size = COM.SysStringByteLen(szValue);
2770 char [] buffer = new char [(size + 1) / 2];
2771 OS.MoveMemory (buffer, szValue, size);
2772 event.string = new String (buffer);
2773 for (int i = 0; i < accessibleEditableTextListenersSize(); i++) {
2774 AccessibleEditableTextListener listener = accessibleEditableTextListeners.get(i);
2775 listener.replaceText(event);
2777 if (event.result != null && event.result.equals(ACC.OK)) code = COM.S_OK;
2778 if (DEBUG) print(this + ".IAccessible::put_accValue(" + v.lVal + ", \"" + event.string + "\") returning " + hresult(code));
2781 if (code != COM.S_OK && iaccessible != null) {
2782 /* If the object did not handle the event, then forward to the proxy. */
2783 code = iaccessible.put_accValue(varChild, szValue);
2784 if (code == COM.E_INVALIDARG) code = COM.DISP_E_MEMBERNOTFOUND; // proxy doesn't know about app childID
2785 if (DEBUG) print(this + ".IAccessible::put_accValue(" + v.lVal + ") returning " + hresult(code) + " from proxy");
2790 /* IEnumVARIANT methods: Next, Skip, Reset, Clone */
2791 /* Retrieve the next celt items in the enumeration sequence.
2792 * If there are fewer than the requested number of elements left
2793 * in the sequence, retrieve the remaining elements.
2794 * The number of elements actually retrieved is returned in pceltFetched
2795 * (unless the caller passed in NULL for that parameter).
2798 /* IEnumVARIANT::Next([in] celt, [out] rgvar, [in, out] pceltFetched)
2799 * Ownership of rgvar transfers from callee to caller so reference count on rgvar
2800 * must be incremented before returning. The caller is responsible for releasing rgvar.
2802 int Next(int celt, long rgvar, long pceltFetched) {
2803 if (DEBUG) print(this + ".IEnumVARIANT::Next");
2804 /* If there are no listeners, query the proxy for
2805 * its IEnumVariant, and get the Next items from it.
2807 if (iaccessible != null && accessibleControlListenersSize() == 0) {
2808 long[] ppvObject = new long[1];
2809 int code = iaccessible.QueryInterface(COM.IIDIEnumVARIANT, ppvObject);
2810 if (code != COM.S_OK) return code;
2811 IEnumVARIANT ienumvariant = new IEnumVARIANT(ppvObject[0]);
2812 int[] celtFetched = new int[1];
2813 code = ienumvariant.Next(celt, rgvar, celtFetched);
2814 ienumvariant.Release();
2815 OS.MoveMemory(pceltFetched, celtFetched, 4);
2819 if (rgvar == 0) return COM.E_INVALIDARG;
2820 if (pceltFetched == 0 && celt != 1) return COM.E_INVALIDARG;
2821 if (enumIndex == 0) {
2822 AccessibleControlEvent event = new AccessibleControlEvent(this);
2823 event.childID = ACC.CHILDID_SELF;
2824 for (int i = 0; i < accessibleControlListenersSize(); i++) {
2825 AccessibleControlListener listener = accessibleControlListeners.get(i);
2826 listener.getChildren(event);
2828 variants = event.children;
2830 Object[] nextItems = null;
2831 if (variants != null && celt >= 1) {
2832 int endIndex = enumIndex + celt - 1;
2833 if (endIndex > (variants.length - 1)) endIndex = variants.length - 1;
2834 if (enumIndex <= endIndex) {
2835 nextItems = new Object[endIndex - enumIndex + 1];
2836 for (int i = 0; i < nextItems.length; i++) {
2837 Object child = variants[enumIndex];
2838 if (child instanceof Integer) {
2839 nextItems[i] = Integer.valueOf(childIDToOs(((Integer)child).intValue()));
2841 nextItems[i] = child;
2847 if (nextItems != null) {
2848 for (int i = 0; i < nextItems.length; i++) {
2849 Object nextItem = nextItems[i];
2850 if (nextItem instanceof Integer) {
2851 int item = ((Integer) nextItem).intValue();
2852 setIntVARIANT(rgvar + i * VARIANT.sizeof, COM.VT_I4, item);
2854 Accessible accessible = (Accessible) nextItem;
2855 accessible.AddRef();
2856 setPtrVARIANT(rgvar + i * VARIANT.sizeof, COM.VT_DISPATCH, accessible.getAddress());
2859 if (pceltFetched != 0)
2860 OS.MoveMemory(pceltFetched, new int[] {nextItems.length}, 4);
2861 if (nextItems.length == celt) return COM.S_OK;
2863 if (pceltFetched != 0)
2864 OS.MoveMemory(pceltFetched, new int[] {0}, 4);
2869 /* IEnumVARIANT::Skip([in] celt) over the specified number of elements in the enumeration sequence. */
2870 int Skip(int celt) {
2871 if (DEBUG) print(this + ".IEnumVARIANT::Skip");
2872 /* If there are no listeners, query the proxy
2873 * for its IEnumVariant, and tell it to Skip.
2875 if (iaccessible != null && accessibleControlListenersSize() == 0) {
2876 long[] ppvObject = new long[1];
2877 int code = iaccessible.QueryInterface(COM.IIDIEnumVARIANT, ppvObject);
2878 if (code != COM.S_OK) return code;
2879 IEnumVARIANT ienumvariant = new IEnumVARIANT(ppvObject[0]);
2880 code = ienumvariant.Skip(celt);
2881 ienumvariant.Release();
2885 if (celt < 1 ) return COM.E_INVALIDARG;
2887 if (enumIndex > (variants.length - 1)) {
2888 enumIndex = variants.length - 1;
2894 /* IEnumVARIANT::Reset() the enumeration sequence to the beginning. */
2896 if (DEBUG) print(this + ".IEnumVARIANT::Reset");
2897 /* If there are no listeners, query the proxy
2898 * for its IEnumVariant, and tell it to Reset.
2900 if (iaccessible != null && accessibleControlListenersSize() == 0) {
2901 long[] ppvObject = new long[1];
2902 int code = (int)iaccessible.QueryInterface(COM.IIDIEnumVARIANT, ppvObject);
2903 if (code != COM.S_OK) return code;
2904 IEnumVARIANT ienumvariant = new IEnumVARIANT(ppvObject[0]);
2905 code = ienumvariant.Reset();
2906 ienumvariant.Release();
2914 /* IEnumVARIANT::Clone([out] ppEnum)
2915 * Ownership of ppEnum transfers from callee to caller so reference count on ppEnum
2916 * must be incremented before returning. The caller is responsible for releasing ppEnum.
2918 int Clone(long ppEnum) {
2919 if (DEBUG) print(this + ".IEnumVARIANT::Clone");
2920 /* If there are no listeners, query the proxy for
2921 * its IEnumVariant, and get the Clone from it.
2923 if (iaccessible != null && accessibleControlListenersSize() == 0) {
2924 long[] ppvObject = new long[1];
2925 int code = iaccessible.QueryInterface(COM.IIDIEnumVARIANT, ppvObject);
2926 if (code != COM.S_OK) return code;
2927 IEnumVARIANT ienumvariant = new IEnumVARIANT(ppvObject[0]);
2928 long [] pEnum = new long [1];
2929 code = ienumvariant.Clone(pEnum);
2930 ienumvariant.Release();
2931 OS.MoveMemory(ppEnum, pEnum, C.PTR_SIZEOF);
2935 if (ppEnum == 0) return COM.E_INVALIDARG;
2936 OS.MoveMemory(ppEnum, new long[] { objIEnumVARIANT.getAddress() }, C.PTR_SIZEOF);
2941 /* IAccessible2::get_nRelations([out] pNRelations) */
2942 int get_nRelations(long pNRelations) {
2943 int count = getRelationCount();
2944 if (DEBUG) print(this + ".IAccessible2::get_nRelations returning " + count + hresult(COM.S_OK));
2945 OS.MoveMemory(pNRelations, new int [] { count }, 4);
2949 /* IAccessible2::get_relation([in] relationIndex, [out] ppRelation) */
2950 int get_relation(int relationIndex, long ppRelation) {
2952 for (int type = 0; type < MAX_RELATION_TYPES; type++) {
2953 Relation relation = relations[type];
2954 if (relation != null) i++;
2955 if (i == relationIndex) {
2956 if (DEBUG) print(this + ".IAccessible2::get_relation(" + relationIndex + ") returning " + relation.getAddress() + hresult(COM.S_OK));
2958 OS.MoveMemory(ppRelation, new long[] { relation.getAddress() }, C.PTR_SIZEOF);
2962 if (DEBUG) print(this + ".IAccessible2::get_relation(" + relationIndex + ") returning" + hresult(COM.E_INVALIDARG));
2963 return COM.E_INVALIDARG;
2966 /* IAccessible2::get_relations([in] maxRelations, [out] ppRelations, [out] pNRelations) */
2967 int get_relations(int maxRelations, long ppRelations, long pNRelations) {
2969 for (int type = 0; type < MAX_RELATION_TYPES; type++) {
2970 if (count == maxRelations) break;
2971 Relation relation = relations[type];
2972 if (relation != null) {
2974 OS.MoveMemory(ppRelations + count * C.PTR_SIZEOF, new long[] { relation.getAddress() }, C.PTR_SIZEOF);
2978 if (DEBUG) print(this + ".IAccessible2::get_relations(" + maxRelations + ") returning " + count + hresult(COM.S_OK));
2979 OS.MoveMemory(pNRelations, new int [] { count }, 4);
2983 /* IAccessible2::get_role([out] pRole) */
2984 int get_role(long pRole) {
2985 int role = getRole();
2986 if (role == 0) role = getDefaultRole();
2987 if (DEBUG) print(this + ".IAccessible2::get_role() returning " + getRoleString(role) + hresult(COM.S_OK));
2988 OS.MoveMemory(pRole, new int [] { role }, 4);
2992 /* IAccessible2::scrollTo([in] scrollType) */
2993 int scrollTo(int scrollType) {
2994 if (DEBUG) print(this + ".IAccessible2::scrollTo");
2995 if (scrollType < ACC.SCROLL_TYPE_LEFT_EDGE || scrollType > ACC.SCROLL_TYPE_ANYWHERE) return COM.E_INVALIDARG;
2996 return COM.E_NOTIMPL;
2999 /* IAccessible2::scrollToPoint([in] coordinateType, [in] x, [in] y) */
3000 int scrollToPoint(int coordinateType, int x, int y) {
3001 if (DEBUG) print(this + ".IAccessible2::scrollToPoint");
3002 if (coordinateType != COM.IA2_COORDTYPE_SCREEN_RELATIVE) return COM.E_INVALIDARG;
3003 return COM.E_NOTIMPL;
3006 /* IAccessible2::get_groupPosition([out] pGroupLevel, [out] pSimilarItemsInGroup, [out] pPositionInGroup) */
3007 int get_groupPosition(long pGroupLevel, long pSimilarItemsInGroup, long pPositionInGroup) {
3008 if (control != null && control.isDisposed()) return COM.CO_E_OBJNOTCONNECTED;
3009 AccessibleAttributeEvent event = new AccessibleAttributeEvent(this);
3010 event.groupLevel = event.groupCount = event.groupIndex = -1;
3011 for (int i = 0; i < accessibleAttributeListenersSize(); i++) {
3012 AccessibleAttributeListener listener = accessibleAttributeListeners.get(i);
3013 listener.getAttributes(event);
3015 int groupLevel = (event.groupLevel != -1) ? event.groupLevel : 0;
3016 int similarItemsInGroup = (event.groupCount != -1) ? event.groupCount : 0;
3017 int positionInGroup = (event.groupIndex != -1) ? event.groupIndex : 0;
3018 if (similarItemsInGroup == 0 && positionInGroup == 0) {
3019 /* Determine position and count for radio buttons. */
3020 if (control instanceof Button && ((control.getStyle() & SWT.RADIO) != 0)) {
3021 Control [] children = control.getParent().getChildren();
3022 positionInGroup = 1;
3023 similarItemsInGroup = 1;
3024 for (int i = 0; i < children.length; i++) {
3025 Control child = children[i];
3026 if (child instanceof Button && ((child.getStyle() & SWT.RADIO) != 0)) {
3027 if (child == control) positionInGroup = similarItemsInGroup;
3028 else similarItemsInGroup++;
3033 OS.MoveMemory(pGroupLevel, new int [] { groupLevel }, 4);
3034 OS.MoveMemory(pSimilarItemsInGroup, new int [] { similarItemsInGroup }, 4);
3035 OS.MoveMemory(pPositionInGroup, new int [] { positionInGroup }, 4);
3036 if (DEBUG) print(this + ".IAccessible2::get_groupPosition() returning level=" + groupLevel + ", count=" + similarItemsInGroup + ", index=" + positionInGroup + hresult(groupLevel == 0 && similarItemsInGroup == 0 && positionInGroup == 0 ? COM.S_FALSE : COM.S_OK));
3037 if (groupLevel == 0 && similarItemsInGroup == 0 && positionInGroup == 0) return COM.S_FALSE;
3041 /* IAccessible2::get_states([out] pStates) */
3042 int get_states(long pStates) {
3043 AccessibleControlEvent event = new AccessibleControlEvent(this);
3044 event.childID = ACC.CHILDID_SELF;
3045 for (int i = 0; i < accessibleControlListenersSize(); i++) {
3046 AccessibleControlListener listener = accessibleControlListeners.get(i);
3047 listener.getState(event);
3049 int states = event.detail;
3051 if ((states & ACC.STATE_ACTIVE) != 0) ia2States |= COM.IA2_STATE_ACTIVE;
3052 if ((states & ACC.STATE_SINGLELINE) != 0) ia2States |= COM.IA2_STATE_SINGLE_LINE;
3053 if ((states & ACC.STATE_MULTILINE) != 0) ia2States |= COM.IA2_STATE_MULTI_LINE;
3054 if ((states & ACC.STATE_REQUIRED) != 0) ia2States |= COM.IA2_STATE_REQUIRED;
3055 if ((states & ACC.STATE_INVALID_ENTRY) != 0) ia2States |= COM.IA2_STATE_INVALID_ENTRY;
3056 if ((states & ACC.STATE_SUPPORTS_AUTOCOMPLETION) != 0) ia2States |= COM.IA2_STATE_SUPPORTS_AUTOCOMPLETION;
3058 /* If the role is text and there are TextExtendedListeners, then set IA2_STATE_EDITABLE.
3059 * Note that IA2_STATE_EDITABLE is not the opposite of STATE_READONLY.
3060 * Instead, it means: "has a caret, supports IAccessibleText, and is a text editing environment".
3062 if (getRole() == ACC.ROLE_TEXT && accessibleTextExtendedListenersSize() > 0) {
3063 ia2States |= COM.IA2_STATE_EDITABLE;
3065 if (DEBUG) print(this + ".IAccessible2::get_states returning" + getIA2StatesString(ia2States) + hresult(COM.S_OK));
3066 OS.MoveMemory(pStates, new int [] { ia2States }, 4);
3070 /* IAccessible2::get_extendedRole([out] pbstrExtendedRole) */
3071 int get_extendedRole(long pbstrExtendedRole) {
3072 /* This feature is not supported. */
3073 setString(pbstrExtendedRole, null);
3077 /* IAccessible2::get_localizedExtendedRole([out] pbstrLocalizedExtendedRole) */
3078 int get_localizedExtendedRole(long pbstrLocalizedExtendedRole) {
3079 /* This feature is not supported. */
3080 setString(pbstrLocalizedExtendedRole, null);
3084 /* IAccessible2::get_nExtendedStates([out] pNExtendedStates) */
3085 int get_nExtendedStates(long pNExtendedStates) {
3086 /* This feature is not supported. */
3087 OS.MoveMemory(pNExtendedStates, new int [] { 0 }, 4);
3091 /* IAccessible2::get_extendedStates([in] maxExtendedStates, [out] ppbstrExtendedStates, [out] pNExtendedStates) */
3092 int get_extendedStates(int maxExtendedStates, long ppbstrExtendedStates, long pNExtendedStates) {
3093 /* This feature is not supported. */
3094 setString(ppbstrExtendedStates, null);
3095 OS.MoveMemory(pNExtendedStates, new int [] { 0 }, 4);
3099 /* IAccessible2::get_localizedExtendedStates([in] maxLocalizedExtendedStates, [out] ppbstrLocalizedExtendedStates, [out] pNLocalizedExtendedStates) */
3100 int get_localizedExtendedStates(int maxLocalizedExtendedStates, long ppbstrLocalizedExtendedStates, long pNLocalizedExtendedStates) {
3101 /* This feature is not supported. */
3102 setString(ppbstrLocalizedExtendedStates, null);
3103 OS.MoveMemory(pNLocalizedExtendedStates, new int [] { 0 }, 4);
3107 /* IAccessible2::get_uniqueID([out] pUniqueID) */
3108 int get_uniqueID(long pUniqueID) {
3109 if (uniqueID == -1) uniqueID = UniqueID--;
3110 if (DEBUG) print(this + ".IAccessible2::get_uniqueID returning " + uniqueID + hresult(COM.S_OK));
3111 OS.MoveMemory(pUniqueID, new long [] { uniqueID }, 4);
3115 /* IAccessible2::get_windowHandle([out] pWindowHandle) */
3116 int get_windowHandle(long pWindowHandle) {
3117 if (DEBUG) print(this + ".IAccessible2::get_windowHandle returning " + control.handle + hresult(COM.S_OK));
3118 OS.MoveMemory(pWindowHandle, new long [] { control.handle }, C.PTR_SIZEOF);
3122 /* IAccessible2::get_indexInParent([out] pIndexInParent) */
3123 int get_indexInParent(long pIndexInParent) {
3124 AccessibleControlEvent event = new AccessibleControlEvent(this);
3125 event.childID = ACC.CHILDID_CHILD_INDEX;
3127 for (int i = 0; i < accessibleControlListenersSize(); i++) {
3128 AccessibleControlListener listener = accessibleControlListeners.get(i);
3129 listener.getChild(event);
3131 int indexInParent = event.detail;
3132 if (indexInParent == -1) {
3133 // /* The application did not implement CHILDID_CHILD_INDEX,
3134 // * so determine the index by looping through the parent's
3135 // * children looking for this Accessible. This may be slow,
3136 // * so applications are strongly encouraged to implement
3137 // * getChild for CHILDID_CHILD_INDEX.
3139 // // TODO: finish this. See also get_groupPosition
3140 // this won't work because VARIANT.sizeof isn't big enough on 64-bit machines.
3141 // just create an long [] ppdispParent - it's not a variant anyhow...
3142 // long ppdispParent = OS.GlobalAlloc (OS.GMEM_FIXED | OS.GMEM_ZEROINIT, VARIANT.sizeof);
3143 // int code = get_accParent(ppdispParent);
3144 // if (code == COM.S_OK) {
3145 // VARIANT v = getVARIANT(ppdispParent);
3146 // if (v.vt == COM.VT_DISPATCH) {
3147 // IAccessible accParent = new IAccessible(v.lVal);
3148 // long pcountChildren = OS.GlobalAlloc (OS.GMEM_FIXED | OS.GMEM_ZEROINIT, 4);
3149 // code = accParent.get_accChildCount(pcountChildren);
3150 // if (code == COM.S_OK) {
3151 // int [] childCount = new int[1];
3152 // OS.MoveMemory(childCount, pcountChildren, 4);
3153 // int[] pcObtained = new int[1];
3154 // long rgVarChildren = OS.GlobalAlloc (OS.GMEM_FIXED | OS.GMEM_ZEROINIT, VARIANT.sizeof * childCount[0]);
3155 // System.out.println("Asking for AccessibleChildren");
3156 // code = COM.AccessibleChildren(accParent.getAddress(), 0, childCount[0], rgVarChildren, pcObtained);
3157 // if (code == COM.S_OK) {
3158 // System.out.println("Got this far - now what?");
3160 // System.out.println("AccessibleChildren failed? code=" + code);
3162 // OS.GlobalFree(rgVarChildren);
3164 // System.out.println("get_accChildCount failed? code=" + code);
3166 // OS.GlobalFree (pcountChildren);
3168 // System.out.println("get_accParent did not return VT_DISPATCH? It returned: " + v.vt);
3170 // COM.VariantClear(ppdispParent);
3171 // OS.GlobalFree (ppdispParent);
3173 // System.out.println("get_accParent failed? code=" + code);
3177 if (DEBUG) print(this + ".IAccessible2::get_indexInParent returning " + indexInParent + hresult(indexInParent == -1 ? COM.S_FALSE : COM.S_OK));
3178 OS.MoveMemory(pIndexInParent, new int [] { indexInParent }, 4);
3179 return indexInParent == -1 ? COM.S_FALSE : COM.S_OK;
3182 /* IAccessible2::get_locale([out] pLocale) */
3183 int get_locale(long pLocale) {
3184 /* Return the default locale for the JVM. */
3185 Locale locale = Locale.getDefault();
3187 char[] data = (locale.getLanguage()+"\0").toCharArray();
3188 long ptr = COM.SysAllocString(data);
3189 OS.MoveMemory(pLocale, new long[] {ptr}, C.PTR_SIZEOF);
3191 data = (locale.getCountry()+"\0").toCharArray();
3192 ptr = COM.SysAllocString(data);
3193 OS.MoveMemory(pLocale + C.PTR_SIZEOF, new long[] {ptr}, C.PTR_SIZEOF);
3195 data = (locale.getVariant()+"\0").toCharArray();
3196 ptr = COM.SysAllocString(data);
3197 OS.MoveMemory(pLocale + 2 * C.PTR_SIZEOF, new long[] {ptr}, C.PTR_SIZEOF);
3199 if (DEBUG) print(this + ".IAccessible2::get_locale() returning" + hresult(COM.S_OK));
3203 /* IAccessible2::get_attributes([out] pbstrAttributes) */
3204 int get_attributes(long pbstrAttributes) {
3205 AccessibleAttributeEvent event = new AccessibleAttributeEvent(this);
3206 for (int i = 0; i < accessibleAttributeListenersSize(); i++) {
3207 AccessibleAttributeListener listener = accessibleAttributeListeners.get(i);
3208 listener.getAttributes(event);
3210 String attributes = "";
3211 attributes += "margin-left:" + event.leftMargin + ";";
3212 attributes += "margin-top:" + event.topMargin + ";";
3213 attributes += "margin-right:" + event.rightMargin + ";";
3214 attributes += "margin-bottom:" + event.bottomMargin + ";";
3215 if (event.tabStops != null) {
3216 for (int i = 0; i < event.tabStops.length; i++) {
3217 attributes += "tab-stop:position=" + event.tabStops[i] + ";";
3220 if (event.justify) attributes += "text-align:justify;";
3221 attributes += "text-align:" + (event.alignment == SWT.LEFT ? "left" : event.alignment == SWT.RIGHT ? "right" : "center") + ";";
3222 attributes += "text-indent:" + event.indent + ";";
3223 if (event.attributes != null) {
3224 for (int i = 0; i + 1 < event.attributes.length; i += 2) {
3225 attributes += event.attributes[i] + ":" + event.attributes[i+1] + ";";
3229 /* If the role is text, then specify the text model for JAWS. */
3230 if (getRole() == ACC.ROLE_TEXT) {
3231 attributes += "text-model:a1;";
3233 if (DEBUG) print(this + ".IAccessible2::get_attributes() returning " + attributes + hresult(attributes.length() == 0 ? COM.S_FALSE : COM.S_OK));
3234 setString(pbstrAttributes, attributes);
3235 if (attributes.length() == 0) return COM.S_FALSE;
3239 /* IAccessibleAction::get_nActions([out] pNActions) */
3240 int get_nActions(long pNActions) {
3241 AccessibleActionEvent event = new AccessibleActionEvent(this);
3242 for (int i = 0; i < accessibleActionListenersSize(); i++) {
3243 AccessibleActionListener listener = accessibleActionListeners.get(i);
3244 listener.getActionCount(event);
3246 if (DEBUG) print(this + ".IAccessibleAction::get_nActions() returning " + event.count + hresult(COM.S_OK));
3247 OS.MoveMemory(pNActions, new int [] { event.count }, 4);
3251 /* IAccessibleAction::doAction([in] actionIndex) */
3252 int doAction(int actionIndex) {
3253 AccessibleActionEvent event = new AccessibleActionEvent(this);
3254 event.index = actionIndex;
3255 for (int i = 0; i < accessibleActionListenersSize(); i++) {
3256 AccessibleActionListener listener = accessibleActionListeners.get(i);
3257 listener.doAction(event);
3259 if (DEBUG) print(this + ".IAccessibleAction::doAction(" + actionIndex + ") returning" + hresult(event.result == null || !event.result.equals(ACC.OK) ? COM.E_INVALIDARG : COM.S_OK));
3260 if (event.result == null || !event.result.equals(ACC.OK)) return COM.E_INVALIDARG;
3264 /* IAccessibleAction::get_description([in] actionIndex, [out] pbstrDescription) */
3265 int get_description(int actionIndex, long pbstrDescription) {
3266 AccessibleActionEvent event = new AccessibleActionEvent(this);
3267 event.index = actionIndex;
3268 for (int i = 0; i < accessibleActionListenersSize(); i++) {
3269 AccessibleActionListener listener = accessibleActionListeners.get(i);
3270 listener.getDescription(event);
3272 if (DEBUG) print(this + ".IAccessibleAction::get_description(" + actionIndex + ") returning " + event.result + hresult(event.result == null || event.result.length() == 0 ? COM.S_FALSE : COM.S_OK));
3273 setString(pbstrDescription, event.result);
3274 if (event.result == null || event.result.length() == 0) return COM.S_FALSE;
3278 /* IAccessibleAction::get_keyBinding([in] actionIndex, [in] nMaxBindings, [out] ppbstrKeyBindings, [out] pNBindings) */
3279 int get_keyBinding(int actionIndex, int nMaxBindings, long ppbstrKeyBindings, long pNBindings) {
3280 AccessibleActionEvent event = new AccessibleActionEvent(this);
3281 event.index = actionIndex;
3282 for (int i = 0; i < accessibleActionListenersSize(); i++) {
3283 AccessibleActionListener listener = accessibleActionListeners.get(i);
3284 listener.getKeyBinding(event);
3286 String keyBindings = event.result;
3288 if (keyBindings != null) length = keyBindings.length();
3289 int i = 0, count = 0;
3290 while (i < length) {
3291 if (count == nMaxBindings) break;
3292 int j = keyBindings.indexOf(';', i);
3293 if (j == -1) j = length;
3294 String keyBinding = keyBindings.substring(i, j);
3295 if (keyBinding.length() > 0) {
3296 setString(ppbstrKeyBindings + count * C.PTR_SIZEOF, keyBinding);
3301 if (DEBUG) print(this + ".IAccessibleAction::get_keyBinding(index=" + actionIndex + " max=" + nMaxBindings + ") returning count=" + count + hresult(count == 0 ? COM.S_FALSE : COM.S_OK));
3302 OS.MoveMemory(pNBindings, new int [] { count }, 4);
3304 setString(ppbstrKeyBindings, null);
3310 /* IAccessibleAction::get_name([in] actionIndex, [out] pbstrName) */
3311 int get_name(int actionIndex, long pbstrName) {
3312 AccessibleActionEvent event = new AccessibleActionEvent(this);
3313 event.index = actionIndex;
3314 event.localized = false;
3315 for (int i = 0; i < accessibleActionListenersSize(); i++) {
3316 AccessibleActionListener listener = accessibleActionListeners.get(i);
3317 listener.getName(event);
3319 if (DEBUG) print(this + ".IAccessibleAction::get_name(" + actionIndex + ") returning " + event.result + hresult(event.result == null || event.result.length() == 0 ? COM.S_FALSE : COM.S_OK));
3320 if (event.result == null || event.result.length() == 0) {
3321 setString(pbstrName, null);
3324 setString(pbstrName, event.result);
3328 /* IAccessibleAction::get_localizedName([in] actionIndex, [out] pbstrLocalizedName) */
3329 int get_localizedName(int actionIndex, long pbstrLocalizedName) {
3330 AccessibleActionEvent event = new AccessibleActionEvent(this);
3331 event.index = actionIndex;
3332 event.localized = true;
3333 for (int i = 0; i < accessibleActionListenersSize(); i++) {
3334 AccessibleActionListener listener = accessibleActionListeners.get(i);
3335 listener.getName(event);
3337 if (DEBUG) print(this + ".IAccessibleAction::get_localizedName(" + actionIndex + ") returning " + event.result + hresult(event.result == null || event.result.length() == 0 ? COM.S_FALSE : COM.S_OK));
3338 if (event.result == null || event.result.length() == 0) {
3339 setString(pbstrLocalizedName, null);
3342 setString(pbstrLocalizedName, event.result);
3346 /* IAccessibleApplication::get_appName([out] pbstrName) */
3347 int get_appName(long pbstrName) {
3348 String appName = Display.getAppName();
3349 if (DEBUG) print(this + ".IAccessibleApplication::get_appName() returning " + appName + hresult(appName == null || appName.length() == 0 ? COM.S_FALSE : COM.S_OK));
3350 if (appName == null || appName.length() == 0) {
3351 setString(pbstrName, null);
3354 setString(pbstrName, appName);
3358 /* IAccessibleApplication::get_appVersion([out] pbstrVersion) */
3359 int get_appVersion(long pbstrVersion) {
3360 String appVersion = Display.getAppVersion();
3361 if (DEBUG) print(this + ".IAccessibleApplication::get_appVersion() returning" + appVersion + hresult(appVersion == null || appVersion.length() == 0 ? COM.S_FALSE : COM.S_OK));
3362 if (appVersion == null || appVersion.length() == 0) {
3363 setString(pbstrVersion, null);
3366 setString(pbstrVersion, appVersion);
3370 /* IAccessibleApplication::get_toolkitName([out] pbstrName) */
3371 int get_toolkitName(long pbstrName) {
3372 String toolkitName = "SWT";
3373 if (DEBUG) print(this + ".IAccessibleApplication::get_toolkitName() returning" + toolkitName + hresult(COM.S_OK));
3374 setString(pbstrName, toolkitName);
3378 /* IAccessibleApplication::get_toolkitVersion([out] pbstrVersion) */
3379 int get_toolkitVersion(long pbstrVersion) {
3380 String toolkitVersion = "" + SWT.getVersion(); //$NON-NLS-1$
3381 if (DEBUG) print(this + ".IAccessibleApplication::get_toolkitVersion() returning" + toolkitVersion + hresult(COM.S_OK));
3382 setString(pbstrVersion, toolkitVersion);
3386 // The following 3 method are intentionally commented. We are not providing IAccessibleComponent at this time.
3387 // /* IAccessibleComponent::get_locationInParent([out] pX, [out] pY) */
3388 // int get_locationInParent(long pX, long pY) {
3389 // if (DEBUG) print(this + ".IAccessibleComponent::get_locationInParent");
3390 // // TO DO: support transparently (hard for lightweight parents - screen vs. parent coords)
3391 // AccessibleControlEvent event = new AccessibleControlEvent(this);
3392 // for (int i = 0; i < accessibleControlListenersSize(); i++) {
3393 // AccessibleControlListener listener = (AccessibleControlListener) accessibleControlListeners.get(i);
3394 // listener.getLocation (event);
3396 // COM.MoveMemory(pX, new int [] { event.x }, 4);
3397 // COM.MoveMemory(pY, new int [] { event.y }, 4);
3401 // /* IAccessibleComponent::get_foreground([out] pForeground) */
3402 // int get_foreground(long pForeground) {
3403 // Color color = control.getForeground();
3404 // if (DEBUG) print(this + ".IAccessibleComponent::get_foreground returning " + color.handle);
3405 // COM.MoveMemory(pForeground, new int [] { color.handle }, 4);
3409 // /* IAccessibleComponent::get_background([out] pBackground) */
3410 // int get_background(long pBackground) {
3411 // Color color = control.getBackground();
3412 // if (DEBUG) print(this + ".IAccessibleComponent::get_background returning " + color.handle);
3413 // COM.MoveMemory(pBackground, new int [] { color.handle }, 4);
3417 /* IAccessibleEditableText::copyText([in] startOffset, [in] endOffset) */
3418 int copyText(int startOffset, int endOffset) {
3419 if (DEBUG) print(this + ".IAccessibleEditableText::copyText, start=" + startOffset + ", end=" + endOffset);
3420 AccessibleEditableTextEvent event = new AccessibleEditableTextEvent(this);
3421 event.start = startOffset == COM.IA2_TEXT_OFFSET_LENGTH ? getCharacterCount() : startOffset;
3422 event.end = endOffset == COM.IA2_TEXT_OFFSET_LENGTH ? getCharacterCount() : endOffset;
3423 for (int i = 0; i < accessibleEditableTextListenersSize(); i++) {
3424 AccessibleEditableTextListener listener = accessibleEditableTextListeners.get(i);
3425 listener.copyText(event);
3427 if (event.result == null || !event.result.equals(ACC.OK)) return COM.E_INVALIDARG;
3431 /* IAccessibleEditableText::deleteText([in] startOffset, [in] endOffset) */
3432 int deleteText(int startOffset, int endOffset) {
3433 if (DEBUG) print(this + ".IAccessibleEditableText::deleteText, start=" + startOffset + ", end=" + endOffset);
3434 AccessibleEditableTextEvent event = new AccessibleEditableTextEvent(this);
3435 event.start = startOffset == COM.IA2_TEXT_OFFSET_LENGTH ? getCharacterCount() : startOffset;
3436 event.end = endOffset == COM.IA2_TEXT_OFFSET_LENGTH ? getCharacterCount() : endOffset;
3438 for (int i = 0; i < accessibleEditableTextListenersSize(); i++) {
3439 AccessibleEditableTextListener listener = accessibleEditableTextListeners.get(i);
3440 listener.replaceText(event);
3442 if (event.result == null || !event.result.equals(ACC.OK)) return COM.E_INVALIDARG;
3446 /* IAccessibleEditableText::insertText([in] offset, [in] pbstrText) */
3447 int insertText(int offset, long pbstrText) {
3448 if (DEBUG) print(this + ".IAccessibleEditableText::insertText, offset=" + offset + ", pbstrText=" + pbstrText);
3449 AccessibleEditableTextEvent event = new AccessibleEditableTextEvent(this);
3450 event.start = offset == COM.IA2_TEXT_OFFSET_LENGTH ? getCharacterCount() : offset;
3451 event.end = event.start;
3452 event.string = getString(pbstrText);
3453 for (int i = 0; i < accessibleEditableTextListenersSize(); i++) {
3454 AccessibleEditableTextListener listener = accessibleEditableTextListeners.get(i);
3455 listener.replaceText(event);
3457 if (event.result == null || !event.result.equals(ACC.OK)) return COM.E_INVALIDARG;
3461 /* IAccessibleEditableText::cutText([in] startOffset, [in] endOffset) */
3462 int cutText(int startOffset, int endOffset) {
3463 if (DEBUG) print(this + ".IAccessibleEditableText::cutText, start=" + startOffset + ", end=" + endOffset);
3464 AccessibleEditableTextEvent event = new AccessibleEditableTextEvent(this);
3465 event.start = startOffset == COM.IA2_TEXT_OFFSET_LENGTH ? getCharacterCount() : startOffset;
3466 event.end = endOffset == COM.IA2_TEXT_OFFSET_LENGTH ? getCharacterCount() : endOffset;
3467 for (int i = 0; i < accessibleEditableTextListenersSize(); i++) {
3468 AccessibleEditableTextListener listener = accessibleEditableTextListeners.get(i);
3469 listener.cutText(event);
3471 if (event.result == null || !event.result.equals(ACC.OK)) return COM.E_INVALIDARG;
3475 /* IAccessibleEditableText::pasteText([in] offset) */
3476 int pasteText(int offset) {
3477 if (DEBUG) print(this + ".IAccessibleEditableText::pasteText, offset=" + offset);
3478 AccessibleEditableTextEvent event = new AccessibleEditableTextEvent(this);
3479 event.start = offset == COM.IA2_TEXT_OFFSET_LENGTH ? getCharacterCount() : offset;
3480 event.end = event.start;
3481 for (int i = 0; i < accessibleEditableTextListenersSize(); i++) {
3482 AccessibleEditableTextListener listener = accessibleEditableTextListeners.get(i);
3483 listener.pasteText(event);
3485 if (event.result == null || !event.result.equals(ACC.OK)) return COM.E_INVALIDARG;
3489 /* IAccessibleEditableText::replaceText([in] startOffset, [in] endOffset, [in] pbstrText) */
3490 int replaceText(int startOffset, int endOffset, long pbstrText) {
3491 if (DEBUG) print(this + ".IAccessibleEditableText::replaceText, start=" + startOffset + ", end=" + endOffset + ", pbstrText=" + pbstrText);
3492 AccessibleEditableTextEvent event = new AccessibleEditableTextEvent(this);
3493 event.start = startOffset == COM.IA2_TEXT_OFFSET_LENGTH ? getCharacterCount() : startOffset;
3494 event.end = endOffset == COM.IA2_TEXT_OFFSET_LENGTH ? getCharacterCount() : endOffset;
3495 event.string = getString(pbstrText);
3496 for (int i = 0; i < accessibleEditableTextListenersSize(); i++) {
3497 AccessibleEditableTextListener listener = accessibleEditableTextListeners.get(i);
3498 listener.replaceText(event);
3500 if (event.result == null || !event.result.equals(ACC.OK)) return COM.E_INVALIDARG;
3504 /* IAccessibleEditableText::setAttributes([in] startOffset, [in] endOffset, [in] pbstrAttributes) */
3505 int setAttributes(int startOffset, int endOffset, long pbstrAttributes) {
3506 if (DEBUG) print(this + ".IAccessibleEditableText::setAttributes, start=" + startOffset + ", end=" + endOffset + ", pbstrAttributes=" + pbstrAttributes);
3507 AccessibleTextAttributeEvent event = new AccessibleTextAttributeEvent(this);
3508 String string = getString(pbstrAttributes);
3509 if (string != null && string.length() > 0) {
3510 event.start = startOffset == COM.IA2_TEXT_OFFSET_LENGTH ? getCharacterCount() : startOffset;
3511 event.end = endOffset == COM.IA2_TEXT_OFFSET_LENGTH ? getCharacterCount() : endOffset;
3512 TextStyle style = new TextStyle();
3513 FontData fontData = null;
3514 int points = 10; // used for default rise
3515 String [] attributes = new String [0];
3517 int end = string.indexOf(';');
3518 while (end != -1 && end < string.length()) {
3519 String keyValue = string.substring(begin, end).trim();
3520 int colonIndex = keyValue.indexOf(':');
3521 if (colonIndex != -1 && colonIndex + 1 < keyValue.length()) {
3522 String [] newAttributes = new String [attributes.length + 2];
3523 System.arraycopy (attributes, 0, newAttributes, 0, attributes.length);
3524 newAttributes[attributes.length] = keyValue.substring(0, colonIndex).trim();
3525 newAttributes[attributes.length + 1] = keyValue.substring(colonIndex + 1).trim();
3526 attributes = newAttributes;
3529 end = string.indexOf(';', begin);
3531 for (int i = 0; i+1 < attributes.length; i+=2) {
3532 String key = attributes[i];
3533 String value = attributes[i+1];
3534 if (key.equals("text-position")) {
3535 if (value.equals("super")) style.rise = points / 2;
3536 else if (value.equals("sub")) style.rise = - points / 2;
3537 } else if (key.equals("text-underline-type")) {
3538 style.underline = true;
3539 if (value.equals("double")) style.underlineStyle = SWT.UNDERLINE_DOUBLE;
3540 else if (value.equals("single")) {
3541 if (style.underlineStyle != SWT.UNDERLINE_SQUIGGLE && style.underlineStyle != SWT.UNDERLINE_ERROR) {
3542 style.underlineStyle = SWT.UNDERLINE_SINGLE;
3545 } else if (key.equals("text-underline-style") && value.equals("wave")) {
3546 style.underline = true;
3547 style.underlineStyle = SWT.UNDERLINE_SQUIGGLE;
3548 } else if (key.equals("invalid") && value.equals("true")) {
3549 style.underline = true;
3550 style.underlineStyle = SWT.UNDERLINE_ERROR;
3551 } else if (key.equals("text-line-through-type")) {
3552 if (value.equals("single")) style.strikeout = true;
3553 } else if (key.equals("font-family")) {
3554 if (fontData == null) fontData = new FontData ();
3555 fontData.setName(value);
3556 } else if (key.equals("font-size")) {
3558 String pts = value.endsWith("pt") ? value.substring(0, value.length() - 2) : value;
3559 points = Integer.parseInt(pts);
3560 if (fontData == null) fontData = new FontData ();
3561 fontData.setHeight(points);
3562 if (style.rise > 0) style.rise = points / 2;
3563 else if (style.rise < 0) style.rise = - points / 2;
3564 } catch (NumberFormatException ex) {}
3565 } else if (key.equals("font-style")) {
3566 if (value.equals("italic")) {
3567 if (fontData == null) fontData = new FontData ();
3568 fontData.setStyle(fontData.getStyle() | SWT.ITALIC);
3570 } else if (key.equals("font-weight")) {
3571 if (value.equals("bold")) {
3572 if (fontData == null) fontData = new FontData ();
3573 fontData.setStyle(fontData.getStyle() | SWT.BOLD);
3576 int weight = Integer.parseInt(value);
3577 if (fontData == null) fontData = new FontData ();
3578 if (weight > 400) fontData.setStyle(fontData.getStyle() | SWT.BOLD);
3579 } catch (NumberFormatException ex) {}
3581 } else if (key.equals("color")) {
3582 style.foreground = colorFromString(value);
3583 } else if (key.equals("background-color")) {
3584 style.background = colorFromString(value);
3587 if (attributes.length > 0) {
3588 event.attributes = attributes;
3589 if (fontData != null) {
3590 style.font = new Font(control.getDisplay(), fontData);
3592 if (!style.equals(new TextStyle())) event.textStyle = style;
3594 for (int i = 0; i < accessibleEditableTextListenersSize(); i++) {
3595 AccessibleEditableTextListener listener = accessibleEditableTextListeners.get(i);
3596 listener.setTextAttributes(event);
3598 if (style.font != null) {
3599 style.font.dispose();
3601 if (style.foreground != null) {
3602 style.foreground.dispose();
3604 if (style.background != null) {
3605 style.background.dispose();
3608 if (event.result == null || !event.result.equals(ACC.OK)) return COM.E_INVALIDARG;
3612 /* IAccessibleHyperlink::get_anchor([in] index, [out] pAnchor) */
3613 int get_anchor(int index, long pAnchor) {
3614 if (DEBUG) print(this + ".IAccessibleHyperlink::get_anchor");
3615 AccessibleHyperlinkEvent event = new AccessibleHyperlinkEvent(this);
3616 event.index = index;
3617 for (int i = 0; i < accessibleHyperlinkListenersSize(); i++) {
3618 AccessibleHyperlinkListener listener = accessibleHyperlinkListeners.get(i);
3619 listener.getAnchor(event);
3621 Accessible accessible = event.accessible;
3622 if (accessible != null) {
3623 accessible.AddRef();
3624 setPtrVARIANT(pAnchor, COM.VT_DISPATCH, accessible.getAddress());
3627 setStringVARIANT(pAnchor, event.result);
3628 if (event.result == null) return COM.S_FALSE;
3632 /* IAccessibleHyperlink::get_anchorTarget([in] index, [out] pAnchorTarget) */
3633 int get_anchorTarget(int index, long pAnchorTarget) {
3634 if (DEBUG) print(this + ".IAccessibleHyperlink::get_anchorTarget");
3635 AccessibleHyperlinkEvent event = new AccessibleHyperlinkEvent(this);
3636 event.index = index;
3637 for (int i = 0; i < accessibleHyperlinkListenersSize(); i++) {
3638 AccessibleHyperlinkListener listener = accessibleHyperlinkListeners.get(i);
3639 listener.getAnchorTarget(event);
3641 Accessible accessible = event.accessible;
3642 if (accessible != null) {
3643 accessible.AddRef();
3644 setPtrVARIANT(pAnchorTarget, COM.VT_DISPATCH, accessible.getAddress());
3647 setStringVARIANT(pAnchorTarget, event.result);
3648 if (event.result == null) return COM.S_FALSE;
3652 /* IAccessibleHyperlink::get_startIndex([out] pIndex) */
3653 int get_startIndex(long pIndex) {
3654 if (DEBUG) print(this + ".IAccessibleHyperlink::get_startIndex");
3655 AccessibleHyperlinkEvent event = new AccessibleHyperlinkEvent(this);
3656 for (int i = 0; i < accessibleHyperlinkListenersSize(); i++) {
3657 AccessibleHyperlinkListener listener = accessibleHyperlinkListeners.get(i);
3658 listener.getStartIndex(event);
3660 OS.MoveMemory(pIndex, new int [] { event.index }, 4);
3664 /* IAccessibleHyperlink::get_endIndex([out] pIndex) */
3665 int get_endIndex(long pIndex) {
3666 if (DEBUG) print(this + ".IAccessibleHyperlink::get_endIndex");
3667 AccessibleHyperlinkEvent event = new AccessibleHyperlinkEvent(this);
3668 for (int i = 0; i < accessibleHyperlinkListenersSize(); i++) {
3669 AccessibleHyperlinkListener listener = accessibleHyperlinkListeners.get(i);
3670 listener.getEndIndex(event);
3672 OS.MoveMemory(pIndex, new int [] { event.index }, 4);
3676 /* IAccessibleHyperlink::get_valid([out] pValid) */
3677 int get_valid(long pValid) {
3679 return COM.E_NOTIMPL;
3682 /* IAccessibleHypertext::get_nHyperlinks([out] pHyperlinkCount) */
3683 int get_nHyperlinks(long pHyperlinkCount) {
3684 if (DEBUG) print(this + ".IAccessibleHypertext::get_nHyperlinks");
3685 AccessibleTextEvent event = new AccessibleTextEvent(this);
3686 for (int i = 0; i < accessibleTextExtendedListenersSize(); i++) {
3687 AccessibleTextExtendedListener listener = accessibleTextExtendedListeners.get(i);
3688 listener.getHyperlinkCount(event);
3690 OS.MoveMemory(pHyperlinkCount, new int [] { event.count }, 4);
3694 /* IAccessibleHypertext::get_hyperlink([in] index, [out] ppHyperlink) */
3695 int get_hyperlink(int index, long ppHyperlink) {
3696 if (DEBUG) print(this + ".IAccessibleHypertext::get_hyperlink");
3697 AccessibleTextEvent event = new AccessibleTextEvent(this);
3698 event.index = index;
3699 for (int i = 0; i < accessibleTextExtendedListenersSize(); i++) {
3700 AccessibleTextExtendedListener listener = accessibleTextExtendedListeners.get(i);
3701 listener.getHyperlink(event);
3703 Accessible accessible = event.accessible;
3704 if (accessible == null) {
3705 setIntVARIANT(ppHyperlink, COM.VT_EMPTY, 0);
3706 return COM.E_INVALIDARG;
3708 accessible.AddRef();
3709 OS.MoveMemory(ppHyperlink, new long[] { accessible.getAddress() }, C.PTR_SIZEOF);
3713 /* IAccessibleHypertext::get_hyperlinkIndex([in] charIndex, [out] pHyperlinkIndex) */
3714 int get_hyperlinkIndex(int charIndex, long pHyperlinkIndex) {
3715 if (DEBUG) print(this + ".IAccessibleHypertext::get_hyperlinkIndex");
3716 AccessibleTextEvent event = new AccessibleTextEvent(this);
3717 event.offset = charIndex;
3719 for (int i = 0; i < accessibleTextExtendedListenersSize(); i++) {
3720 AccessibleTextExtendedListener listener = accessibleTextExtendedListeners.get(i);
3721 listener.getHyperlinkIndex(event);
3723 OS.MoveMemory(pHyperlinkIndex, new int [] { event.index }, 4);
3724 if (event.index == -1) return COM.S_FALSE;
3728 // The following 3 method are intentionally commented. We are not providing IAccessibleImage at this time.
3729 // /* IAccessibleImage::get_description([out] pbstrDescription) */
3730 // int get_description(long pbstrDescription) {
3731 // if (DEBUG) print(this + ".IAccessibleImage::get_description");
3732 // // TO DO: Does it make sense to just reuse description?
3733 // AccessibleEvent event = new AccessibleEvent(this);
3734 // event.childID = ACC.CHILDID_SELF;
3735 // for (int i = 0; i < accessibleListenersSize(); i++) {
3736 // AccessibleListener listener = (AccessibleListener) accessibleListeners.get(i);
3737 // listener.getDescription(event);
3739 // setString(pbstrDescription, event.result);
3740 // if (event.result == null) return COM.S_FALSE;
3744 // /* IAccessibleImage::get_imagePosition([in] coordinateType, [out] pX, [out] pY) */
3745 // int get_imagePosition(int coordinateType, long pX, long pY) {
3746 // if (DEBUG) print(this + ".IAccessibleImage::get_imagePosition");
3747 // // TO DO: does it make sense to just reuse getLocation?
3748 // AccessibleControlEvent event = new AccessibleControlEvent(this);
3749 // event.childID = ACC.CHILDID_SELF;
3750 // for (int i = 0; i < accessibleControlListenersSize(); i++) {
3751 // AccessibleControlListener listener = (AccessibleControlListener) accessibleControlListeners.get(i);
3752 // listener.getLocation(event);
3754 // COM.MoveMemory(pX, new int [] { event.x }, 4);
3755 // COM.MoveMemory(pY, new int [] { event.y }, 4);
3759 // /* IAccessibleImage::get_imageSize([out] pHeight, [out] pWidth) */
3760 // int get_imageSize(long pHeight, long pWidth) {
3761 // if (DEBUG) print(this + ".IAccessibleImage::get_imageSize");
3762 // // TO DO: does it make sense to just reuse getLocation?
3763 // AccessibleControlEvent event = new AccessibleControlEvent(this);
3764 // for (int i = 0; i < accessibleControlListenersSize(); i++) {
3765 // AccessibleControlListener listener = (AccessibleControlListener) accessibleControlListeners.get(i);
3766 // listener.getLocation(event);
3768 // COM.MoveMemory(pHeight, new int [] { event.height }, 4);
3769 // COM.MoveMemory(pWidth, new int [] { event.width }, 4);
3773 /* IAccessibleTable2::get_cellAt([in] row, [in] column, [out] ppCell) */
3774 int get_cellAt(int row, int column, long ppCell) {
3775 AccessibleTableEvent event = new AccessibleTableEvent(this);
3777 event.column = column;
3778 for (int i = 0; i < accessibleTableListenersSize(); i++) {
3779 AccessibleTableListener listener = accessibleTableListeners.get(i);
3780 listener.getCell(event);
3782 Accessible accessible = event.accessible;
3783 if (DEBUG) print(this + ".IAccessibleTable2::get_cellAt(row=" + row + ", column=" + column + ") returning " + accessible);
3784 if (accessible == null) return COM.E_INVALIDARG;
3785 accessible.AddRef();
3786 OS.MoveMemory(ppCell, new long[] { accessible.getAddress() }, C.PTR_SIZEOF);
3790 /* IAccessibleTable2::get_caption([out] ppAccessible) */
3791 int get_caption(long ppAccessible) {
3792 AccessibleTableEvent event = new AccessibleTableEvent(this);
3793 for (int i = 0; i < accessibleTableListenersSize(); i++) {
3794 AccessibleTableListener listener = accessibleTableListeners.get(i);
3795 listener.getCaption(event);
3797 Accessible accessible = event.accessible;
3798 if (DEBUG) print(this + ".IAccessibleTable2::get_caption() returning " + accessible);
3799 if (accessible == null) {
3800 OS.MoveMemory(ppAccessible, new long[] { 0 }, C.PTR_SIZEOF);
3803 accessible.AddRef();
3804 OS.MoveMemory(ppAccessible, new long[] { accessible.getAddress() }, C.PTR_SIZEOF);
3808 /* IAccessibleTable2::get_columnDescription([in] column, [out] pbstrDescription) */
3809 int get_columnDescription(int column, long pbstrDescription) {
3810 AccessibleTableEvent event = new AccessibleTableEvent(this);
3811 event.column = column;
3812 for (int i = 0; i < accessibleTableListenersSize(); i++) {
3813 AccessibleTableListener listener = accessibleTableListeners.get(i);
3814 listener.getColumnDescription(event);
3816 if (DEBUG) print(this + ".IAccessibleTable2::get_columnDescription(column=" + column + ") returning " + event.result);
3817 setString(pbstrDescription, event.result);
3818 if (event.result == null) return COM.S_FALSE;
3822 /* IAccessibleTable2::get_nColumns([out] pColumnCount) */
3823 int get_nColumns(long pColumnCount) {
3824 AccessibleTableEvent event = new AccessibleTableEvent(this);
3825 for (int i = 0; i < accessibleTableListenersSize(); i++) {
3826 AccessibleTableListener listener = accessibleTableListeners.get(i);
3827 listener.getColumnCount(event);
3829 if (DEBUG) print(this + ".IAccessibleTable2::get_nColumns() returning " + event.count);
3830 OS.MoveMemory(pColumnCount, new int [] { event.count }, 4);
3834 /* IAccessibleTable2::get_nRows([out] pRowCount) */
3835 int get_nRows(long pRowCount) {
3836 AccessibleTableEvent event = new AccessibleTableEvent(this);
3837 for (int i = 0; i < accessibleTableListenersSize(); i++) {
3838 AccessibleTableListener listener = accessibleTableListeners.get(i);
3839 listener.getRowCount(event);
3841 if (DEBUG) print(this + ".IAccessibleTable2::get_nRows() returning " + event.count);
3842 OS.MoveMemory(pRowCount, new int [] { event.count }, 4);
3846 /* IAccessibleTable2::get_nSelectedCells([out] pCellCount) */
3847 int get_nSelectedCells(long pCellCount) {
3848 AccessibleTableEvent event = new AccessibleTableEvent(this);
3849 for (int i = 0; i < accessibleTableListenersSize(); i++) {
3850 AccessibleTableListener listener = accessibleTableListeners.get(i);
3851 listener.getSelectedCellCount(event);
3853 if (DEBUG) print(this + ".IAccessibleTable2::get_nSelectedCells() returning " + event.count);
3854 OS.MoveMemory(pCellCount, new int [] { event.count }, 4);
3858 /* IAccessibleTable2::get_nSelectedColumns([out] pColumnCount) */
3859 int get_nSelectedColumns(long pColumnCount) {
3860 AccessibleTableEvent event = new AccessibleTableEvent(this);
3861 for (int i = 0; i < accessibleTableListenersSize(); i++) {
3862 AccessibleTableListener listener = accessibleTableListeners.get(i);
3863 listener.getSelectedColumnCount(event);
3865 if (DEBUG) print(this + ".IAccessibleTable2::get_nSelectedColumns() returning " + event.count);
3866 OS.MoveMemory(pColumnCount, new int [] { event.count }, 4);
3870 /* IAccessibleTable2::get_nSelectedRows([out] pRowCount) */
3871 int get_nSelectedRows(long pRowCount) {
3872 AccessibleTableEvent event = new AccessibleTableEvent(this);
3873 for (int i = 0; i < accessibleTableListenersSize(); i++) {
3874 AccessibleTableListener listener = accessibleTableListeners.get(i);
3875 listener.getSelectedRowCount(event);
3877 if (DEBUG) print(this + ".IAccessibleTable2::get_nSelectedRows() returning " + event.count);
3878 OS.MoveMemory(pRowCount, new int [] { event.count }, 4);
3882 /* IAccessibleTable2::get_rowDescription([in] row, [out] pbstrDescription) */
3883 int get_rowDescription(int row, long pbstrDescription) {
3884 AccessibleTableEvent event = new AccessibleTableEvent(this);
3886 for (int i = 0; i < accessibleTableListenersSize(); i++) {
3887 AccessibleTableListener listener = accessibleTableListeners.get(i);
3888 listener.getRowDescription(event);
3890 if (DEBUG) print(this + ".IAccessibleTable2::get_rowDescription(row=" + row + ") returning " + event.result);
3891 setString(pbstrDescription, event.result);
3892 if (event.result == null) return COM.S_FALSE;
3896 /* IAccessibleTable2::get_selectedCells([out] ppCells, [out] pNSelectedCells) */
3897 int get_selectedCells(long ppCells, long pNSelectedCells) {
3898 AccessibleTableEvent event = new AccessibleTableEvent(this);
3899 for (int i = 0; i < accessibleTableListenersSize(); i++) {
3900 AccessibleTableListener listener = accessibleTableListeners.get(i);
3901 listener.getSelectedCells(event);
3903 if (DEBUG) print(this + ".IAccessibleTable2::get_selectedCells() returning " + (event.accessibles == null ? "null" : "accessibles[" + event.accessibles.length + "]"));
3904 if (event.accessibles == null || event.accessibles.length == 0) {
3905 OS.MoveMemory(ppCells, new long[] { 0 }, C.PTR_SIZEOF);
3906 OS.MoveMemory(pNSelectedCells, new int [] { 0 }, 4);
3909 int length = event.accessibles.length;
3910 long pv = OS.CoTaskMemAlloc(length * C.PTR_SIZEOF);
3912 for (int i = 0; i < length; i++) {
3913 Accessible accessible = event.accessibles[i];
3914 if (accessible != null) {
3915 accessible.AddRef();
3916 OS.MoveMemory(pv + i * C.PTR_SIZEOF, new long[] { accessible.getAddress() }, C.PTR_SIZEOF);
3920 OS.MoveMemory(ppCells, new long [] { pv }, C.PTR_SIZEOF);
3921 OS.MoveMemory(pNSelectedCells, new int [] { count }, 4);
3925 /* IAccessibleTable2::get_selectedColumns([out] ppSelectedColumns, [out] pNColumns) */
3926 int get_selectedColumns(long ppSelectedColumns, long pNColumns) {
3927 AccessibleTableEvent event = new AccessibleTableEvent(this);
3928 for (int i = 0; i < accessibleTableListenersSize(); i++) {
3929 AccessibleTableListener listener = accessibleTableListeners.get(i);
3930 listener.getSelectedColumns(event);
3932 int count = event.selected == null ? 0 : event.selected.length;
3933 if (DEBUG) print(this + ".IAccessibleTable2::get_selectedColumns() returning " + (count == 0 ? "null" : "selected[" + count + "]"));
3935 OS.MoveMemory(ppSelectedColumns, new long[] { 0 }, C.PTR_SIZEOF);
3936 OS.MoveMemory(pNColumns, new int [] { 0 }, 4);
3939 long pv = OS.CoTaskMemAlloc(count * 4);
3940 OS.MoveMemory(pv, event.selected, count * 4);
3941 OS.MoveMemory(ppSelectedColumns, new long [] { pv }, C.PTR_SIZEOF);
3942 OS.MoveMemory(pNColumns, new int [] { count }, 4);
3946 /* IAccessibleTable2::get_selectedRows([out] ppSelectedRows, [out] pNRows) */
3947 int get_selectedRows(long ppSelectedRows, long pNRows) {
3948 AccessibleTableEvent event = new AccessibleTableEvent(this);
3949 for (int i = 0; i < accessibleTableListenersSize(); i++) {
3950 AccessibleTableListener listener = accessibleTableListeners.get(i);
3951 listener.getSelectedRows(event);
3953 int count = event.selected == null ? 0 : event.selected.length;
3954 if (DEBUG) print(this + ".IAccessibleTable2::get_selectedRows() returning " + (count == 0 ? "null" : "selected[" + count + "]"));
3956 OS.MoveMemory(ppSelectedRows, new long[] { 0 }, C.PTR_SIZEOF);
3957 OS.MoveMemory(pNRows, new int [] { 0 }, 4);
3960 long pv = OS.CoTaskMemAlloc(count * 4);
3961 OS.MoveMemory(pv, event.selected, count * 4);
3962 OS.MoveMemory(ppSelectedRows, new long [] { pv }, C.PTR_SIZEOF);
3963 OS.MoveMemory(pNRows, new int [] { count }, 4);
3967 /* IAccessibleTable2::get_summary([out] ppAccessible) */
3968 int get_summary(long ppAccessible) {
3969 AccessibleTableEvent event = new AccessibleTableEvent(this);
3970 for (int i = 0; i < accessibleTableListenersSize(); i++) {
3971 AccessibleTableListener listener = accessibleTableListeners.get(i);
3972 listener.getSummary(event);
3974 Accessible accessible = event.accessible;
3975 if (DEBUG) print(this + ".IAccessibleTable2::get_summary() returning " + accessible);
3976 if (accessible == null) {
3977 OS.MoveMemory(ppAccessible, new long[] { 0 }, C.PTR_SIZEOF);
3980 accessible.AddRef();
3981 OS.MoveMemory(ppAccessible, new long[] { accessible.getAddress() }, C.PTR_SIZEOF);
3985 /* IAccessibleTable2::get_isColumnSelected([in] column, [out] pIsSelected) */
3986 int get_isColumnSelected(int column, long pIsSelected) {
3987 AccessibleTableEvent event = new AccessibleTableEvent(this);
3988 event.column = column;
3989 for (int i = 0; i < accessibleTableListenersSize(); i++) {
3990 AccessibleTableListener listener = accessibleTableListeners.get(i);
3991 listener.isColumnSelected(event);
3993 if (DEBUG) print(this + ".IAccessibleTable2::get_isColumnSelected() returning " + event.isSelected);
3994 OS.MoveMemory(pIsSelected, new int [] {event.isSelected ? 1 : 0}, 4);
3998 /* IAccessibleTable2::get_isRowSelected([in] row, [out] pIsSelected) */
3999 int get_isRowSelected(int row, long pIsSelected) {
4000 AccessibleTableEvent event = new AccessibleTableEvent(this);
4002 for (int i = 0; i < accessibleTableListenersSize(); i++) {
4003 AccessibleTableListener listener = accessibleTableListeners.get(i);
4004 listener.isRowSelected(event);
4006 if (DEBUG) print(this + ".IAccessibleTable2::get_isRowSelected() returning " + event.isSelected);
4007 OS.MoveMemory(pIsSelected, new int [] {event.isSelected ? 1 : 0}, 4);
4011 /* IAccessibleTable2::selectRow([in] row) */
4012 int selectRow(int row) {
4013 AccessibleTableEvent event = new AccessibleTableEvent(this);
4015 for (int i = 0; i < accessibleTableListenersSize(); i++) {
4016 AccessibleTableListener listener = accessibleTableListeners.get(i);
4017 listener.setSelectedRow(event);
4019 if (DEBUG) print(this + ".IAccessibleTable2::selectRow() returning " + (event.result == null ? "E_INVALIDARG" : event.result));
4020 if (event.result == null || !event.result.equals(ACC.OK)) return COM.E_INVALIDARG;
4024 /* IAccessibleTable2::selectColumn([in] column) */
4025 int selectColumn(int column) {
4026 AccessibleTableEvent event = new AccessibleTableEvent(this);
4027 event.column = column;
4028 for (int i = 0; i < accessibleTableListenersSize(); i++) {
4029 AccessibleTableListener listener = accessibleTableListeners.get(i);
4030 listener.setSelectedColumn(event);
4032 if (DEBUG) print(this + ".IAccessibleTable2::selectColumn() returning " + (event.result == null ? "E_INVALIDARG" : event.result));
4033 if (event.result == null || !event.result.equals(ACC.OK)) return COM.E_INVALIDARG;
4037 /* IAccessibleTable2::unselectRow([in] row) */
4038 int unselectRow(int row) {
4039 AccessibleTableEvent event = new AccessibleTableEvent(this);
4041 for (int i = 0; i < accessibleTableListenersSize(); i++) {
4042 AccessibleTableListener listener = accessibleTableListeners.get(i);
4043 listener.deselectRow(event);
4045 if (DEBUG) print(this + ".IAccessibleTable2::unselectRow() returning " + (event.result == null ? "E_INVALIDARG" : event.result));
4046 if (event.result == null || !event.result.equals(ACC.OK)) return COM.E_INVALIDARG;
4050 /* IAccessibleTable2::unselectColumn([in] column) */
4051 int unselectColumn(int column) {
4052 AccessibleTableEvent event = new AccessibleTableEvent(this);
4053 event.column = column;
4054 for (int i = 0; i < accessibleTableListenersSize(); i++) {
4055 AccessibleTableListener listener = accessibleTableListeners.get(i);
4056 listener.deselectColumn(event);
4058 if (DEBUG) print(this + ".IAccessibleTable2::unselectColumn() returning " + (event.result == null ? "E_INVALIDARG" : event.result));
4059 if (event.result == null || !event.result.equals(ACC.OK)) return COM.E_INVALIDARG;
4063 /* IAccessibleTable2::get_modelChange([out] pModelChange) */
4064 int get_modelChange(long pModelChange) {
4065 if (DEBUG) print(this + ".IAccessibleTable2::get_modelChange() returning " + (tableChange == null ? "null" : "tableChange=" + tableChange[0] + ", " + tableChange[1] + ", " + tableChange[2] + ", " + tableChange[3]));
4066 if (tableChange == null) {
4067 OS.MoveMemory(pModelChange, new long [] { 0 }, C.PTR_SIZEOF);
4070 OS.MoveMemory(pModelChange, tableChange, tableChange.length * 4);
4074 /* IAccessibleTableCell::get_columnExtent([out] pNColumnsSpanned) */
4075 int get_columnExtent(long pNColumnsSpanned) {
4076 AccessibleTableCellEvent event = new AccessibleTableCellEvent(this);
4077 for (int i = 0; i < accessibleTableCellListenersSize(); i++) {
4078 AccessibleTableCellListener listener = accessibleTableCellListeners.get(i);
4079 listener.getColumnSpan(event);
4081 if (DEBUG) print(this + ".IAccessibleTableCell::get_columnExtent() returning " + event.count);
4082 OS.MoveMemory(pNColumnsSpanned, new int [] { event.count }, 4);
4086 /* IAccessibleTableCell::get_columnHeaderCells([out] ppCellAccessibles, [out] pNColumnHeaderCells) */
4087 int get_columnHeaderCells(long ppCellAccessibles, long pNColumnHeaderCells) {
4088 AccessibleTableCellEvent event = new AccessibleTableCellEvent(this);
4089 for (int i = 0; i < accessibleTableCellListenersSize(); i++) {
4090 AccessibleTableCellListener listener = accessibleTableCellListeners.get(i);
4091 listener.getColumnHeaders(event);
4093 if (DEBUG) print(this + ".IAccessibleTableCell::get_columnHeaderCells() returning " + (event.accessibles == null ? "null" : "accessibles[" + event.accessibles.length + "]"));
4094 if (event.accessibles == null || event.accessibles.length == 0) {
4095 OS.MoveMemory(ppCellAccessibles, new long[] { 0 }, C.PTR_SIZEOF);
4096 OS.MoveMemory(pNColumnHeaderCells, new int [] { 0 }, 4);
4099 int length = event.accessibles.length;
4100 long pv = OS.CoTaskMemAlloc(length * C.PTR_SIZEOF);
4102 for (int i = 0; i < length; i++) {
4103 Accessible accessible = event.accessibles[i];
4104 if (accessible != null) {
4105 accessible.AddRef();
4106 OS.MoveMemory(pv + i * C.PTR_SIZEOF, new long[] { accessible.getAddress() }, C.PTR_SIZEOF);
4110 OS.MoveMemory(ppCellAccessibles, new long [] { pv }, C.PTR_SIZEOF);
4111 OS.MoveMemory(pNColumnHeaderCells, new int [] { count }, 4);
4115 /* IAccessibleTableCell::get_columnIndex([out] pColumnIndex) */
4116 int get_columnIndex(long pColumnIndex) {
4117 AccessibleTableCellEvent event = new AccessibleTableCellEvent(this);
4118 for (int i = 0; i < accessibleTableCellListenersSize(); i++) {
4119 AccessibleTableCellListener listener = accessibleTableCellListeners.get(i);
4120 listener.getColumnIndex(event);
4122 if (DEBUG) print(this + ".IAccessibleTableCell::get_columnIndex() returning " + event.index);
4123 OS.MoveMemory(pColumnIndex, new int [] { event.index }, 4);
4127 /* IAccessibleTableCell::get_rowExtent([out] pNRowsSpanned) */
4128 int get_rowExtent(long pNRowsSpanned) {
4129 AccessibleTableCellEvent event = new AccessibleTableCellEvent(this);
4130 for (int i = 0; i < accessibleTableCellListenersSize(); i++) {
4131 AccessibleTableCellListener listener = accessibleTableCellListeners.get(i);
4132 listener.getRowSpan(event);
4134 if (DEBUG) print(this + ".IAccessibleTableCell::get_rowExtent() returning " + event.count);
4135 OS.MoveMemory(pNRowsSpanned, new int [] { event.count }, 4);
4139 /* IAccessibleTableCell::get_rowHeaderCells([out] ppCellAccessibles, [out] pNRowHeaderCells) */
4140 int get_rowHeaderCells(long ppCellAccessibles, long pNRowHeaderCells) {
4141 AccessibleTableCellEvent event = new AccessibleTableCellEvent(this);
4142 for (int i = 0; i < accessibleTableCellListenersSize(); i++) {
4143 AccessibleTableCellListener listener = accessibleTableCellListeners.get(i);
4144 listener.getRowHeaders(event);
4146 if (DEBUG) print(this + ".IAccessibleTableCell::get_rowHeaderCells() returning " + (event.accessibles == null ? "null" : "accessibles[" + event.accessibles.length + "]"));
4147 if (event.accessibles == null || event.accessibles.length == 0) {
4148 OS.MoveMemory(ppCellAccessibles, new long[] { 0 }, C.PTR_SIZEOF);
4149 OS.MoveMemory(pNRowHeaderCells, new int [] { 0 }, 4);
4152 int length = event.accessibles.length;
4153 long pv = OS.CoTaskMemAlloc(length * C.PTR_SIZEOF);
4155 for (int i = 0; i < length; i++) {
4156 Accessible accessible = event.accessibles[i];
4157 if (accessible != null) {
4158 accessible.AddRef();
4159 OS.MoveMemory(pv + i * C.PTR_SIZEOF, new long[] { accessible.getAddress() }, C.PTR_SIZEOF);
4163 OS.MoveMemory(ppCellAccessibles, new long [] { pv }, C.PTR_SIZEOF);
4164 OS.MoveMemory(pNRowHeaderCells, new int [] { count }, 4);
4168 /* IAccessibleTableCell::get_rowIndex([out] pRowIndex) */
4169 int get_rowIndex(long pRowIndex) {
4170 AccessibleTableCellEvent event = new AccessibleTableCellEvent(this);
4171 for (int i = 0; i < accessibleTableCellListenersSize(); i++) {
4172 AccessibleTableCellListener listener = accessibleTableCellListeners.get(i);
4173 listener.getRowIndex(event);
4175 if (DEBUG) print(this + ".IAccessibleTableCell::get_rowIndex() returning " + event.index);
4176 OS.MoveMemory(pRowIndex, new int [] { event.index }, 4);
4180 /* IAccessibleTableCell::get_isSelected([out] pIsSelected) */
4181 int get_isSelected(long pIsSelected) {
4182 AccessibleTableCellEvent event = new AccessibleTableCellEvent(this);
4183 for (int i = 0; i < accessibleTableCellListenersSize(); i++) {
4184 AccessibleTableCellListener listener = accessibleTableCellListeners.get(i);
4185 listener.isSelected(event);
4187 if (DEBUG) print(this + ".IAccessibleTableCell::get_isSelected() returning " + event.isSelected);
4188 OS.MoveMemory(pIsSelected, new int [] {event.isSelected ? 1 : 0}, 4);
4192 /* IAccessibleTableCell::get_rowColumnExtents([out] pRow, [out] pColumn, [out] pRowExtents, [out] pColumnExtents, [out] pIsSelected) */
4193 int get_rowColumnExtents(long pRow, long pColumn, long pRowExtents, long pColumnExtents, long pIsSelected) {
4194 if (DEBUG) print(this + ".IAccessibleTableCell::get_rowColumnExtents");
4195 // TODO: should we implement this? It is just a convenience function.
4196 return COM.DISP_E_MEMBERNOTFOUND;
4197 // AccessibleTableCellEvent event = new AccessibleTableCellEvent(this);
4198 // for (int i = 0; i < accessibleTableCellListenersSize(); i++) {
4199 // AccessibleTableCellListener listener = (AccessibleTableCellListener) accessibleTableCellListeners.get(i);
4200 // listener.getRowColumnExtents(event);
4202 // COM.MoveMemory(pRow, new int [] { event.row }, 4);
4203 // COM.MoveMemory(pColumn, new int [] { event.column }, 4);
4204 // COM.MoveMemory(pRowExtents, new int [] { event.rowExtents }, 4);
4205 // COM.MoveMemory(pColumnExtents, new int [] { event.columnExtents }, 4);
4209 /* IAccessibleTableCell::get_table([out] ppTable) */
4210 int get_table(long ppTable) {
4211 AccessibleTableCellEvent event = new AccessibleTableCellEvent(this);
4212 for (int i = 0; i < accessibleTableCellListenersSize(); i++) {
4213 AccessibleTableCellListener listener = accessibleTableCellListeners.get(i);
4214 listener.getTable(event);
4216 Accessible accessible = event.accessible;
4217 if (DEBUG) print(this + ".IAccessibleTableCell::get_table() returning " + accessible);
4218 if (accessible == null) {
4219 // TODO: This is not supposed to return S_FALSE. We need to lookup the table role parent and return that.
4220 OS.MoveMemory(ppTable, new long[] { 0 }, C.PTR_SIZEOF);
4223 accessible.AddRef();
4224 OS.MoveMemory(ppTable, new long[] { accessible.getAddress() }, C.PTR_SIZEOF);
4228 /* IAccessibleText::addSelection([in] startOffset, [in] endOffset) */
4229 int addSelection(int startOffset, int endOffset) {
4230 if (DEBUG) print(this + ".IAccessibleText::addSelection(" + startOffset + ", " + endOffset + ")");
4231 AccessibleTextEvent event = new AccessibleTextEvent(this);
4232 event.start = startOffset == COM.IA2_TEXT_OFFSET_LENGTH ? getCharacterCount() : startOffset;
4233 event.end = endOffset == COM.IA2_TEXT_OFFSET_LENGTH ? getCharacterCount() : endOffset;
4234 for (int i = 0; i < accessibleTextExtendedListenersSize(); i++) {
4235 AccessibleTextExtendedListener listener = accessibleTextExtendedListeners.get(i);
4236 listener.addSelection(event);
4238 if (event.result == null || !event.result.equals(ACC.OK)) return COM.E_INVALIDARG;
4242 /* IAccessibleText::get_attributes([in] offset, [out] pStartOffset, [out] pEndOffset, [out] pbstrTextAttributes) */
4243 int get_attributes(int offset, long pStartOffset, long pEndOffset, long pbstrTextAttributes) {
4244 AccessibleTextAttributeEvent event = new AccessibleTextAttributeEvent(this);
4245 event.offset = offset == COM.IA2_TEXT_OFFSET_LENGTH ? getCharacterCount() : offset;
4246 for (int i = 0; i < accessibleAttributeListenersSize(); i++) {
4247 AccessibleAttributeListener listener = accessibleAttributeListeners.get(i);
4248 listener.getTextAttributes(event);
4250 String textAttributes = "";
4251 TextStyle style = event.textStyle;
4252 if (style != null) {
4253 if (style.rise != 0) {
4254 textAttributes += "text-position:";
4255 if (style.rise > 0) textAttributes += "super";
4256 else textAttributes += "sub";
4258 if (style.underline) {
4259 textAttributes += "text-underline-type:";
4260 switch (style.underlineStyle) {
4261 case SWT.UNDERLINE_SINGLE: textAttributes += "single;"; break;
4262 case SWT.UNDERLINE_DOUBLE: textAttributes += "double;"; break;
4263 case SWT.UNDERLINE_SQUIGGLE: textAttributes += "single;text-underline-style:wave;"; break;
4264 case SWT.UNDERLINE_ERROR: textAttributes += "single;text-underline-style:wave;invalid:true;"; break;
4265 default: textAttributes += "none;"; break;
4267 // style.underlineColor is not currently part of the IA2 spec. If provided, it would be "text-underline-color:rgb(n,n,n);"
4269 if (style.strikeout) {
4270 textAttributes += "text-line-through-type:single;";
4271 // style.strikeoutColor is not currently part of the IA2 spec. If provided, it would be "text-line-through-color:rgb(n,n,n);"
4273 Font font = style.font;
4274 if (font != null && !font.isDisposed()) {
4275 FontData fontData = font.getFontData()[0];
4276 textAttributes += "font-family:" + fontData.getName() + ";";
4277 textAttributes += "font-size:" + fontData.getHeight() + "pt;";
4278 textAttributes += "font-style:" + (fontData.data.lfItalic != 0 ? "italic" : "normal") + ";";
4279 textAttributes += "font-weight:" + fontData.data.lfWeight + ";";
4281 Color color = style.foreground;
4282 if (color != null && !color.isDisposed()) {
4283 textAttributes += "color:rgb(" + color.getRed() + "," + color.getGreen() + "," + color.getBlue() + ");";
4285 color = style.background;
4286 if (color != null && !color.isDisposed()) {
4287 textAttributes += "background-color:rgb(" + color.getRed() + "," + color.getGreen() + "," + color.getBlue() + ");";
4290 if (event.attributes != null) {
4291 for (int i = 0; i + 1 < event.attributes.length; i += 2) {
4292 textAttributes += event.attributes[i] + ":" + event.attributes[i+1] + ";";
4295 if (DEBUG) print(this + ".IAccessibleText::get_attributes(" + offset + ") returning start = " + event.start + ", end = " + event.end + ", attributes = " + textAttributes);
4296 OS.MoveMemory(pStartOffset, new int [] { event.start }, 4);
4297 OS.MoveMemory(pEndOffset, new int [] { event.end }, 4);
4298 setString(pbstrTextAttributes, textAttributes);
4299 if (textAttributes.length() == 0) return COM.S_FALSE;
4303 /* IAccessibleText::get_caretOffset([out] pOffset) */
4304 int get_caretOffset(long pOffset) {
4305 int offset = getCaretOffset();
4306 if (DEBUG) print(this + ".IAccessibleText::get_caretOffset returning " + offset + hresult(offset == -1 ? COM.S_FALSE : COM.S_OK));
4307 OS.MoveMemory(pOffset, new int [] { offset }, 4);
4308 if (offset == -1) return COM.S_FALSE;
4312 /* IAccessibleText::get_characterExtents([in] offset, [in] coordType, [out] pX, [out] pY, [out] pWidth, [out] pHeight) */
4313 int get_characterExtents(int offset, int coordType, long pX, long pY, long pWidth, long pHeight) {
4314 int length = getCharacterCount();
4315 AccessibleTextEvent event = new AccessibleTextEvent(this);
4316 event.start = offset == COM.IA2_TEXT_OFFSET_LENGTH ? length : offset < 0 ? 0 : offset;
4317 event.end = offset == COM.IA2_TEXT_OFFSET_LENGTH || offset >= length ? length : offset + 1;
4318 for (int i = 0; i < accessibleTextExtendedListenersSize(); i++) {
4319 AccessibleTextExtendedListener listener = accessibleTextExtendedListeners.get(i);
4320 listener.getTextBounds(event);
4322 /* Note: event.rectangles is not used here, because IAccessibleText::get_characterExtents is just for one character. */
4323 if (DEBUG) print(this + ".IAccessibleText::get_characterExtents(" + offset + ") returning " + event.x + ", " + event.y + ", " + event.width + ", " + event.height);
4324 OS.MoveMemory(pX, new int [] { event.x }, 4);
4325 OS.MoveMemory(pY, new int [] { event.y }, 4);
4326 OS.MoveMemory(pWidth, new int [] { event.width }, 4);
4327 OS.MoveMemory(pHeight, new int [] { event.height }, 4);
4328 if (event.width == 0 && event.height == 0) return COM.E_INVALIDARG;
4332 /* IAccessibleText::get_nSelections([out] pNSelections) */
4333 int get_nSelections(long pNSelections) {
4334 AccessibleTextEvent event = new AccessibleTextEvent(this);
4336 for (int i = 0; i < accessibleTextExtendedListenersSize(); i++) {
4337 AccessibleTextExtendedListener listener = accessibleTextExtendedListeners.get(i);
4338 listener.getSelectionCount(event);
4340 if (event.count == -1) {
4341 event.childID = ACC.CHILDID_SELF;
4344 for (int i = 0; i < accessibleTextListenersSize(); i++) {
4345 AccessibleTextListener listener = accessibleTextListeners.get(i);
4346 listener.getSelectionRange (event);
4348 event.count = event.offset != -1 && event.length > 0 ? 1 : 0;
4350 if (DEBUG) print(this + ".IAccessibleText::get_nSelections returning " + event.count);
4351 OS.MoveMemory(pNSelections, new int [] { event.count }, 4);
4355 /* IAccessibleText::get_offsetAtPoint([in] x, [in] y, [in] coordType, [out] pOffset) */
4356 int get_offsetAtPoint(int x, int y, int coordType, long pOffset) {
4357 AccessibleTextEvent event = new AccessibleTextEvent(this);
4361 for (int i = 0; i < accessibleTextExtendedListenersSize(); i++) {
4362 AccessibleTextExtendedListener listener = accessibleTextExtendedListeners.get(i);
4363 listener.getOffsetAtPoint(event);
4365 if (DEBUG) print(this + ".IAccessibleText::get_offsetAtPoint(" + x + ", " + y + ") returning " + event.offset + hresult(event.offset == -1 ? COM.S_FALSE : COM.S_OK));
4367 * Note that the current IA2 spec says to return 0 when there's nothing to return,
4368 * but since 0 is a valid return value, the spec is going to be updated to return -1.
4370 OS.MoveMemory(pOffset, new int [] { event.offset }, 4);
4371 if (event.offset == -1) return COM.S_FALSE;
4375 /* IAccessibleText::get_selection([in] selectionIndex, [out] pStartOffset, [out] pEndOffset) */
4376 int get_selection(int selectionIndex, long pStartOffset, long pEndOffset) {
4377 AccessibleTextEvent event = new AccessibleTextEvent(this);
4378 event.index = selectionIndex;
4381 for (int i = 0; i < accessibleTextExtendedListenersSize(); i++) {
4382 AccessibleTextExtendedListener listener = accessibleTextExtendedListeners.get(i);
4383 listener.getSelection(event);
4385 if (event.start == -1 && selectionIndex == 0) {
4386 event.childID = ACC.CHILDID_SELF;
4389 for (int i = 0; i < accessibleTextListenersSize(); i++) {
4390 AccessibleTextListener listener = accessibleTextListeners.get(i);
4391 listener.getSelectionRange (event);
4393 event.start = event.offset;
4394 event.end = event.offset + event.length;
4396 if (DEBUG) print(this + ".IAccessibleText::get_selection(" + selectionIndex + ") returning " + event.start + ", " + event.end);
4397 OS.MoveMemory(pStartOffset, new int [] { event.start }, 4);
4398 OS.MoveMemory(pEndOffset, new int [] { event.end }, 4);
4400 * Note that the current IA2 spec says to return 0,0 when there's nothing to return,
4401 * but since 0 is a valid return value, the spec is going to be updated to return -1,-1.
4403 if (event.start == -1) return COM.S_FALSE;
4407 /* IAccessibleText::get_text([in] startOffset, [in] endOffset, [out] pbstrText) */
4408 int get_text(int startOffset, int endOffset, long pbstrText) {
4409 AccessibleTextEvent event = new AccessibleTextEvent(this);
4410 event.start = startOffset == COM.IA2_TEXT_OFFSET_LENGTH ? getCharacterCount() : startOffset;
4411 event.end = endOffset == COM.IA2_TEXT_OFFSET_LENGTH ? getCharacterCount() : endOffset;
4412 if (event.start > event.end) {
4413 /* IA2 spec says that indices can be exchanged. */
4414 int temp = event.start;
4415 event.start = event.end;
4419 event.type = ACC.TEXT_BOUNDARY_ALL;
4420 for (int i = 0; i < accessibleTextExtendedListenersSize(); i++) {
4421 AccessibleTextExtendedListener listener = accessibleTextExtendedListeners.get(i);
4422 listener.getText(event);
4424 if (event.result == null) {
4425 AccessibleControlEvent e = new AccessibleControlEvent(this);
4426 e.childID = ACC.CHILDID_SELF;
4427 for (int i = 0; i < accessibleControlListenersSize(); i++) {
4428 AccessibleControlListener listener = accessibleControlListeners.get(i);
4429 listener.getRole(e);
4430 listener.getValue(e);
4432 // TODO: Consider passing the value through for other roles as well (i.e. combo, etc). Keep in sync with get_nCharacters.
4433 if (e.detail == ACC.ROLE_TEXT) {
4434 event.result = e.result;
4437 if (DEBUG) print(this + ".IAccessibleText::get_text(" + startOffset + ", " + endOffset + ") returning " + event.result + hresult(event.result == null ? COM.E_INVALIDARG : COM.S_OK));
4438 setString(pbstrText, event.result);
4439 if (event.result == null) return COM.E_INVALIDARG;
4443 /* IAccessibleText::get_textBeforeOffset([in] offset, [in] boundaryType, [out] pStartOffset, [out] pEndOffset, [out] pbstrText) */
4444 int get_textBeforeOffset(int offset, int boundaryType, long pStartOffset, long pEndOffset, long pbstrText) {
4445 AccessibleTextEvent event = new AccessibleTextEvent(this);
4446 int charCount = getCharacterCount();
4447 event.start = offset == COM.IA2_TEXT_OFFSET_LENGTH ? charCount : offset == COM.IA2_TEXT_OFFSET_CARET ? getCaretOffset() : offset;
4448 event.end = event.start;
4450 switch (boundaryType) {
4451 case COM.IA2_TEXT_BOUNDARY_CHAR: event.type = ACC.TEXT_BOUNDARY_CHAR; break;
4452 case COM.IA2_TEXT_BOUNDARY_WORD: event.type = ACC.TEXT_BOUNDARY_WORD; break;
4453 case COM.IA2_TEXT_BOUNDARY_SENTENCE: event.type = ACC.TEXT_BOUNDARY_SENTENCE; break;
4454 case COM.IA2_TEXT_BOUNDARY_PARAGRAPH: event.type = ACC.TEXT_BOUNDARY_PARAGRAPH; break;
4455 case COM.IA2_TEXT_BOUNDARY_LINE: event.type = ACC.TEXT_BOUNDARY_LINE; break;
4456 default: return COM.E_INVALIDARG;
4458 int eventStart = event.start;
4459 int eventEnd = event.end;
4460 for (int i = 0; i < accessibleTextExtendedListenersSize(); i++) {
4461 AccessibleTextExtendedListener listener = accessibleTextExtendedListeners.get(i);
4462 listener.getText(event);
4464 if (event.end < charCount) {
4465 switch (boundaryType) {
4466 case COM.IA2_TEXT_BOUNDARY_WORD:
4467 case COM.IA2_TEXT_BOUNDARY_SENTENCE:
4468 case COM.IA2_TEXT_BOUNDARY_PARAGRAPH:
4469 case COM.IA2_TEXT_BOUNDARY_LINE:
4470 int start = event.start;
4471 event.start = eventStart;
4472 event.end = eventEnd;
4474 for (int i = 0; i < accessibleTextExtendedListenersSize(); i++) {
4475 AccessibleTextExtendedListener listener = accessibleTextExtendedListeners.get(i);
4476 listener.getText(event);
4478 event.end = event.start;
4479 event.start = start;
4480 event.type = ACC.TEXT_BOUNDARY_ALL;
4482 for (int i = 0; i < accessibleTextExtendedListenersSize(); i++) {
4483 AccessibleTextExtendedListener listener = accessibleTextExtendedListeners.get(i);
4484 listener.getText(event);
4488 if (DEBUG) print(this + ".IAccessibleText::get_textBeforeOffset(" + offset + ") returning start=" + event.start + ", end=" + event.end + " " + event.result + hresult(event.result == null ? COM.S_FALSE : COM.S_OK));
4489 OS.MoveMemory(pStartOffset, new int [] { event.start }, 4);
4490 OS.MoveMemory(pEndOffset, new int [] { event.end }, 4);
4491 setString(pbstrText, event.result);
4492 if (event.result == null) return COM.S_FALSE;
4496 /* IAccessibleText::get_textAfterOffset([in] offset, [in] boundaryType, [out] pStartOffset, [out] pEndOffset, [out] pbstrText) */
4497 int get_textAfterOffset(int offset, int boundaryType, long pStartOffset, long pEndOffset, long pbstrText) {
4498 AccessibleTextEvent event = new AccessibleTextEvent(this);
4499 int charCount = getCharacterCount();
4500 event.start = offset == COM.IA2_TEXT_OFFSET_LENGTH ? charCount : offset == COM.IA2_TEXT_OFFSET_CARET ? getCaretOffset() : offset;
4501 event.end = event.start;
4503 switch (boundaryType) {
4504 case COM.IA2_TEXT_BOUNDARY_CHAR: event.type = ACC.TEXT_BOUNDARY_CHAR; break;
4505 case COM.IA2_TEXT_BOUNDARY_WORD: event.type = ACC.TEXT_BOUNDARY_WORD; break;
4506 case COM.IA2_TEXT_BOUNDARY_SENTENCE: event.type = ACC.TEXT_BOUNDARY_SENTENCE; break;
4507 case COM.IA2_TEXT_BOUNDARY_PARAGRAPH: event.type = ACC.TEXT_BOUNDARY_PARAGRAPH; break;
4508 case COM.IA2_TEXT_BOUNDARY_LINE: event.type = ACC.TEXT_BOUNDARY_LINE; break;
4509 default: return COM.E_INVALIDARG;
4511 int eventStart = event.start;
4512 int eventEnd = event.end;
4513 for (int i = 0; i < accessibleTextExtendedListenersSize(); i++) {
4514 AccessibleTextExtendedListener listener = accessibleTextExtendedListeners.get(i);
4515 listener.getText(event);
4517 if (event.end < charCount) {
4518 switch (boundaryType) {
4519 case COM.IA2_TEXT_BOUNDARY_WORD:
4520 case COM.IA2_TEXT_BOUNDARY_SENTENCE:
4521 case COM.IA2_TEXT_BOUNDARY_PARAGRAPH:
4522 case COM.IA2_TEXT_BOUNDARY_LINE:
4523 int start = event.start;
4524 event.start = eventStart;
4525 event.end = eventEnd;
4527 for (int i = 0; i < accessibleTextExtendedListenersSize(); i++) {
4528 AccessibleTextExtendedListener listener = accessibleTextExtendedListeners.get(i);
4529 listener.getText(event);
4531 event.end = event.start;
4532 event.start = start;
4533 event.type = ACC.TEXT_BOUNDARY_ALL;
4535 for (int i = 0; i < accessibleTextExtendedListenersSize(); i++) {
4536 AccessibleTextExtendedListener listener = accessibleTextExtendedListeners.get(i);
4537 listener.getText(event);
4541 if (DEBUG) print(this + ".IAccessibleText::get_textAfterOffset(" + offset + ") returning start=" + event.start + ", end=" + event.end + " " + event.result + hresult(event.result == null ? COM.S_FALSE : COM.S_OK));
4542 OS.MoveMemory(pStartOffset, new int [] { event.start }, 4);
4543 OS.MoveMemory(pEndOffset, new int [] { event.end }, 4);
4544 setString(pbstrText, event.result);
4545 if (event.result == null) return COM.S_FALSE;
4549 /* IAccessibleText::get_textAtOffset([in] offset, [in] boundaryType, [out] pStartOffset, [out] pEndOffset, [out] pbstrText) */
4550 int get_textAtOffset(int offset, int boundaryType, long pStartOffset, long pEndOffset, long pbstrText) {
4551 AccessibleTextEvent event = new AccessibleTextEvent(this);
4552 int charCount = getCharacterCount();
4553 event.start = offset == COM.IA2_TEXT_OFFSET_LENGTH ? charCount : offset == COM.IA2_TEXT_OFFSET_CARET ? getCaretOffset() : offset;
4554 event.end = event.start;
4556 switch (boundaryType) {
4557 case COM.IA2_TEXT_BOUNDARY_CHAR: event.type = ACC.TEXT_BOUNDARY_CHAR; break;
4558 case COM.IA2_TEXT_BOUNDARY_WORD: event.type = ACC.TEXT_BOUNDARY_WORD; break;
4559 case COM.IA2_TEXT_BOUNDARY_SENTENCE: event.type = ACC.TEXT_BOUNDARY_SENTENCE; break;
4560 case COM.IA2_TEXT_BOUNDARY_PARAGRAPH: event.type = ACC.TEXT_BOUNDARY_PARAGRAPH; break;
4561 case COM.IA2_TEXT_BOUNDARY_LINE: event.type = ACC.TEXT_BOUNDARY_LINE; break;
4562 case COM.IA2_TEXT_BOUNDARY_ALL: {
4563 event.type = ACC.TEXT_BOUNDARY_ALL;
4565 event.end = charCount;
4569 default: return COM.E_INVALIDARG;
4571 int eventStart = event.start;
4572 int eventEnd = event.end;
4573 for (int i = 0; i < accessibleTextExtendedListenersSize(); i++) {
4574 AccessibleTextExtendedListener listener = accessibleTextExtendedListeners.get(i);
4575 listener.getText(event);
4577 if (event.end < charCount) {
4578 switch (boundaryType) {
4579 case COM.IA2_TEXT_BOUNDARY_WORD:
4580 case COM.IA2_TEXT_BOUNDARY_SENTENCE:
4581 case COM.IA2_TEXT_BOUNDARY_PARAGRAPH:
4582 case COM.IA2_TEXT_BOUNDARY_LINE:
4583 int start = event.start;
4584 event.start = eventStart;
4585 event.end = eventEnd;
4587 for (int i = 0; i < accessibleTextExtendedListenersSize(); i++) {
4588 AccessibleTextExtendedListener listener = accessibleTextExtendedListeners.get(i);
4589 listener.getText(event);
4591 event.end = event.start;
4592 event.start = start;
4593 event.type = ACC.TEXT_BOUNDARY_ALL;
4595 for (int i = 0; i < accessibleTextExtendedListenersSize(); i++) {
4596 AccessibleTextExtendedListener listener = accessibleTextExtendedListeners.get(i);
4597 listener.getText(event);
4601 if (DEBUG) print(this + ".IAccessibleText::get_textAtOffset(" + offset + ") returning start=" + event.start + ", end=" + event.end + " " + event.result + hresult(event.result == null ? COM.S_FALSE : COM.S_OK));
4602 OS.MoveMemory(pStartOffset, new int [] { event.start }, 4);
4603 OS.MoveMemory(pEndOffset, new int [] { event.end }, 4);
4604 setString(pbstrText, event.result);
4605 if (event.result == null) return COM.S_FALSE;
4609 /* IAccessibleText::removeSelection([in] selectionIndex) */
4610 int removeSelection(int selectionIndex) {
4611 AccessibleTextEvent event = new AccessibleTextEvent(this);
4612 event.index = selectionIndex;
4613 for (int i = 0; i < accessibleTextExtendedListenersSize(); i++) {
4614 AccessibleTextExtendedListener listener = accessibleTextExtendedListeners.get(i);
4615 listener.removeSelection(event);
4617 if (DEBUG) print(this + ".IAccessibleText::removeSelection(" + selectionIndex + ") returning" + hresult(event.result == null || !event.result.equals(ACC.OK) ? COM.E_INVALIDARG : COM.S_OK));
4618 if (event.result == null || !event.result.equals(ACC.OK)) return COM.E_INVALIDARG;
4622 /* IAccessibleText::setCaretOffset([in] offset) */
4623 int setCaretOffset(int offset) {
4624 AccessibleTextEvent event = new AccessibleTextEvent(this);
4625 event.offset = offset == COM.IA2_TEXT_OFFSET_LENGTH ? getCharacterCount() : offset;
4626 for (int i = 0; i < accessibleTextExtendedListenersSize(); i++) {
4627 AccessibleTextExtendedListener listener = accessibleTextExtendedListeners.get(i);
4628 listener.setCaretOffset(event);
4630 if (DEBUG) print(this + ".IAccessibleText::setCaretOffset(" + offset + ") returning" + hresult(event.result == null || !event.result.equals(ACC.OK) ? COM.E_INVALIDARG : COM.S_OK));
4631 if (event.result == null || !event.result.equals(ACC.OK)) return COM.E_INVALIDARG; // TODO: @retval E_FAIL if the caret cannot be set ?
4635 /* IAccessibleText::setSelection([in] selectionIndex, [in] startOffset, [in] endOffset) */
4636 int setSelection(int selectionIndex, int startOffset, int endOffset) {
4637 AccessibleTextEvent event = new AccessibleTextEvent(this);
4638 event.index = selectionIndex;
4639 event.start = startOffset == COM.IA2_TEXT_OFFSET_LENGTH ? getCharacterCount() : startOffset;
4640 event.end = endOffset == COM.IA2_TEXT_OFFSET_LENGTH ? getCharacterCount() : endOffset;
4641 for (int i = 0; i < accessibleTextExtendedListenersSize(); i++) {
4642 AccessibleTextExtendedListener listener = accessibleTextExtendedListeners.get(i);
4643 listener.setSelection(event);
4645 if (DEBUG) print(this + ".IAccessibleText::setSelection(index=" + selectionIndex + ", start=" + event.start + ", end=" + event.end + ") returning " + (event.result.equals(ACC.OK) ? "OK" : "INVALIDARG"));
4646 if (event.result == null || !event.result.equals(ACC.OK)) return COM.E_INVALIDARG;
4650 /* IAccessibleText::get_nCharacters([out] pNCharacters) */
4651 int get_nCharacters(long pNCharacters) {
4652 int count = getCharacterCount();
4653 OS.MoveMemory(pNCharacters, new int [] { count }, 4);
4654 if (DEBUG) print(this + ".IAccessibleText::get_nCharacters returning " + count);
4658 /* IAccessibleText::scrollSubstringTo([in] startIndex, [in] endIndex, [in] scrollType) */
4659 int scrollSubstringTo(int startIndex, int endIndex, int scrollType) {
4660 if (DEBUG) print(this + ".IAccessibleText::scrollSubstringTo");
4661 AccessibleTextEvent event = new AccessibleTextEvent(this);
4662 event.start = startIndex;
4663 event.end = endIndex;
4664 switch (scrollType) {
4665 case COM.IA2_SCROLL_TYPE_TOP_LEFT: event.type = ACC.SCROLL_TYPE_TOP_LEFT; break;
4666 case COM.IA2_SCROLL_TYPE_BOTTOM_RIGHT: event.type = ACC.SCROLL_TYPE_BOTTOM_RIGHT; break;
4667 case COM.IA2_SCROLL_TYPE_TOP_EDGE: event.type = ACC.SCROLL_TYPE_TOP_EDGE; break;
4668 case COM.IA2_SCROLL_TYPE_BOTTOM_EDGE: event.type = ACC.SCROLL_TYPE_BOTTOM_EDGE; break;
4669 case COM.IA2_SCROLL_TYPE_LEFT_EDGE: event.type = ACC.SCROLL_TYPE_LEFT_EDGE; break;
4670 case COM.IA2_SCROLL_TYPE_RIGHT_EDGE: event.type = ACC.SCROLL_TYPE_RIGHT_EDGE; break;
4671 case COM.IA2_SCROLL_TYPE_ANYWHERE: event.type = ACC.SCROLL_TYPE_ANYWHERE; break;
4673 for (int i = 0; i < accessibleTextExtendedListenersSize(); i++) {
4674 AccessibleTextExtendedListener listener = accessibleTextExtendedListeners.get(i);
4675 listener.scrollText(event);
4677 if (event.result == null || !event.result.equals(ACC.OK)) return COM.E_INVALIDARG;
4681 /* IAccessibleText::scrollSubstringToPoint([in] startIndex, [in] endIndex, [in] coordinateType, [in] x, [in] y) */
4682 int scrollSubstringToPoint(int startIndex, int endIndex, int coordinateType, int x, int y) {
4683 if (DEBUG) print(this + ".IAccessibleText::scrollSubstringToPoint");
4684 AccessibleTextEvent event = new AccessibleTextEvent(this);
4685 event.start = startIndex;
4686 event.end = endIndex;
4687 event.type = ACC.SCROLL_TYPE_POINT;
4690 for (int i = 0; i < accessibleTextExtendedListenersSize(); i++) {
4691 AccessibleTextExtendedListener listener = accessibleTextExtendedListeners.get(i);
4692 listener.scrollText(event);
4694 if (event.result == null || !event.result.equals(ACC.OK)) return COM.E_INVALIDARG; // TODO: @retval S_FALSE if the object is already at the specified location.
4698 /* IAccessibleText::get_newText([out] pNewText) */
4699 int get_newText(long pNewText) {
4700 if (DEBUG) print(this + ".IAccessibleText::get_newText");
4704 if (textInserted != null) {
4705 text = (String) textInserted[3];
4706 start = ((Integer)textInserted[1]).intValue();
4707 end = ((Integer)textInserted[2]).intValue();
4709 setString(pNewText, text);
4710 OS.MoveMemory(pNewText + C.PTR_SIZEOF, new int [] {start}, 4);
4711 OS.MoveMemory(pNewText + C.PTR_SIZEOF + 4, new int [] {end}, 4);
4712 if (textInserted == null) return COM.S_FALSE;
4716 /* IAccessibleText::get_oldText([out] pOldText) */
4717 int get_oldText(long pOldText) {
4718 if (DEBUG) print(this + ".IAccessibleText::get_oldText");
4722 if (textDeleted != null) {
4723 text = (String) textDeleted[3];
4724 start = ((Integer)textDeleted[1]).intValue();
4725 end = ((Integer)textDeleted[2]).intValue();
4727 setString(pOldText, text);
4728 OS.MoveMemory(pOldText + C.PTR_SIZEOF, new int [] {start}, 4);
4729 OS.MoveMemory(pOldText + C.PTR_SIZEOF + 4, new int [] {end}, 4);
4730 if (textDeleted == null) return COM.S_FALSE;
4734 /* IAccessibleValue::get_currentValue([out] pCurrentValue) */
4735 int get_currentValue(long pCurrentValue) {
4736 AccessibleValueEvent event = new AccessibleValueEvent(this);
4737 for (int i = 0; i < accessibleValueListenersSize(); i++) {
4738 AccessibleValueListener listener = accessibleValueListeners.get(i);
4739 listener.getCurrentValue(event);
4741 if (DEBUG) print(this + ".IAccessibleValue::get_currentValue returning " + event.value + hresult(event.value == null ? COM.S_FALSE : COM.S_OK));
4742 setNumberVARIANT(pCurrentValue, event.value);
4746 /* IAccessibleValue::setCurrentValue([in] value) */
4747 int setCurrentValue(long value) {
4748 if (DEBUG) print(this + ".IAccessibleValue::setCurrentValue");
4749 AccessibleValueEvent event = new AccessibleValueEvent(this);
4750 event.value = getNumberVARIANT(value);
4751 for (int i = 0; i < accessibleValueListenersSize(); i++) {
4752 AccessibleValueListener listener = accessibleValueListeners.get(i);
4753 listener.setCurrentValue(event);
4755 //if (event.value == null) return COM.S_FALSE;
4759 /* IAccessibleValue::get_maximumValue([out] pMaximumValue) */
4760 int get_maximumValue(long pMaximumValue) {
4761 AccessibleValueEvent event = new AccessibleValueEvent(this);
4762 for (int i = 0; i < accessibleValueListenersSize(); i++) {
4763 AccessibleValueListener listener = accessibleValueListeners.get(i);
4764 listener.getMaximumValue(event);
4766 if (DEBUG) print(this + ".IAccessibleValue::get_maximumValue returning " + event.value + hresult(event.value == null ? COM.S_FALSE : COM.S_OK));
4767 setNumberVARIANT(pMaximumValue, event.value);
4771 /* IAccessibleValue::get_minimumValue([out] pMinimumValue) */
4772 int get_minimumValue(long pMinimumValue) {
4773 AccessibleValueEvent event = new AccessibleValueEvent(this);
4774 for (int i = 0; i < accessibleValueListenersSize(); i++) {
4775 AccessibleValueListener listener = accessibleValueListeners.get(i);
4776 listener.getMinimumValue(event);
4778 if (DEBUG) print(this + ".IAccessibleValue::get_minimumValue returning " + event.value + hresult(event.value == null ? COM.S_FALSE : COM.S_OK));
4779 setNumberVARIANT(pMinimumValue, event.value);
4783 int eventChildID() {
4784 if (parent == null) return COM.CHILDID_SELF;
4785 if (uniqueID == -1) uniqueID = UniqueID--;
4789 void checkUniqueID(int childID) {
4790 /* If the application is using child ids, check whether there's a corresponding
4791 * accessible, and if so, use the child id as that accessible's unique id. */
4792 AccessibleControlEvent event = new AccessibleControlEvent(this);
4793 event.childID = childID;
4794 for (int l = 0; l < accessibleControlListenersSize(); l++) {
4795 AccessibleControlListener listener = accessibleControlListeners.get(l);
4796 listener.getChild(event);
4798 Accessible accessible = event.accessible;
4799 if (accessible != null && accessible.uniqueID == -1) {
4800 accessible.uniqueID = childID;
4804 int childIDToOs(int childID) {
4805 if (childID == ACC.CHILDID_SELF) return COM.CHILDID_SELF;
4806 /* ChildIDs are 1-based indices. */
4807 int osChildID = childID + 1;
4808 if (control instanceof Tree) {
4809 osChildID = (int)OS.SendMessage (control.handle, OS.TVM_MAPHTREEITEMTOACCID, childID, 0);
4811 checkUniqueID(osChildID);
4815 int osToChildID(int osChildID) {
4816 if (osChildID == COM.CHILDID_SELF) return ACC.CHILDID_SELF;
4818 * Feature of Windows:
4819 * Before Windows XP, tree item ids were 1-based indices.
4820 * Windows XP and later use the tree item handle for the
4821 * accessible child ID. For backward compatibility, we still
4822 * take 1-based childIDs for tree items prior to Windows XP.
4823 * All other childIDs are 1-based indices.
4825 if (!(control instanceof Tree)) return osChildID - 1;
4826 return (int)OS.SendMessage (control.handle, OS.TVM_MAPACCIDTOHTREEITEM, osChildID, 0);
4829 int stateToOs(int state) {
4831 if ((state & ACC.STATE_SELECTED) != 0) osState |= COM.STATE_SYSTEM_SELECTED;
4832 if ((state & ACC.STATE_SELECTABLE) != 0) osState |= COM.STATE_SYSTEM_SELECTABLE;
4833 if ((state & ACC.STATE_MULTISELECTABLE) != 0) osState |= COM.STATE_SYSTEM_MULTISELECTABLE;
4834 if ((state & ACC.STATE_FOCUSED) != 0) osState |= COM.STATE_SYSTEM_FOCUSED;
4835 if ((state & ACC.STATE_FOCUSABLE) != 0) osState |= COM.STATE_SYSTEM_FOCUSABLE;
4836 if ((state & ACC.STATE_PRESSED) != 0) osState |= COM.STATE_SYSTEM_PRESSED;
4837 if ((state & ACC.STATE_CHECKED) != 0) osState |= COM.STATE_SYSTEM_CHECKED;
4838 if ((state & ACC.STATE_EXPANDED) != 0) osState |= COM.STATE_SYSTEM_EXPANDED;
4839 if ((state & ACC.STATE_COLLAPSED) != 0) osState |= COM.STATE_SYSTEM_COLLAPSED;
4840 if ((state & ACC.STATE_HOTTRACKED) != 0) osState |= COM.STATE_SYSTEM_HOTTRACKED;
4841 if ((state & ACC.STATE_BUSY) != 0) osState |= COM.STATE_SYSTEM_BUSY;
4842 if ((state & ACC.STATE_READONLY) != 0) osState |= COM.STATE_SYSTEM_READONLY;
4843 if ((state & ACC.STATE_INVISIBLE) != 0) osState |= COM.STATE_SYSTEM_INVISIBLE;
4844 if ((state & ACC.STATE_OFFSCREEN) != 0) osState |= COM.STATE_SYSTEM_OFFSCREEN;
4845 if ((state & ACC.STATE_SIZEABLE) != 0) osState |= COM.STATE_SYSTEM_SIZEABLE;
4846 if ((state & ACC.STATE_LINKED) != 0) osState |= COM.STATE_SYSTEM_LINKED;
4847 if ((state & ACC.STATE_DISABLED) != 0) osState |= COM.STATE_SYSTEM_UNAVAILABLE;
4851 int osToState(int osState) {
4852 int state = ACC.STATE_NORMAL;
4853 if ((osState & COM.STATE_SYSTEM_SELECTED) != 0) state |= ACC.STATE_SELECTED;
4854 if ((osState & COM.STATE_SYSTEM_SELECTABLE) != 0) state |= ACC.STATE_SELECTABLE;
4855 if ((osState & COM.STATE_SYSTEM_MULTISELECTABLE) != 0) state |= ACC.STATE_MULTISELECTABLE;
4856 if ((osState & COM.STATE_SYSTEM_FOCUSED) != 0) state |= ACC.STATE_FOCUSED;
4857 if ((osState & COM.STATE_SYSTEM_FOCUSABLE) != 0) state |= ACC.STATE_FOCUSABLE;
4858 if ((osState & COM.STATE_SYSTEM_PRESSED) != 0) state |= ACC.STATE_PRESSED;
4859 if ((osState & COM.STATE_SYSTEM_CHECKED) != 0) state |= ACC.STATE_CHECKED;
4860 if ((osState & COM.STATE_SYSTEM_EXPANDED) != 0) state |= ACC.STATE_EXPANDED;
4861 if ((osState & COM.STATE_SYSTEM_COLLAPSED) != 0) state |= ACC.STATE_COLLAPSED;
4862 if ((osState & COM.STATE_SYSTEM_HOTTRACKED) != 0) state |= ACC.STATE_HOTTRACKED;
4863 if ((osState & COM.STATE_SYSTEM_BUSY) != 0) state |= ACC.STATE_BUSY;
4864 if ((osState & COM.STATE_SYSTEM_READONLY) != 0) state |= ACC.STATE_READONLY;
4865 if ((osState & COM.STATE_SYSTEM_INVISIBLE) != 0) state |= ACC.STATE_INVISIBLE;
4866 if ((osState & COM.STATE_SYSTEM_OFFSCREEN) != 0) state |= ACC.STATE_OFFSCREEN;
4867 if ((osState & COM.STATE_SYSTEM_SIZEABLE) != 0) state |= ACC.STATE_SIZEABLE;
4868 if ((osState & COM.STATE_SYSTEM_LINKED) != 0) state |= ACC.STATE_LINKED;
4869 if ((osState & COM.STATE_SYSTEM_UNAVAILABLE) != 0) state |= ACC.STATE_DISABLED;
4873 int roleToOs(int role) {
4875 case ACC.ROLE_CLIENT_AREA: return COM.ROLE_SYSTEM_CLIENT;
4876 case ACC.ROLE_WINDOW: return COM.ROLE_SYSTEM_WINDOW;
4877 case ACC.ROLE_MENUBAR: return COM.ROLE_SYSTEM_MENUBAR;
4878 case ACC.ROLE_MENU: return COM.ROLE_SYSTEM_MENUPOPUP;
4879 case ACC.ROLE_MENUITEM: return COM.ROLE_SYSTEM_MENUITEM;
4880 case ACC.ROLE_SEPARATOR: return COM.ROLE_SYSTEM_SEPARATOR;
4881 case ACC.ROLE_TOOLTIP: return COM.ROLE_SYSTEM_TOOLTIP;
4882 case ACC.ROLE_SCROLLBAR: return COM.ROLE_SYSTEM_SCROLLBAR;
4883 case ACC.ROLE_DIALOG: return COM.ROLE_SYSTEM_DIALOG;
4884 case ACC.ROLE_LABEL: return COM.ROLE_SYSTEM_STATICTEXT;
4885 case ACC.ROLE_PUSHBUTTON: return COM.ROLE_SYSTEM_PUSHBUTTON;
4886 case ACC.ROLE_CHECKBUTTON: return COM.ROLE_SYSTEM_CHECKBUTTON;
4887 case ACC.ROLE_RADIOBUTTON: return COM.ROLE_SYSTEM_RADIOBUTTON;
4888 case ACC.ROLE_SPLITBUTTON: return COM.ROLE_SYSTEM_SPLITBUTTON;
4889 case ACC.ROLE_COMBOBOX: return COM.ROLE_SYSTEM_COMBOBOX;
4890 case ACC.ROLE_TEXT: return COM.ROLE_SYSTEM_TEXT;
4891 case ACC.ROLE_TOOLBAR: return COM.ROLE_SYSTEM_TOOLBAR;
4892 case ACC.ROLE_LIST: return COM.ROLE_SYSTEM_LIST;
4893 case ACC.ROLE_LISTITEM: return COM.ROLE_SYSTEM_LISTITEM;
4894 case ACC.ROLE_TABLE: return COM.ROLE_SYSTEM_TABLE;
4895 case ACC.ROLE_TABLECELL: return COM.ROLE_SYSTEM_CELL;
4896 case ACC.ROLE_TABLECOLUMNHEADER: return COM.ROLE_SYSTEM_COLUMNHEADER;
4897 case ACC.ROLE_TABLEROWHEADER: return COM.ROLE_SYSTEM_ROWHEADER;
4898 case ACC.ROLE_TREE: return COM.ROLE_SYSTEM_OUTLINE;
4899 case ACC.ROLE_TREEITEM: return COM.ROLE_SYSTEM_OUTLINEITEM;
4900 case ACC.ROLE_TABFOLDER: return COM.ROLE_SYSTEM_PAGETABLIST;
4901 case ACC.ROLE_TABITEM: return COM.ROLE_SYSTEM_PAGETAB;
4902 case ACC.ROLE_PROGRESSBAR: return COM.ROLE_SYSTEM_PROGRESSBAR;
4903 case ACC.ROLE_SLIDER: return COM.ROLE_SYSTEM_SLIDER;
4904 case ACC.ROLE_LINK: return COM.ROLE_SYSTEM_LINK;
4905 case ACC.ROLE_ALERT: return COM.ROLE_SYSTEM_ALERT;
4906 case ACC.ROLE_ANIMATION: return COM.ROLE_SYSTEM_ANIMATION;
4907 case ACC.ROLE_COLUMN: return COM.ROLE_SYSTEM_COLUMN;
4908 case ACC.ROLE_DOCUMENT: return COM.ROLE_SYSTEM_DOCUMENT;
4909 case ACC.ROLE_GRAPHIC: return COM.ROLE_SYSTEM_GRAPHIC;
4910 case ACC.ROLE_GROUP: return COM.ROLE_SYSTEM_GROUPING;
4911 case ACC.ROLE_ROW: return COM.ROLE_SYSTEM_ROW;
4912 case ACC.ROLE_SPINBUTTON: return COM.ROLE_SYSTEM_SPINBUTTON;
4913 case ACC.ROLE_STATUSBAR: return COM.ROLE_SYSTEM_STATUSBAR;
4914 case ACC.ROLE_CLOCK: return COM.ROLE_SYSTEM_CLOCK;
4915 case ACC.ROLE_CALENDAR: return COM.ROLE_SYSTEM_DROPLIST;
4917 /* The rest are IA2 roles, so return the closest match. */
4918 case ACC.ROLE_CANVAS: return COM.ROLE_SYSTEM_CLIENT;
4919 case ACC.ROLE_CHECKMENUITEM: return COM.ROLE_SYSTEM_MENUITEM;
4920 case ACC.ROLE_RADIOMENUITEM: return COM.ROLE_SYSTEM_MENUITEM;
4921 case ACC.ROLE_DATETIME: return COM.ROLE_SYSTEM_DROPLIST;
4922 case ACC.ROLE_FOOTER: return COM.ROLE_SYSTEM_CLIENT;
4923 case ACC.ROLE_FORM: return COM.ROLE_SYSTEM_CLIENT;
4924 case ACC.ROLE_HEADER: return COM.ROLE_SYSTEM_CLIENT;
4925 case ACC.ROLE_HEADING: return COM.ROLE_SYSTEM_CLIENT;
4926 case ACC.ROLE_PAGE: return COM.ROLE_SYSTEM_CLIENT;
4927 case ACC.ROLE_PARAGRAPH: return COM.ROLE_SYSTEM_CLIENT;
4928 case ACC.ROLE_SECTION: return COM.ROLE_SYSTEM_CLIENT;
4930 return COM.ROLE_SYSTEM_CLIENT;
4933 int osToRole(int osRole) {
4935 case COM.ROLE_SYSTEM_CLIENT: return ACC.ROLE_CLIENT_AREA;
4936 case COM.ROLE_SYSTEM_WINDOW: return ACC.ROLE_WINDOW;
4937 case COM.ROLE_SYSTEM_MENUBAR: return ACC.ROLE_MENUBAR;
4938 case COM.ROLE_SYSTEM_MENUPOPUP: return ACC.ROLE_MENU;
4939 case COM.ROLE_SYSTEM_MENUITEM: return ACC.ROLE_MENUITEM;
4940 case COM.ROLE_SYSTEM_SEPARATOR: return ACC.ROLE_SEPARATOR;
4941 case COM.ROLE_SYSTEM_TOOLTIP: return ACC.ROLE_TOOLTIP;
4942 case COM.ROLE_SYSTEM_SCROLLBAR: return ACC.ROLE_SCROLLBAR;
4943 case COM.ROLE_SYSTEM_DIALOG: return ACC.ROLE_DIALOG;
4944 case COM.ROLE_SYSTEM_STATICTEXT: return ACC.ROLE_LABEL;
4945 case COM.ROLE_SYSTEM_PUSHBUTTON: return ACC.ROLE_PUSHBUTTON;
4946 case COM.ROLE_SYSTEM_CHECKBUTTON: return ACC.ROLE_CHECKBUTTON;
4947 case COM.ROLE_SYSTEM_RADIOBUTTON: return ACC.ROLE_RADIOBUTTON;
4948 case COM.ROLE_SYSTEM_SPLITBUTTON: return ACC.ROLE_SPLITBUTTON;
4949 case COM.ROLE_SYSTEM_COMBOBOX: return ACC.ROLE_COMBOBOX;
4950 case COM.ROLE_SYSTEM_TEXT: return ACC.ROLE_TEXT;
4951 case COM.ROLE_SYSTEM_TOOLBAR: return ACC.ROLE_TOOLBAR;
4952 case COM.ROLE_SYSTEM_LIST: return ACC.ROLE_LIST;
4953 case COM.ROLE_SYSTEM_LISTITEM: return ACC.ROLE_LISTITEM;
4954 case COM.ROLE_SYSTEM_TABLE: return ACC.ROLE_TABLE;
4955 case COM.ROLE_SYSTEM_CELL: return ACC.ROLE_TABLECELL;
4956 case COM.ROLE_SYSTEM_COLUMNHEADER: return ACC.ROLE_TABLECOLUMNHEADER;
4957 case COM.ROLE_SYSTEM_ROWHEADER: return ACC.ROLE_TABLEROWHEADER;
4958 case COM.ROLE_SYSTEM_OUTLINE: return ACC.ROLE_TREE;
4959 case COM.ROLE_SYSTEM_OUTLINEITEM: return ACC.ROLE_TREEITEM;
4960 case COM.ROLE_SYSTEM_PAGETABLIST: return ACC.ROLE_TABFOLDER;
4961 case COM.ROLE_SYSTEM_PAGETAB: return ACC.ROLE_TABITEM;
4962 case COM.ROLE_SYSTEM_PROGRESSBAR: return ACC.ROLE_PROGRESSBAR;
4963 case COM.ROLE_SYSTEM_SLIDER: return ACC.ROLE_SLIDER;
4964 case COM.ROLE_SYSTEM_LINK: return ACC.ROLE_LINK;
4965 case COM.ROLE_SYSTEM_ALERT: return ACC.ROLE_ALERT;
4966 case COM.ROLE_SYSTEM_ANIMATION: return ACC.ROLE_ANIMATION;
4967 case COM.ROLE_SYSTEM_COLUMN: return ACC.ROLE_COLUMN;
4968 case COM.ROLE_SYSTEM_DOCUMENT: return ACC.ROLE_DOCUMENT;
4969 case COM.ROLE_SYSTEM_GRAPHIC: return ACC.ROLE_GRAPHIC;
4970 case COM.ROLE_SYSTEM_GROUPING: return ACC.ROLE_GROUP;
4971 case COM.ROLE_SYSTEM_ROW: return ACC.ROLE_ROW;
4972 case COM.ROLE_SYSTEM_SPINBUTTON: return ACC.ROLE_SPINBUTTON;
4973 case COM.ROLE_SYSTEM_STATUSBAR: return ACC.ROLE_STATUSBAR;
4974 case COM.ROLE_SYSTEM_CLOCK: return ACC.ROLE_CLOCK;
4975 case COM.ROLE_SYSTEM_DROPLIST: return ACC.ROLE_CALENDAR;
4977 return ACC.ROLE_CLIENT_AREA;
4981 * Return a Color given a string of the form "rgb(n,n,n)".
4983 Color colorFromString(String rgbString) {
4985 int open = rgbString.indexOf('(');
4986 int comma1 = rgbString.indexOf(',');
4987 int comma2 = rgbString.indexOf(',', comma1 + 1);
4988 int close = rgbString.indexOf(')');
4989 int r = Integer.parseInt(rgbString.substring(open + 1, comma1));
4990 int g = Integer.parseInt(rgbString.substring(comma1 + 1, comma2));
4991 int b = Integer.parseInt(rgbString.substring(comma2 + 1, close));
4992 return new Color(control.getDisplay(), r, g, b);
4993 } catch (NumberFormatException ex) {}
4997 int getCaretOffset() {
4998 AccessibleTextEvent event = new AccessibleTextEvent(this);
5000 for (int i = 0; i < accessibleTextExtendedListenersSize(); i++) {
5001 AccessibleTextListener listener = accessibleTextExtendedListeners.get(i);
5002 listener.getCaretOffset (event);
5004 if (event.offset == -1) {
5005 for (int i = 0; i < accessibleTextListenersSize(); i++) {
5006 event.childID = ACC.CHILDID_SELF;
5007 AccessibleTextListener listener = accessibleTextListeners.get(i);
5008 listener.getCaretOffset (event);
5011 return event.offset;
5014 int getCharacterCount() {
5015 AccessibleTextEvent event = new AccessibleTextEvent(this);
5017 for (int i = 0; i < accessibleTextExtendedListenersSize(); i++) {
5018 AccessibleTextExtendedListener listener = accessibleTextExtendedListeners.get(i);
5019 listener.getCharacterCount(event);
5021 if (event.count == -1) {
5022 AccessibleControlEvent e = new AccessibleControlEvent(this);
5023 e.childID = ACC.CHILDID_SELF;
5024 for (int i = 0; i < accessibleControlListenersSize(); i++) {
5025 AccessibleControlListener listener = accessibleControlListeners.get(i);
5026 listener.getRole(e);
5027 listener.getValue(e);
5029 // TODO: Consider passing the value through for other roles as well (i.e. combo, etc). Keep in sync with get_text.
5030 event.count = e.detail == ACC.ROLE_TEXT && e.result != null ? e.result.length() : 0;
5035 int getRelationCount() {
5037 for (int type = 0; type < MAX_RELATION_TYPES; type++) {
5038 if (relations[type] != null) count++;
5044 AccessibleControlEvent event = new AccessibleControlEvent(this);
5045 event.childID = ACC.CHILDID_SELF;
5046 for (int i = 0; i < accessibleControlListenersSize(); i++) {
5047 AccessibleControlListener listener = accessibleControlListeners.get(i);
5048 listener.getRole(event);
5050 return event.detail;
5053 int getDefaultRole() {
5055 role = COM.ROLE_SYSTEM_CLIENT;
5056 if (iaccessible != null) {
5057 /* Get the default role from the OS. */
5058 long varChild = OS.GlobalAlloc (OS.GMEM_FIXED | OS.GMEM_ZEROINIT, VARIANT.sizeof);
5059 setIntVARIANT(varChild, COM.VT_I4, COM.CHILDID_SELF);
5060 long pvarRole = OS.GlobalAlloc (OS.GMEM_FIXED | OS.GMEM_ZEROINIT, VARIANT.sizeof);
5061 int code = iaccessible.get_accRole(varChild, pvarRole);
5062 if (code == COM.S_OK) {
5063 VARIANT v = getVARIANT(pvarRole);
5064 if (v.vt == COM.VT_I4) role = v.lVal;
5066 OS.GlobalFree(varChild);
5067 OS.GlobalFree(pvarRole);
5072 String getString(long psz) {
5073 long [] ptr = new long [1];
5074 OS.MoveMemory (ptr, psz, C.PTR_SIZEOF);
5075 int size = COM.SysStringByteLen(ptr [0]);
5076 if (size == 0) return "";
5077 char [] buffer = new char [(size + 1) / 2];
5078 OS.MoveMemory (buffer, ptr [0], size);
5079 return new String (buffer);
5082 VARIANT getVARIANT(long variant) {
5083 VARIANT v = new VARIANT();
5084 COM.MoveMemory(v, variant, VARIANT.sizeof);
5088 Number getNumberVARIANT(long variant) {
5089 VARIANT v = new VARIANT();
5090 COM.MoveMemory(v, variant, VARIANT.sizeof);
5091 if (v.vt == COM.VT_I8) return Long.valueOf(v.lVal); // TODO: Fix this - v.lVal is an int - don't use struct
5092 return Integer.valueOf(v.lVal);
5095 void setIntVARIANT(long variant, short vt, int lVal) {
5096 if (vt == COM.VT_I4 || vt == COM.VT_EMPTY) {
5097 OS.MoveMemory(variant, new short[] { vt }, 2);
5098 OS.MoveMemory(variant + 8, new int[] { lVal }, 4);
5102 void setPtrVARIANT(long variant, short vt, long lVal) {
5103 if (vt == COM.VT_DISPATCH || vt == COM.VT_UNKNOWN) {
5104 OS.MoveMemory(variant, new short[] { vt }, 2);
5105 OS.MoveMemory(variant + 8, new long [] { lVal }, C.PTR_SIZEOF);
5109 void setNumberVARIANT(long variant, Number number) {
5110 if (number == null) {
5111 OS.MoveMemory(variant, new short[] { COM.VT_EMPTY }, 2);
5112 OS.MoveMemory(variant + 8, new int[] { 0 }, 4);
5113 } else if (number instanceof Double) {
5114 OS.MoveMemory(variant, new short[] { COM.VT_R8 }, 2);
5115 OS.MoveMemory(variant + 8, new double[] { number.doubleValue() }, 8);
5116 } else if (number instanceof Float) {
5117 OS.MoveMemory(variant, new short[] { COM.VT_R4 }, 2);
5118 OS.MoveMemory(variant + 8, new float[] { number.floatValue() }, 4);
5119 } else if (number instanceof Long) {
5120 OS.MoveMemory(variant, new short[] { COM.VT_I8 }, 2);
5121 OS.MoveMemory(variant + 8, new long[] { number.longValue() }, 8);
5123 OS.MoveMemory(variant, new short[] { COM.VT_I4 }, 2);
5124 OS.MoveMemory(variant + 8, new int[] { number.intValue() }, 4);
5128 void setString(long psz, String string) {
5130 if (string != null) {
5131 char[] data = (string + "\0").toCharArray();
5132 ptr = COM.SysAllocString(data);
5134 OS.MoveMemory(psz, new long [] { ptr }, C.PTR_SIZEOF);
5137 void setStringVARIANT(long variant, String string) {
5139 if (string != null) {
5140 char[] data = (string + "\0").toCharArray();
5141 ptr = COM.SysAllocString(data);
5143 OS.MoveMemory(variant, new short[] { ptr == 0 ? COM.VT_EMPTY : COM.VT_BSTR }, 2);
5144 OS.MoveMemory(variant + 8, new long [] { ptr }, C.PTR_SIZEOF);
5147 /* checkWidget was copied from Widget, and rewritten to work in this package */
5148 void checkWidget () {
5149 if (!isValidThread ()) SWT.error (SWT.ERROR_THREAD_INVALID_ACCESS);
5150 if (control.isDisposed ()) SWT.error (SWT.ERROR_WIDGET_DISPOSED);
5153 boolean isATRunning () {
5155 * Currently there is no accurate way to check if AT is running from 'refCount'.
5156 * JAWS screen reader cannot be detected using 'refCount' approach,
5157 * because 'refCount' continues to be 1 even when JAWS is running.
5159 // if (refCount <= 1) return false;
5163 /* isValidThread was copied from Widget, and rewritten to work in this package */
5164 boolean isValidThread () {
5165 return control.getDisplay ().getThread () == Thread.currentThread ();
5169 static void print (String str) {
5170 if (DEBUG) System.out.println (str);
5172 String getRoleString(int role) {
5173 if (DEBUG) switch (role) {
5174 case COM.ROLE_SYSTEM_CLIENT: return "ROLE_SYSTEM_CLIENT";
5175 case COM.ROLE_SYSTEM_WINDOW: return "ROLE_SYSTEM_WINDOW";
5176 case COM.ROLE_SYSTEM_MENUBAR: return "ROLE_SYSTEM_MENUBAR";
5177 case COM.ROLE_SYSTEM_MENUPOPUP: return "ROLE_SYSTEM_MENUPOPUP";
5178 case COM.ROLE_SYSTEM_MENUITEM: return "ROLE_SYSTEM_MENUITEM";
5179 case COM.ROLE_SYSTEM_SEPARATOR: return "ROLE_SYSTEM_SEPARATOR";
5180 case COM.ROLE_SYSTEM_TOOLTIP: return "ROLE_SYSTEM_TOOLTIP";
5181 case COM.ROLE_SYSTEM_SCROLLBAR: return "ROLE_SYSTEM_SCROLLBAR";
5182 case COM.ROLE_SYSTEM_DIALOG: return "ROLE_SYSTEM_DIALOG";
5183 case COM.ROLE_SYSTEM_STATICTEXT: return "ROLE_SYSTEM_STATICTEXT";
5184 case COM.ROLE_SYSTEM_PUSHBUTTON: return "ROLE_SYSTEM_PUSHBUTTON";
5185 case COM.ROLE_SYSTEM_CHECKBUTTON: return "ROLE_SYSTEM_CHECKBUTTON";
5186 case COM.ROLE_SYSTEM_RADIOBUTTON: return "ROLE_SYSTEM_RADIOBUTTON";
5187 case COM.ROLE_SYSTEM_SPLITBUTTON: return "ROLE_SYSTEM_SPLITBUTTON";
5188 case COM.ROLE_SYSTEM_COMBOBOX: return "ROLE_SYSTEM_COMBOBOX";
5189 case COM.ROLE_SYSTEM_TEXT: return "ROLE_SYSTEM_TEXT";
5190 case COM.ROLE_SYSTEM_TOOLBAR: return "ROLE_SYSTEM_TOOLBAR";
5191 case COM.ROLE_SYSTEM_LIST: return "ROLE_SYSTEM_LIST";
5192 case COM.ROLE_SYSTEM_LISTITEM: return "ROLE_SYSTEM_LISTITEM";
5193 case COM.ROLE_SYSTEM_TABLE: return "ROLE_SYSTEM_TABLE";
5194 case COM.ROLE_SYSTEM_CELL: return "ROLE_SYSTEM_CELL";
5195 case COM.ROLE_SYSTEM_COLUMNHEADER: return "ROLE_SYSTEM_COLUMNHEADER";
5196 case COM.ROLE_SYSTEM_ROWHEADER: return "ROLE_SYSTEM_ROWHEADER";
5197 case COM.ROLE_SYSTEM_OUTLINE: return "ROLE_SYSTEM_OUTLINE";
5198 case COM.ROLE_SYSTEM_OUTLINEITEM: return "ROLE_SYSTEM_OUTLINEITEM";
5199 case COM.ROLE_SYSTEM_PAGETABLIST: return "ROLE_SYSTEM_PAGETABLIST";
5200 case COM.ROLE_SYSTEM_PAGETAB: return "ROLE_SYSTEM_PAGETAB";
5201 case COM.ROLE_SYSTEM_PROGRESSBAR: return "ROLE_SYSTEM_PROGRESSBAR";
5202 case COM.ROLE_SYSTEM_SLIDER: return "ROLE_SYSTEM_SLIDER";
5203 case COM.ROLE_SYSTEM_LINK: return "ROLE_SYSTEM_LINK";
5204 case COM.ROLE_SYSTEM_ALERT: return "ROLE_SYSTEM_ALERT";
5205 case COM.ROLE_SYSTEM_ANIMATION: return "ROLE_SYSTEM_ANIMATION";
5206 case COM.ROLE_SYSTEM_COLUMN: return "ROLE_SYSTEM_COLUMN";
5207 case COM.ROLE_SYSTEM_DOCUMENT: return "ROLE_SYSTEM_DOCUMENT";
5208 case COM.ROLE_SYSTEM_GRAPHIC: return "ROLE_SYSTEM_GRAPHIC";
5209 case COM.ROLE_SYSTEM_GROUPING: return "ROLE_SYSTEM_GROUPING";
5210 case COM.ROLE_SYSTEM_ROW: return "ROLE_SYSTEM_ROW";
5211 case COM.ROLE_SYSTEM_SPINBUTTON: return "ROLE_SYSTEM_SPINBUTTON";
5212 case COM.ROLE_SYSTEM_STATUSBAR: return "ROLE_SYSTEM_STATUSBAR";
5213 case COM.ROLE_SYSTEM_CLOCK: return "ROLE_SYSTEM_CLOCK";
5214 case COM.ROLE_SYSTEM_DROPLIST: return "ROLE_SYSTEM_DROPLIST";
5216 case ACC.ROLE_CANVAS: return "IA2_ROLE_CANVAS";
5217 case ACC.ROLE_CHECKMENUITEM: return "IA2_ROLE_CHECKMENUITEM";
5218 case ACC.ROLE_RADIOMENUITEM: return "IA2_ROLE_RADIOMENUITEM";
5219 case ACC.ROLE_DATETIME: return "IA2_ROLE_DATETIME";
5220 case ACC.ROLE_FOOTER: return "IA2_ROLE_FOOTER";
5221 case ACC.ROLE_FORM: return "IA2_ROLE_FORM";
5222 case ACC.ROLE_HEADER: return "IA2_ROLE_HEADER";
5223 case ACC.ROLE_HEADING: return "IA2_ROLE_HEADING";
5224 case ACC.ROLE_PAGE: return "IA2_ROLE_PAGE";
5225 case ACC.ROLE_PARAGRAPH: return "IA2_ROLE_PARAGRAPH";
5226 case ACC.ROLE_SECTION: return "IA2_ROLE_SECTION";
5228 return "Unknown role (" + role + ")";
5230 String getStateString(int state) {
5231 if (state == 0) return " no state bits set";
5232 StringBuilder stateString = new StringBuilder();
5234 if ((state & COM.STATE_SYSTEM_SELECTED) != 0) stateString.append(" STATE_SYSTEM_SELECTED");
5235 if ((state & COM.STATE_SYSTEM_SELECTABLE) != 0) stateString.append(" STATE_SYSTEM_SELECTABLE");
5236 if ((state & COM.STATE_SYSTEM_MULTISELECTABLE) != 0) stateString.append(" STATE_SYSTEM_MULTISELECTABLE");
5237 if ((state & COM.STATE_SYSTEM_FOCUSED) != 0) stateString.append(" STATE_SYSTEM_FOCUSED");
5238 if ((state & COM.STATE_SYSTEM_FOCUSABLE) != 0) stateString.append(" STATE_SYSTEM_FOCUSABLE");
5239 if ((state & COM.STATE_SYSTEM_PRESSED) != 0) stateString.append(" STATE_SYSTEM_PRESSED");
5240 if ((state & COM.STATE_SYSTEM_CHECKED) != 0) stateString.append(" STATE_SYSTEM_CHECKED");
5241 if ((state & COM.STATE_SYSTEM_EXPANDED) != 0) stateString.append(" STATE_SYSTEM_EXPANDED");
5242 if ((state & COM.STATE_SYSTEM_COLLAPSED) != 0) stateString.append(" STATE_SYSTEM_COLLAPSED");
5243 if ((state & COM.STATE_SYSTEM_HOTTRACKED) != 0) stateString.append(" STATE_SYSTEM_HOTTRACKED");
5244 if ((state & COM.STATE_SYSTEM_BUSY) != 0) stateString.append(" STATE_SYSTEM_BUSY");
5245 if ((state & COM.STATE_SYSTEM_READONLY) != 0) stateString.append(" STATE_SYSTEM_READONLY");
5246 if ((state & COM.STATE_SYSTEM_INVISIBLE) != 0) stateString.append(" STATE_SYSTEM_INVISIBLE");
5247 if ((state & COM.STATE_SYSTEM_OFFSCREEN) != 0) stateString.append(" STATE_SYSTEM_OFFSCREEN");
5248 if ((state & COM.STATE_SYSTEM_SIZEABLE) != 0) stateString.append(" STATE_SYSTEM_SIZEABLE");
5249 if ((state & COM.STATE_SYSTEM_LINKED) != 0) stateString.append(" STATE_SYSTEM_LINKED");
5250 if ((state & COM.STATE_SYSTEM_UNAVAILABLE) != 0) stateString.append(" STATE_SYSTEM_UNAVAILABLE");
5251 if (stateString.length() == 0) stateString.append(" Unknown state[s] (" + Integer.toHexString(state) + ")");
5253 return stateString.toString();
5255 String getIA2StatesString(int ia2States) {
5256 if (ia2States == 0) return " no state bits set";
5257 StringBuilder stateString = new StringBuilder();
5259 if ((ia2States & COM.IA2_STATE_ACTIVE) != 0) stateString.append(" IA2_STATE_ACTIVE");
5260 if ((ia2States & COM.IA2_STATE_EDITABLE) != 0) stateString.append(" IA2_STATE_EDITABLE");
5261 if ((ia2States & COM.IA2_STATE_SINGLE_LINE) != 0) stateString.append(" IA2_STATE_SINGLE_LINE");
5262 if ((ia2States & COM.IA2_STATE_MULTI_LINE) != 0) stateString.append(" IA2_STATE_MULTI_LINE");
5263 if ((ia2States & COM.IA2_STATE_REQUIRED) != 0) stateString.append(" IA2_STATE_REQUIRED");
5264 if ((ia2States & COM.IA2_STATE_INVALID_ENTRY) != 0) stateString.append(" IA2_STATE_INVALID_ENTRY");
5265 if ((ia2States & COM.IA2_STATE_SUPPORTS_AUTOCOMPLETION) != 0) stateString.append(" IA2_STATE_SUPPORTS_AUTOCOMPLETION");
5266 if (stateString.length() == 0) stateString.append(" Unknown IA2 state[s] (" + ia2States + ")");
5268 return stateString.toString();
5270 String getEventString(int event) {
5271 if (DEBUG) switch (event) {
5272 case ACC.EVENT_TABLE_CHANGED: return "IA2_EVENT_TABLE_CHANGED";
5273 case ACC.EVENT_TEXT_CHANGED: return "IA2_EVENT_TEXT_REMOVED or IA2_EVENT_TEXT_INSERTED";
5274 case ACC.EVENT_HYPERTEXT_LINK_SELECTED: return "IA2_EVENT_HYPERTEXT_LINK_SELECTED";
5275 case ACC.EVENT_VALUE_CHANGED: return "EVENT_OBJECT_VALUECHANGE";
5276 case ACC.EVENT_STATE_CHANGED: return "EVENT_OBJECT_STATECHANGE";
5277 case ACC.EVENT_SELECTION_CHANGED: return "EVENT_OBJECT_SELECTIONWITHIN";
5278 case ACC.EVENT_TEXT_SELECTION_CHANGED: return "EVENT_OBJECT_TEXTSELECTIONCHANGED";
5279 case ACC.EVENT_LOCATION_CHANGED: return "EVENT_OBJECT_LOCATIONCHANGE";
5280 case ACC.EVENT_NAME_CHANGED: return "EVENT_OBJECT_NAMECHANGE";
5281 case ACC.EVENT_DESCRIPTION_CHANGED: return "EVENT_OBJECT_DESCRIPTIONCHANGE";
5282 case ACC.EVENT_DOCUMENT_LOAD_COMPLETE: return "IA2_EVENT_DOCUMENT_LOAD_COMPLETE";
5283 case ACC.EVENT_DOCUMENT_LOAD_STOPPED: return "IA2_EVENT_DOCUMENT_LOAD_STOPPED";
5284 case ACC.EVENT_DOCUMENT_RELOAD: return "IA2_EVENT_DOCUMENT_RELOAD";
5285 case ACC.EVENT_PAGE_CHANGED: return "IA2_EVENT_PAGE_CHANGED";
5286 case ACC.EVENT_SECTION_CHANGED: return "IA2_EVENT_SECTION_CHANGED";
5287 case ACC.EVENT_ACTION_CHANGED: return "IA2_EVENT_ACTION_CHANGED";
5288 case ACC.EVENT_HYPERLINK_START_INDEX_CHANGED: return "IA2_EVENT_HYPERLINK_START_INDEX_CHANGED";
5289 case ACC.EVENT_HYPERLINK_END_INDEX_CHANGED: return "IA2_EVENT_HYPERLINK_END_INDEX_CHANGED";
5290 case ACC.EVENT_HYPERLINK_ANCHOR_COUNT_CHANGED: return "IA2_EVENT_HYPERLINK_ANCHOR_COUNT_CHANGED";
5291 case ACC.EVENT_HYPERLINK_SELECTED_LINK_CHANGED: return "IA2_EVENT_HYPERLINK_SELECTED_LINK_CHANGED";
5292 case ACC.EVENT_HYPERLINK_ACTIVATED: return "IA2_EVENT_HYPERLINK_ACTIVATED";
5293 case ACC.EVENT_HYPERTEXT_LINK_COUNT_CHANGED: return "IA2_EVENT_HYPERTEXT_LINK_COUNT_CHANGED";
5294 case ACC.EVENT_ATTRIBUTE_CHANGED: return "IA2_EVENT_ATTRIBUTE_CHANGED";
5295 case ACC.EVENT_TABLE_CAPTION_CHANGED: return "IA2_EVENT_TABLE_CAPTION_CHANGED";
5296 case ACC.EVENT_TABLE_COLUMN_DESCRIPTION_CHANGED: return "IA2_EVENT_TABLE_COLUMN_DESCRIPTION_CHANGED";
5297 case ACC.EVENT_TABLE_COLUMN_HEADER_CHANGED: return "IA2_EVENT_TABLE_COLUMN_HEADER_CHANGED";
5298 case ACC.EVENT_TABLE_ROW_DESCRIPTION_CHANGED: return "IA2_EVENT_TABLE_ROW_DESCRIPTION_CHANGED";
5299 case ACC.EVENT_TABLE_ROW_HEADER_CHANGED: return "IA2_EVENT_TABLE_ROW_HEADER_CHANGED";
5300 case ACC.EVENT_TABLE_SUMMARY_CHANGED: return "IA2_EVENT_TABLE_SUMMARY_CHANGED";
5301 case ACC.EVENT_TEXT_ATTRIBUTE_CHANGED: return "IA2_EVENT_TEXT_ATTRIBUTE_CHANGED";
5302 case ACC.EVENT_TEXT_CARET_MOVED: return "IA2_EVENT_TEXT_CARET_MOVED";
5303 case ACC.EVENT_TEXT_COLUMN_CHANGED: return "IA2_EVENT_TEXT_COLUMN_CHANGED";
5305 return "Unknown event (" + event + ")";
5307 private String hresult(int code) {
5308 if (DEBUG) switch (code) {
5309 case COM.S_OK: return " S_OK";
5310 case COM.S_FALSE: return " S_FALSE";
5311 case COM.E_ACCESSDENIED: return " E_ACCESSDENIED";
5312 case COM.E_FAIL: return " E_FAIL";
5313 case COM.E_INVALIDARG: return " E_INVALIDARG";
5314 case COM.E_NOINTERFACE: return " E_NOINTERFACE";
5315 case COM.E_NOTIMPL: return " E_NOTIMPL";
5316 case COM.E_NOTSUPPORTED: return " E_NOTSUPPORTED";
5317 case COM.E_OUTOFMEMORY: return " E_OUTOFMEMORY";
5318 case OS.E_POINTER: return " E_POINTER";
5319 case COM.DISP_E_EXCEPTION: return " DISP_E_EXCEPTION";
5320 case COM.DISP_E_MEMBERNOTFOUND: return " DISP_E_MEMBERNOTFOUND";
5321 case COM.DISP_E_UNKNOWNINTERFACE: return " DISP_E_UNKNOWNINTERFACE";
5322 case COM.DISP_E_UNKNOWNNAME: return " DISP_E_UNKNOWNNAME";
5324 return " HRESULT=" + code;
5326 boolean interesting(GUID guid) {
5328 if (COM.IsEqualGUID(guid, COM.IIDIUnknown)) return true;
5329 if (COM.IsEqualGUID(guid, COM.IIDIAccessible)) return true;
5330 if (COM.IsEqualGUID(guid, COM.IIDIEnumVARIANT)) return true;
5331 if (COM.IsEqualGUID(guid, COM.IIDIServiceProvider)) return true;
5332 if (COM.IsEqualGUID(guid, COM.IIDIAccessible2)) return true;
5333 if (COM.IsEqualGUID(guid, COM.IIDIAccessibleRelation)) return true;
5334 if (COM.IsEqualGUID(guid, COM.IIDIAccessibleAction)) return true;
5335 if (COM.IsEqualGUID(guid, COM.IIDIAccessibleComponent)) return true;
5336 if (COM.IsEqualGUID(guid, COM.IIDIAccessibleValue)) return true;
5337 if (COM.IsEqualGUID(guid, COM.IIDIAccessibleText)) return true;
5338 if (COM.IsEqualGUID(guid, COM.IIDIAccessibleEditableText)) return true;
5339 if (COM.IsEqualGUID(guid, COM.IIDIAccessibleHyperlink)) return true;
5340 if (COM.IsEqualGUID(guid, COM.IIDIAccessibleHypertext)) return true;
5341 if (COM.IsEqualGUID(guid, COM.IIDIAccessibleTable)) return true;
5342 if (COM.IsEqualGUID(guid, COM.IIDIAccessibleTable2)) return true;
5343 if (COM.IsEqualGUID(guid, COM.IIDIAccessibleTableCell)) return true;
5344 if (COM.IsEqualGUID(guid, COM.IIDIAccessibleImage)) return true;
5345 if (COM.IsEqualGUID(guid, COM.IIDIAccessibleApplication)) return true;
5346 if (COM.IsEqualGUID(guid, COM.IIDIAccessibleContext)) return true;
5350 String guidString(GUID guid) {
5352 final GUID IIDIAccessibleHandler = IIDFromString("{03022430-ABC4-11D0-BDE2-00AA001A1953}"); //$NON-NLS-1$
5353 final GUID IIDIAccessor = IIDFromString("{0C733A8C-2A1C-11CE-ADE5-00AA0044773D}"); //$NON-NLS-1$
5354 final GUID IIDIAdviseSink2 = IIDFromString("{00000125-0000-0000-C000-000000000046}"); //$NON-NLS-1$
5355 final GUID IIDIBindCtx = IIDFromString("{0000000E-0000-0000-C000-000000000046}"); //$NON-NLS-1$
5356 final GUID IIDICreateErrorInfo = IIDFromString("{22F03340-547D-101B-8E65-08002B2BD119}"); //$NON-NLS-1$
5357 final GUID IIDICreateTypeInfo = IIDFromString("{00020405-0000-0000-C000-000000000046}"); //$NON-NLS-1$
5358 final GUID IIDICreateTypeLib = IIDFromString("{00020406-0000-0000-C000-000000000046}"); //$NON-NLS-1$
5359 final GUID IIDIDataAdviseHolder = IIDFromString("{00000110-0000-0000-C000-000000000046}"); //$NON-NLS-1$
5360 final GUID IIDIEnumConnectionPoints = IIDFromString("{B196B285-BAB4-101A-B69C-00AA00341D07}"); //$NON-NLS-1$
5361 final GUID IIDIEnumConnections = IIDFromString("{B196B287-BAB4-101A-B69C-00AA00341D07}"); //$NON-NLS-1$
5362 final GUID IIDIEnumMoniker = IIDFromString("{00000102-0000-0000-C000-000000000046}"); //$NON-NLS-1$
5363 final GUID IIDIEnumOLEVERB = IIDFromString("{00000104-0000-0000-C000-000000000046}"); //$NON-NLS-1$
5364 final GUID IIDIEnumSTATDATA = IIDFromString("{00000105-0000-0000-C000-000000000046}"); //$NON-NLS-1$
5365 final GUID IIDIEnumSTATSTG = IIDFromString("{0000000D-0000-0000-C000-000000000046}"); //$NON-NLS-1$
5366 final GUID IIDIEnumString = IIDFromString("{00000101-0000-0000-C000-000000000046}"); //$NON-NLS-1$
5367 final GUID IIDIEnumUnknown = IIDFromString("{00000100-0000-0000-C000-000000000046}"); //$NON-NLS-1$
5368 final GUID IIDIErrorInfo = IIDFromString("{1CF2B120-547D-101B-8E65-08002B2BD119}"); //$NON-NLS-1$
5369 final GUID IIDIErrorLog = IIDFromString("{3127CA40-446E-11CE-8135-00AA004BB851}"); //$NON-NLS-1$
5370 final GUID IIDIExternalConnection = IIDFromString("{00000019-0000-0000-C000-000000000046}"); //$NON-NLS-1$
5371 final GUID IIDIFontDisp = IIDFromString("{BEF6E003-A874-101A-8BBA-00AA00300CAB}"); //$NON-NLS-1$
5372 final GUID IIDILockBytes = IIDFromString("{0000000A-0000-0000-C000-000000000046}"); //$NON-NLS-1$
5373 final GUID IIDIMalloc = IIDFromString("{00000002-0000-0000-C000-000000000046}"); //$NON-NLS-1$
5374 final GUID IIDIMallocSpy = IIDFromString("{0000001D-0000-0000-C000-000000000046}"); //$NON-NLS-1$
5375 final GUID IIDIMarshal = IIDFromString("{00000003-0000-0000-C000-000000000046}"); //$NON-NLS-1$
5376 final GUID IIDIMessageFilter = IIDFromString("{00000016-0000-0000-C000-000000000046}"); //$NON-NLS-1$
5377 final GUID IIDIMoniker = IIDFromString("{0000000F-0000-0000-C000-000000000046}"); //$NON-NLS-1$
5378 final GUID IIDIOleAdviseHolder = IIDFromString("{00000111-0000-0000-C000-000000000046}"); //$NON-NLS-1$
5379 final GUID IIDIOleCache = IIDFromString("{0000011E-0000-0000-C000-000000000046}"); //$NON-NLS-1$
5380 final GUID IIDIOleCache2 = IIDFromString("{00000128-0000-0000-C000-000000000046}"); //$NON-NLS-1$
5381 final GUID IIDIOleCacheControl = IIDFromString("{00000129-0000-0000-C000-000000000046}"); //$NON-NLS-1$
5382 final GUID IIDIOleItemContainer = IIDFromString("{0000011C-0000-0000-C000-000000000046}"); //$NON-NLS-1$
5383 final GUID IIDIParseDisplayName = IIDFromString("{0000011A-0000-0000-C000-000000000046}"); //$NON-NLS-1$
5384 final GUID IIDIPerPropertyBrowsing = IIDFromString("{376BD3AA-3845-101B-84ED-08002B2EC713}"); //$NON-NLS-1$
5385 final GUID IIDIPersistMemory = IIDFromString("{BD1AE5E0-A6AE-11CE-BD37-504200C10000}"); //$NON-NLS-1$
5386 final GUID IIDIPersistPropertyBag = IIDFromString("{37D84F60-42CB-11CE-8135-00AA004BB851}"); //$NON-NLS-1$
5387 final GUID IIDIPicture = IIDFromString("{7BF80980-BF32-101A-8BBB-00AA00300CAB}"); //$NON-NLS-1$
5388 final GUID IIDIPictureDisp = IIDFromString("{7BF80981-BF32-101A-8BBB-00AA00300CAB}"); //$NON-NLS-1$
5389 final GUID IIDIPropertyBag = IIDFromString("{55272A00-42CB-11CE-8135-00AA004BB851}"); //$NON-NLS-1$
5390 final GUID IIDIPropertyPage = IIDFromString("{B196B28D-BAB4-101A-B69C-00AA00341D07}"); //$NON-NLS-1$
5391 final GUID IIDIPropertyPage2 = IIDFromString("{01E44665-24AC-101B-84ED-08002B2EC713}"); //$NON-NLS-1$
5392 final GUID IIDIPropertyPageSite = IIDFromString("{B196B28C-BAB4-101A-B69C-00AA00341D07}"); //$NON-NLS-1$
5393 final GUID IIDIPSFactoryBuffer = IIDFromString("{D5F569D0-593B-101A-B569-08002B2DBF7A}"); //$NON-NLS-1$
5394 final GUID IIDIRootStorage = IIDFromString("{00000012-0000-0000-C000-000000000046}"); //$NON-NLS-1$
5395 final GUID IIDIROTData = IIDFromString("{F29F6BC0-5021-11CE-AA15-00006901293F}"); //$NON-NLS-1$
5396 final GUID IIDIRpcChannelBuffer = IIDFromString("{D5F56B60-593B-101A-B569-08002B2DBF7A}"); //$NON-NLS-1$
5397 final GUID IIDIRpcProxyBuffer = IIDFromString("{D5F56A34-593B-101A-B569-08002B2DBF7A}"); //$NON-NLS-1$
5398 final GUID IIDIRpcStubBuffer = IIDFromString("{D5F56AFC-593B-101A-B569-08002B2DBF7A}"); //$NON-NLS-1$
5399 final GUID IIDIRunnableObject = IIDFromString("{00000126-0000-0000-C000-000000000046}"); //$NON-NLS-1$
5400 final GUID IIDIRunningObjectTable = IIDFromString("{00000010-0000-0000-C000-000000000046}"); //$NON-NLS-1$
5401 final GUID IIDISimpleFrameSite = IIDFromString("{742B0E01-14E6-101B-914E-00AA00300CAB}"); //$NON-NLS-1$
5402 final GUID IIDIStdMarshalInfo = IIDFromString("{00000018-0000-0000-C000-000000000046}"); //$NON-NLS-1$
5403 final GUID IIDISupportErrorInfo = IIDFromString("{DF0B3D60-548F-101B-8E65-08002B2BD119}"); //$NON-NLS-1$
5404 final GUID IIDITypeComp = IIDFromString("{00020403-0000-0000-C000-000000000046}"); //$NON-NLS-1$
5405 final GUID IIDITypeLib = IIDFromString("{00020402-0000-0000-C000-000000000046}"); //$NON-NLS-1$
5406 final GUID IIDIViewObject = IIDFromString("{0000010D-0000-0000-C000-000000000046}"); //$NON-NLS-1$
5407 final GUID IIDIdentityUnmarshal = IIDFromString("{0000001b-0000-0000-c000-000000000046}"); //$NON-NLS-1$
5408 final GUID IIDInternalMSMarshaller = IIDFromString("{4c1e39e1-e3e3-4296-aa86-ec938d896e92}"); //$NON-NLS-1$
5409 final GUID IIDIAccIdentity = IIDFromString("{7852B78D-1CFD-41C1-A615-9C0C85960B5F}"); //$NON-NLS-1$
5410 final GUID IIDIAccPropServer = IIDFromString("{76C0DBBB-15E0-4E7B-B61B-20EEEA2001E0}"); //$NON-NLS-1$
5411 final GUID IIDIAccPropServices = IIDFromString("{6E26E776-04F0-495D-80E4-3330352E3169}"); //$NON-NLS-1$
5412 if (COM.IsEqualGUID(guid, COM.IID_IDropTargetHelper)) return "IID_IDropTargetHelper";
5413 if (COM.IsEqualGUID(guid, COM.IIDJavaBeansBridge)) return "IIDJavaBeansBridge";
5414 if (COM.IsEqualGUID(guid, COM.IIDShockwaveActiveXControl)) return "IIDShockwaveActiveXControl";
5415 if (COM.IsEqualGUID(guid, COM.IIDIAccessible)) return "IIDIAccessible";
5416 if (COM.IsEqualGUID(guid, IIDIAccessibleHandler)) return "IIDIAccessibleHandler";
5417 if (COM.IsEqualGUID(guid, IIDIAccessor)) return "IIDIAccessor";
5418 if (COM.IsEqualGUID(guid, COM.IIDIAdviseSink)) return "IIDIAdviseSink";
5419 if (COM.IsEqualGUID(guid, IIDIAdviseSink2)) return "IIDIAdviseSink2";
5420 if (COM.IsEqualGUID(guid, IIDIBindCtx)) return "IIDIBindCtx";
5421 if (COM.IsEqualGUID(guid, COM.IIDIClassFactory)) return "IIDIClassFactory";
5422 if (COM.IsEqualGUID(guid, COM.IIDIClassFactory2)) return "IIDIClassFactory2";
5423 if (COM.IsEqualGUID(guid, COM.IIDIConnectionPointContainer)) return "IIDIConnectionPointContainer";
5424 if (COM.IsEqualGUID(guid, IIDICreateErrorInfo)) return "IIDICreateErrorInfo";
5425 if (COM.IsEqualGUID(guid, IIDICreateTypeInfo)) return "IIDICreateTypeInfo";
5426 if (COM.IsEqualGUID(guid, IIDICreateTypeLib)) return "IIDICreateTypeLib";
5427 if (COM.IsEqualGUID(guid, IIDIDataAdviseHolder)) return "IIDIDataAdviseHolder";
5428 if (COM.IsEqualGUID(guid, COM.IIDIDataObject)) return "IIDIDataObject";
5429 if (COM.IsEqualGUID(guid, COM.IIDIDispatch)) return "IIDIDispatch";
5430 if (COM.IsEqualGUID(guid, COM.IIDIDispatchEx)) return "IIDIDispatchEx";
5431 if (COM.IsEqualGUID(guid, COM.IIDIDocHostUIHandler)) return "IIDIDocHostUIHandler";
5432 if (COM.IsEqualGUID(guid, COM.IIDIDocHostShowUI)) return "IIDIDocHostShowUI";
5433 if (COM.IsEqualGUID(guid, COM.IIDIDropSource)) return "IIDIDropSource";
5434 if (COM.IsEqualGUID(guid, COM.IIDIDropTarget)) return "IIDIDropTarget";
5435 if (COM.IsEqualGUID(guid, IIDIEnumConnectionPoints)) return "IIDIEnumConnectionPoints";
5436 if (COM.IsEqualGUID(guid, IIDIEnumConnections)) return "IIDIEnumConnections";
5437 if (COM.IsEqualGUID(guid, COM.IIDIEnumFORMATETC)) return "IIDIEnumFORMATETC";
5438 if (COM.IsEqualGUID(guid, IIDIEnumMoniker)) return "IIDIEnumMoniker";
5439 if (COM.IsEqualGUID(guid, IIDIEnumOLEVERB)) return "IIDIEnumOLEVERB";
5440 if (COM.IsEqualGUID(guid, IIDIEnumSTATDATA)) return "IIDIEnumSTATDATA";
5441 if (COM.IsEqualGUID(guid, IIDIEnumSTATSTG)) return "IIDIEnumSTATSTG";
5442 if (COM.IsEqualGUID(guid, IIDIEnumString)) return "IIDIEnumString";
5443 if (COM.IsEqualGUID(guid, IIDIEnumUnknown)) return "IIDIEnumUnknown";
5444 if (COM.IsEqualGUID(guid, COM.IIDIEnumVARIANT)) return "IIDIEnumVARIANT";
5445 if (COM.IsEqualGUID(guid, IIDIErrorInfo)) return "IIDIErrorInfo";
5446 if (COM.IsEqualGUID(guid, IIDIErrorLog)) return "IIDIErrorLog";
5447 if (COM.IsEqualGUID(guid, IIDIExternalConnection)) return "IIDIExternalConnection";
5448 if (COM.IsEqualGUID(guid, IIDIFontDisp)) return "IIDIFontDisp";
5449 // if (COM.IsEqualGUID(guid, COM.IIDIHTMLDocumentEvents2)) return "IIDIHTMLDocumentEvents2";
5450 if (COM.IsEqualGUID(guid, COM.IIDIInternetSecurityManager)) return "IIDIInternetSecurityManager";
5451 if (COM.IsEqualGUID(guid, COM.IIDIAuthenticate)) return "IIDIAuthenticate";
5452 if (COM.IsEqualGUID(guid, COM.IIDIJScriptTypeInfo)) return "IIDIJScriptTypeInfo";
5453 if (COM.IsEqualGUID(guid, IIDILockBytes)) return "IIDILockBytes";
5454 if (COM.IsEqualGUID(guid, IIDIMalloc)) return "IIDIMalloc";
5455 if (COM.IsEqualGUID(guid, IIDIMallocSpy)) return "IIDIMallocSpy";
5456 if (COM.IsEqualGUID(guid, IIDIMarshal)) return "IIDIMarshal";
5457 if (COM.IsEqualGUID(guid, IIDIMessageFilter)) return "IIDIMessageFilter";
5458 if (COM.IsEqualGUID(guid, IIDIMoniker)) return "IIDIMoniker";
5459 if (COM.IsEqualGUID(guid, IIDIOleAdviseHolder)) return "IIDIOleAdviseHolder";
5460 if (COM.IsEqualGUID(guid, IIDIOleCache)) return "IIDIOleCache";
5461 if (COM.IsEqualGUID(guid, IIDIOleCache2)) return "IIDIOleCache2";
5462 if (COM.IsEqualGUID(guid, IIDIOleCacheControl)) return "IIDIOleCacheControl";
5463 if (COM.IsEqualGUID(guid, COM.IIDIOleClientSite)) return "IIDIOleClientSite";
5464 if (COM.IsEqualGUID(guid, COM.IIDIOleCommandTarget)) return "IIDIOleCommandTarget";
5465 if (COM.IsEqualGUID(guid, COM.IIDIOleControl)) return "IIDIOleControl";
5466 if (COM.IsEqualGUID(guid, COM.IIDIOleControlSite)) return "IIDIOleControlSite";
5467 if (COM.IsEqualGUID(guid, COM.IIDIOleDocument)) return "IIDIOleDocument";
5468 if (COM.IsEqualGUID(guid, COM.IIDIOleDocumentSite)) return "IIDIOleDocumentSite";
5469 if (COM.IsEqualGUID(guid, COM.IIDIOleInPlaceFrame)) return "IIDIOleInPlaceFrame";
5470 if (COM.IsEqualGUID(guid, COM.IIDIOleInPlaceObject)) return "IIDIOleInPlaceObject";
5471 if (COM.IsEqualGUID(guid, COM.IIDIOleInPlaceSite)) return "IIDIOleInPlaceSite";
5472 if (COM.IsEqualGUID(guid, IIDIOleItemContainer)) return "IIDIOleItemContainer";
5473 if (COM.IsEqualGUID(guid, COM.IIDIOleLink)) return "IIDIOleLink";
5474 if (COM.IsEqualGUID(guid, COM.IIDIOleObject)) return "IIDIOleObject";
5475 if (COM.IsEqualGUID(guid, IIDIParseDisplayName)) return "IIDIParseDisplayName";
5476 if (COM.IsEqualGUID(guid, IIDIPerPropertyBrowsing)) return "IIDIPerPropertyBrowsing";
5477 if (COM.IsEqualGUID(guid, COM.IIDIPersist)) return "IIDIPersist";
5478 if (COM.IsEqualGUID(guid, COM.IIDIPersistFile)) return "IIDIPersistFile";
5479 if (COM.IsEqualGUID(guid, IIDIPersistMemory)) return "IIDIPersistMemory";
5480 if (COM.IsEqualGUID(guid, IIDIPersistPropertyBag)) return "IIDIPersistPropertyBag";
5481 if (COM.IsEqualGUID(guid, COM.IIDIPersistStorage)) return "IIDIPersistStorage";
5482 if (COM.IsEqualGUID(guid, COM.IIDIPersistStreamInit)) return "IIDIPersistStreamInit";
5483 if (COM.IsEqualGUID(guid, IIDIPicture)) return "IIDIPicture";
5484 if (COM.IsEqualGUID(guid, IIDIPictureDisp)) return "IIDIPictureDisp";
5485 if (COM.IsEqualGUID(guid, IIDIPropertyBag)) return "IIDIPropertyBag";
5486 if (COM.IsEqualGUID(guid, COM.IIDIPropertyNotifySink)) return "IIDIPropertyNotifySink";
5487 if (COM.IsEqualGUID(guid, IIDIPropertyPage)) return "IIDIPropertyPage";
5488 if (COM.IsEqualGUID(guid, IIDIPropertyPage2)) return "IIDIPropertyPage2";
5489 if (COM.IsEqualGUID(guid, IIDIPropertyPageSite)) return "IIDIPropertyPageSite";
5490 if (COM.IsEqualGUID(guid, COM.IIDIProvideClassInfo)) return "IIDIProvideClassInfo";
5491 if (COM.IsEqualGUID(guid, COM.IIDIProvideClassInfo2)) return "IIDIProvideClassInfo2";
5492 if (COM.IsEqualGUID(guid, IIDIPSFactoryBuffer)) return "IIDIPSFactoryBuffer";
5493 if (COM.IsEqualGUID(guid, IIDIRootStorage)) return "IIDIRootStorage";
5494 if (COM.IsEqualGUID(guid, IIDIROTData)) return "IIDIROTData";
5495 if (COM.IsEqualGUID(guid, IIDIRpcChannelBuffer)) return "IIDIRpcChannelBuffer";
5496 if (COM.IsEqualGUID(guid, IIDIRpcProxyBuffer)) return "IIDIRpcProxyBuffer";
5497 if (COM.IsEqualGUID(guid, IIDIRpcStubBuffer)) return "IIDIRpcStubBuffer";
5498 if (COM.IsEqualGUID(guid, IIDIRunnableObject)) return "IIDIRunnableObject";
5499 if (COM.IsEqualGUID(guid, IIDIRunningObjectTable)) return "IIDIRunningObjectTable";
5500 if (COM.IsEqualGUID(guid, IIDISimpleFrameSite)) return "IIDISimpleFrameSite";
5501 if (COM.IsEqualGUID(guid, COM.IIDIServiceProvider)) return "IIDIServiceProvider";
5502 if (COM.IsEqualGUID(guid, COM.IIDISpecifyPropertyPages)) return "IIDISpecifyPropertyPages";
5503 if (COM.IsEqualGUID(guid, IIDIStdMarshalInfo)) return "IIDIStdMarshalInfo";
5504 if (COM.IsEqualGUID(guid, IIDISupportErrorInfo)) return "IIDISupportErrorInfo";
5505 if (COM.IsEqualGUID(guid, IIDITypeComp)) return "IIDITypeComp";
5506 if (COM.IsEqualGUID(guid, IIDITypeLib)) return "IIDITypeLib";
5507 if (COM.IsEqualGUID(guid, COM.IIDIUnknown)) return "IIDIUnknown";
5508 if (COM.IsEqualGUID(guid, IIDIViewObject)) return "IIDIViewObject";
5509 if (COM.IsEqualGUID(guid, COM.IIDIViewObject2)) return "IIDIViewObject2";
5510 if (COM.IsEqualGUID(guid, COM.CGID_DocHostCommandHandler)) return "CGID_DocHostCommandHandler";
5511 if (COM.IsEqualGUID(guid, COM.CGID_Explorer)) return "CGID_Explorer";
5512 if (COM.IsEqualGUID(guid, COM.IIDIAccessible2)) return "IIDIAccessible2";
5513 if (COM.IsEqualGUID(guid, COM.IIDIAccessibleRelation)) return "IIDIAccessibleRelation";
5514 if (COM.IsEqualGUID(guid, COM.IIDIAccessibleAction)) return "IIDIAccessibleAction";
5515 if (COM.IsEqualGUID(guid, COM.IIDIAccessibleComponent)) return "IIDIAccessibleComponent";
5516 if (COM.IsEqualGUID(guid, COM.IIDIAccessibleValue)) return "IIDIAccessibleValue";
5517 if (COM.IsEqualGUID(guid, COM.IIDIAccessibleText)) return "IIDIAccessibleText";
5518 if (COM.IsEqualGUID(guid, COM.IIDIAccessibleEditableText)) return "IIDIAccessibleEditableText";
5519 if (COM.IsEqualGUID(guid, COM.IIDIAccessibleHyperlink)) return "IIDIAccessibleHyperlink";
5520 if (COM.IsEqualGUID(guid, COM.IIDIAccessibleHypertext)) return "IIDIAccessibleHypertext";
5521 if (COM.IsEqualGUID(guid, COM.IIDIAccessibleTable)) return "IIDIAccessibleTable";
5522 if (COM.IsEqualGUID(guid, COM.IIDIAccessibleTable2)) return "IIDIAccessibleTable2";
5523 if (COM.IsEqualGUID(guid, COM.IIDIAccessibleTableCell)) return "IIDIAccessibleTableCell";
5524 if (COM.IsEqualGUID(guid, COM.IIDIAccessibleImage)) return "IIDIAccessibleImage";
5525 if (COM.IsEqualGUID(guid, COM.IIDIAccessibleApplication)) return "IIDIAccessibleApplication";
5526 if (COM.IsEqualGUID(guid, COM.IIDIAccessibleContext)) return "IIDIAccessibleContext";
5527 if (COM.IsEqualGUID(guid, IIDIdentityUnmarshal)) return "IIDIdentityUnmarshal";
5528 if (COM.IsEqualGUID(guid, IIDInternalMSMarshaller)) return "IIDInternalMSMarshaller";
5529 if (COM.IsEqualGUID(guid, IIDIAccIdentity)) return "IIDIAccIdentity";
5530 if (COM.IsEqualGUID(guid, IIDIAccPropServer)) return "IIDIAccPropServer";
5531 if (COM.IsEqualGUID(guid, IIDIAccPropServices)) return "IIDIAccPropServices";
5533 return guid.toString();
5535 static GUID IIDFromString(String lpsz) {
5537 int length = lpsz.length();
5538 char[] buffer = new char[length + 1];
5539 lpsz.getChars(0, length, buffer, 0);
5540 GUID lpiid = new GUID();
5541 if (COM.IIDFromString(buffer, lpiid) == COM.S_OK) return lpiid;
5546 public String toString () {
5547 String toString = super.toString();
5549 int role = getRole();
5550 if (role == 0) role = getDefaultRole();
5551 return toString.substring(toString.lastIndexOf('.') + 1) + "(" + getRoleString(role) + ")";