KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > swt > accessibility > Accessible


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.swt.accessibility;
12
13
14 import java.util.Vector JavaDoc;
15 import org.eclipse.swt.*;
16 import org.eclipse.swt.widgets.*;
17 import org.eclipse.swt.internal.win32.*;
18 import org.eclipse.swt.ole.win32.*;
19 import org.eclipse.swt.internal.ole.win32.*;
20
21 /**
22  * Instances of this class provide a bridge between application
23  * code and assistive technology clients. Many platforms provide
24  * default accessible behavior for most widgets, and this class
25  * allows that default behavior to be overridden. Applications
26  * can get the default Accessible object for a control by sending
27  * it <code>getAccessible</code>, and then add an accessible listener
28  * to override simple items like the name and help string, or they
29  * can add an accessible control listener to override complex items.
30  * As a rule of thumb, an application would only want to use the
31  * accessible control listener to implement accessibility for a
32  * custom control.
33  *
34  * @see Control#getAccessible
35  * @see AccessibleListener
36  * @see AccessibleEvent
37  * @see AccessibleControlListener
38  * @see AccessibleControlEvent
39  *
40  * @since 2.0
41  */

42 public class Accessible {
43     int refCount = 0, enumIndex = 0;
44     COMObject objIAccessible, objIEnumVARIANT;
45     IAccessible iaccessible;
46     Vector JavaDoc accessibleListeners = new Vector JavaDoc();
47     Vector JavaDoc accessibleControlListeners = new Vector JavaDoc();
48     Vector JavaDoc textListeners = new Vector JavaDoc ();
49     Object JavaDoc[] variants;
50     Control control;
51
52     Accessible(Control control) {
53         this.control = control;
54         int /*long*/[] ppvObject = new int /*long*/[1];
55         /* CreateStdAccessibleObject([in] hwnd, [in] idObject, [in] riidInterface, [out] ppvObject).
56          * AddRef has already been called on ppvObject by the callee and must be released by the caller.
57          */

58         int result = (int)/*64*/COM.CreateStdAccessibleObject(control.handle, COM.OBJID_CLIENT, COM.IIDIAccessible, ppvObject);
59         /* The object needs to be checked, because if the CreateStdAccessibleObject()
60          * symbol is not found, the return value is S_OK.
61          */

62         if (ppvObject[0] == 0) return;
63         if (result != COM.S_OK) OLE.error(OLE.ERROR_CANNOT_CREATE_OBJECT, result);
64         iaccessible = new IAccessible(ppvObject[0]);
65
66         objIAccessible = new COMObject(new int[] {2,0,0,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}) {
67             public int /*long*/ method0(int /*long*/[] args) {return QueryInterface(args[0], args[1]);}
68             public int /*long*/ method1(int /*long*/[] args) {return AddRef();}
69             public int /*long*/ method2(int /*long*/[] args) {return Release();}
70             // method3 GetTypeInfoCount - not implemented
71
// method4 GetTypeInfo - not implemented
72
// method5 GetIDsOfNames - not implemented
73
// method6 Invoke - not implemented
74
public int /*long*/ method7(int /*long*/[] args) {return get_accParent(args[0]);}
75             public int /*long*/ method8(int /*long*/[] args) {return get_accChildCount(args[0]);}
76             public int /*long*/ method9(int /*long*/[] args) {return get_accChild(args[0], args[1]);}
77             public int /*long*/ method10(int /*long*/[] args) {return get_accName(args[0], args[1]);}
78             public int /*long*/ method11(int /*long*/[] args) {return get_accValue(args[0], args[1]);}
79             public int /*long*/ method12(int /*long*/[] args) {return get_accDescription(args[0], args[1]);}
80             public int /*long*/ method13(int /*long*/[] args) {return get_accRole(args[0], args[1]);}
81             public int /*long*/ method14(int /*long*/[] args) {return get_accState(args[0], args[1]);}
82             public int /*long*/ method15(int /*long*/[] args) {return get_accHelp(args[0], args[1]);}
83             public int /*long*/ method16(int /*long*/[] args) {return get_accHelpTopic(args[0], args[1], args[2]);}
84             public int /*long*/ method17(int /*long*/[] args) {return get_accKeyboardShortcut(args[0], args[1]);}
85             public int /*long*/ method18(int /*long*/[] args) {return get_accFocus(args[0]);}
86             public int /*long*/ method19(int /*long*/[] args) {return get_accSelection(args[0]);}
87             public int /*long*/ method20(int /*long*/[] args) {return get_accDefaultAction(args[0], args[1]);}
88             public int /*long*/ method21(int /*long*/[] args) {return accSelect((int)/*64*/args[0], args[1]);}
89             public int /*long*/ method22(int /*long*/[] args) {return accLocation(args[0], args[1], args[2], args[3], args[4]);}
90             public int /*long*/ method23(int /*long*/[] args) {return accNavigate((int)/*64*/args[0], args[1], args[2]);}
91             public int /*long*/ method24(int /*long*/[] args) {return accHitTest((int)/*64*/args[0], (int)/*64*/args[1], args[2]);}
92             public int /*long*/ method25(int /*long*/[] args) {return accDoDefaultAction(args[0]);}
93             public int /*long*/ method26(int /*long*/[] args) {return put_accName(args[0], args[1]);}
94             public int /*long*/ method27(int /*long*/[] args) {return put_accValue(args[0], args[1]);}
95         };
96
97         int /*long*/ ppVtable = objIAccessible.ppVtable;
98         int /*long*/[] pVtable = new int /*long*/[1];
99         COM.MoveMemory(pVtable, ppVtable, OS.PTR_SIZEOF);
100         int /*long*/[] funcs = new int /*long*/[28];
101         COM.MoveMemory(funcs, pVtable[0], OS.PTR_SIZEOF * funcs.length);
102         funcs[9] = COM.get_accChild_CALLBACK(funcs[9]);
103         funcs[10] = COM.get_accName_CALLBACK(funcs[10]);
104         funcs[11] = COM.get_accValue_CALLBACK(funcs[11]);
105         funcs[12] = COM.get_accDescription_CALLBACK(funcs[12]);
106         funcs[13] = COM.get_accRole_CALLBACK(funcs[13]);
107         funcs[14] = COM.get_accState_CALLBACK(funcs[14]);
108         funcs[15] = COM.get_accHelp_CALLBACK(funcs[15]);
109         funcs[16] = COM.get_accHelpTopic_CALLBACK(funcs[16]);
110         funcs[17] = COM.get_accKeyboardShortcut_CALLBACK(funcs[17]);
111         funcs[20] = COM.get_accDefaultAction_CALLBACK(funcs[20]);
112         funcs[21] = COM.accSelect_CALLBACK(funcs[21]);
113         funcs[22] = COM.accLocation_CALLBACK(funcs[22]);
114         funcs[23] = COM.accNavigate_CALLBACK(funcs[23]);
115         funcs[25] = COM.accDoDefaultAction_CALLBACK(funcs[25]);
116         funcs[26] = COM.put_accName_CALLBACK(funcs[26]);
117         funcs[27] = COM.put_accValue_CALLBACK(funcs[27]);
118         COM.MoveMemory(pVtable[0], funcs, OS.PTR_SIZEOF * funcs.length);
119
120         objIEnumVARIANT = new COMObject(new int[] {2,0,0,3,1,0,1}) {
121             public int /*long*/ method0(int /*long*/[] args) {return QueryInterface(args[0], args[1]);}
122             public int /*long*/ method1(int /*long*/[] args) {return AddRef();}
123             public int /*long*/ method2(int /*long*/[] args) {return Release();}
124             public int /*long*/ method3(int /*long*/[] args) {return Next((int)args[0], args[1], args[2]);}
125             public int /*long*/ method4(int /*long*/[] args) {return Skip((int)args[0]);}
126             public int /*long*/ method5(int /*long*/[] args) {return Reset();}
127             public int /*long*/ method6(int /*long*/[] args) {return Clone(args[0]);}
128         };
129         AddRef();
130     }
131     
132     /**
133      * Invokes platform specific functionality to allocate a new accessible object.
134      * <p>
135      * <b>IMPORTANT:</b> This method is <em>not</em> part of the public
136      * API for <code>Accessible</code>. It is marked public only so that it
137      * can be shared within the packages provided by SWT. It is not
138      * available on all platforms, and should never be called from
139      * application code.
140      * </p>
141      *
142      * @param control the control to get the accessible object for
143      * @return the platform specific accessible object
144      */

145     public static Accessible internal_new_Accessible(Control control) {
146         return new Accessible(control);
147     }
148
149     /**
150      * Adds the listener to the collection of listeners who will
151      * be notified when an accessible client asks for certain strings,
152      * such as name, description, help, or keyboard shortcut. The
153      * listener is notified by sending it one of the messages defined
154      * in the <code>AccessibleListener</code> interface.
155      *
156      * @param listener the listener that should be notified when the receiver
157      * is asked for a name, description, help, or keyboard shortcut string
158      *
159      * @exception IllegalArgumentException <ul>
160      * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
161      * </ul>
162      * @exception SWTException <ul>
163      * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
164      * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
165      * </ul>
166      *
167      * @see AccessibleListener
168      * @see #removeAccessibleListener
169      */

170     public void addAccessibleListener(AccessibleListener listener) {
171         checkWidget();
172         if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
173         accessibleListeners.addElement(listener);
174     }
175     
176     /**
177      * Adds the listener to the collection of listeners who will
178      * be notified when an accessible client asks for custom control
179      * specific information. The listener is notified by sending it
180      * one of the messages defined in the <code>AccessibleControlListener</code>
181      * interface.
182      *
183      * @param listener the listener that should be notified when the receiver
184      * is asked for custom control specific information
185      *
186      * @exception IllegalArgumentException <ul>
187      * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
188      * </ul>
189      * @exception SWTException <ul>
190      * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
191      * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
192      * </ul>
193      *
194      * @see AccessibleControlListener
195      * @see #removeAccessibleControlListener
196      */

197     public void addAccessibleControlListener(AccessibleControlListener listener) {
198         checkWidget();
199         if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
200         accessibleControlListeners.addElement(listener);
201     }
202
203     /**
204      * Adds the listener to the collection of listeners who will
205      * be notified when an accessible client asks for custom text control
206      * specific information. The listener is notified by sending it
207      * one of the messages defined in the <code>AccessibleTextListener</code>
208      * interface.
209      *
210      * @param listener the listener that should be notified when the receiver
211      * is asked for custom text control specific information
212      *
213      * @exception IllegalArgumentException <ul>
214      * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
215      * </ul>
216      * @exception SWTException <ul>
217      * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
218      * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
219      * </ul>
220      *
221      * @see AccessibleTextListener
222      * @see #removeAccessibleTextListener
223      *
224      * @since 3.0
225      */

226     public void addAccessibleTextListener (AccessibleTextListener listener) {
227         checkWidget ();
228         if (listener == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
229         textListeners.addElement (listener);
230     }
231     
232     /**
233      * Returns the control for this Accessible object.
234      *
235      * @return the receiver's control
236      * @since 3.0
237      */

238     public Control getControl() {
239         return control;
240     }
241
242     /**
243      * Invokes platform specific functionality to dispose an accessible object.
244      * <p>
245      * <b>IMPORTANT:</b> This method is <em>not</em> part of the public
246      * API for <code>Accessible</code>. It is marked public only so that it
247      * can be shared within the packages provided by SWT. It is not
248      * available on all platforms, and should never be called from
249      * application code.
250      * </p>
251      */

252     public void internal_dispose_Accessible() {
253         if (iaccessible != null) {
254             iaccessible.Release();
255         }
256         iaccessible = null;
257         Release();
258     }
259     
260     /**
261      * Invokes platform specific functionality to handle a window message.
262      * <p>
263      * <b>IMPORTANT:</b> This method is <em>not</em> part of the public
264      * API for <code>Accessible</code>. It is marked public only so that it
265      * can be shared within the packages provided by SWT. It is not
266      * available on all platforms, and should never be called from
267      * application code.
268      * </p>
269      */

270     public int /*long*/ internal_WM_GETOBJECT (int /*long*/ wParam, int /*long*/ lParam) {
271         if (objIAccessible == null) return 0;
272         if ((int)/*64*/lParam == COM.OBJID_CLIENT) {
273             /* LresultFromObject([in] riid, [in] wParam, [in] pAcc)
274              * The argument pAcc is owned by the caller so reference count does not
275              * need to be incremented.
276              */

277             return COM.LresultFromObject(COM.IIDIAccessible, wParam, objIAccessible.getAddress());
278         }
279         return 0;
280     }
281
282     /**
283      * Removes the listener from the collection of listeners who will
284      * be notified when an accessible client asks for certain strings,
285      * such as name, description, help, or keyboard shortcut.
286      *
287      * @param listener the listener that should no longer be notified when the receiver
288      * is asked for a name, description, help, or keyboard shortcut string
289      *
290      * @exception IllegalArgumentException <ul>
291      * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
292      * </ul>
293      * @exception SWTException <ul>
294      * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
295      * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
296      * </ul>
297      *
298      * @see AccessibleListener
299      * @see #addAccessibleListener
300      */

301     public void removeAccessibleListener(AccessibleListener listener) {
302         checkWidget();
303         if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
304         accessibleListeners.removeElement(listener);
305     }
306
307     /**
308      * Removes the listener from the collection of listeners who will
309      * be notified when an accessible client asks for custom control
310      * specific information.
311      *
312      * @param listener the listener that should no longer be notified when the receiver
313      * is asked for custom control specific information
314      *
315      * @exception IllegalArgumentException <ul>
316      * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
317      * </ul>
318      * @exception SWTException <ul>
319      * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
320      * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
321      * </ul>
322      *
323      * @see AccessibleControlListener
324      * @see #addAccessibleControlListener
325      */

326     public void removeAccessibleControlListener(AccessibleControlListener listener) {
327         checkWidget();
328         if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
329         accessibleControlListeners.removeElement(listener);
330     }
331
332     /**
333      * Removes the listener from the collection of listeners who will
334      * be notified when an accessible client asks for custom text control
335      * specific information.
336      *
337      * @param listener the listener that should no longer be notified when the receiver
338      * is asked for custom text control specific information
339      *
340      * @exception IllegalArgumentException <ul>
341      * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
342      * </ul>
343      * @exception SWTException <ul>
344      * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
345      * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
346      * </ul>
347      *
348      * @see AccessibleTextListener
349      * @see #addAccessibleTextListener
350      *
351      * @since 3.0
352      */

353     public void removeAccessibleTextListener (AccessibleTextListener listener) {
354         checkWidget ();
355         if (listener == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
356         textListeners.removeElement (listener);
357     }
358
359     /**
360      * Sends a message to accessible clients that the child selection
361      * within a custom container control has changed.
362      *
363      * @exception SWTException <ul>
364      * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
365      * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
366      * </ul>
367      *
368      * @since 3.0
369      */

370     public void selectionChanged () {
371         checkWidget();
372         COM.NotifyWinEvent (COM.EVENT_OBJECT_SELECTIONWITHIN, control.handle, COM.OBJID_CLIENT, COM.CHILDID_SELF);
373     }
374
375     /**
376      * Sends a message to accessible clients indicating that the focus
377      * has changed within a custom control.
378      *
379      * @param childID an identifier specifying a child of the control
380      *
381      * @exception SWTException <ul>
382      * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
383      * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
384      * </ul>
385      */

386     public void setFocus(int childID) {
387         checkWidget();
388         COM.NotifyWinEvent (COM.EVENT_OBJECT_FOCUS, control.handle, COM.OBJID_CLIENT, childIDToOs(childID));
389     }
390
391     /**
392      * Sends a message to accessible clients that the text
393      * caret has moved within a custom control.
394      *
395      * @param index the new caret index within the control
396      *
397      * @exception SWTException <ul>
398      * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
399      * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
400      * </ul>
401      *
402      * @since 3.0
403      */

404     public void textCaretMoved (int index) {
405         checkWidget();
406         COM.NotifyWinEvent (COM.EVENT_OBJECT_LOCATIONCHANGE, control.handle, COM.OBJID_CARET, COM.CHILDID_SELF);
407     }
408     
409     /**
410      * Sends a message to accessible clients that the text
411      * within a custom control has changed.
412      *
413      * @param type the type of change, one of <code>ACC.NOTIFY_TEXT_INSERT</code>
414      * or <code>ACC.NOTIFY_TEXT_DELETE</code>
415      * @param startIndex the text index within the control where the insertion or deletion begins
416      * @param length the non-negative length in characters of the insertion or deletion
417      *
418      * @exception SWTException <ul>
419      * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
420      * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
421      * </ul>
422      *
423      * @see ACC#TEXT_INSERT
424      * @see ACC#TEXT_DELETE
425      *
426      * @since 3.0
427      */

428     public void textChanged (int type, int startIndex, int length) {
429         checkWidget();
430         COM.NotifyWinEvent (COM.EVENT_OBJECT_VALUECHANGE, control.handle, COM.OBJID_CLIENT, COM.CHILDID_SELF);
431     }
432     
433     /**
434      * Sends a message to accessible clients that the text
435      * selection has changed within a custom control.
436      *
437      * @exception SWTException <ul>
438      * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
439      * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
440      * </ul>
441      *
442      * @since 3.0
443      */

444     public void textSelectionChanged () {
445         checkWidget();
446         // not an MSAA event
447
}
448     
449     /* QueryInterface([in] iid, [out] ppvObject)
450      * Ownership of ppvObject transfers from callee to caller so reference count on ppvObject
451      * must be incremented before returning. Caller is responsible for releasing ppvObject.
452      */

453     int QueryInterface(int /*long*/ iid, int /*long*/ ppvObject) {
454         if (iaccessible == null) return COM.CO_E_OBJNOTCONNECTED;
455         GUID guid = new GUID();
456         COM.MoveMemory(guid, iid, GUID.sizeof);
457
458         if (COM.IsEqualGUID(guid, COM.IIDIUnknown)) {
459             COM.MoveMemory(ppvObject, new int /*long*/[] { objIAccessible.getAddress()}, OS.PTR_SIZEOF);
460             AddRef();
461             return COM.S_OK;
462         }
463
464         if (COM.IsEqualGUID(guid, COM.IIDIDispatch)) {
465             COM.MoveMemory(ppvObject, new int /*long*/[] { objIAccessible.getAddress()}, OS.PTR_SIZEOF);
466             AddRef();
467             return COM.S_OK;
468         }
469
470         if (COM.IsEqualGUID(guid, COM.IIDIAccessible)) {
471             COM.MoveMemory(ppvObject, new int /*long*/[] { objIAccessible.getAddress()}, OS.PTR_SIZEOF);
472             AddRef();
473             return COM.S_OK;
474         }
475
476         if (COM.IsEqualGUID(guid, COM.IIDIEnumVARIANT)) {
477             COM.MoveMemory(ppvObject, new int /*long*/[] { objIEnumVARIANT.getAddress()}, OS.PTR_SIZEOF);
478             AddRef();
479             enumIndex = 0;
480             return COM.S_OK;
481         }
482
483         int /*long*/[] ppv = new int /*long*/[1];
484         int result = iaccessible.QueryInterface(guid, ppv);
485         COM.MoveMemory(ppvObject, ppv, OS.PTR_SIZEOF);
486         return result;
487     }
488
489     int AddRef() {
490         refCount++;
491         return refCount;
492     }
493
494     int Release() {
495         refCount--;
496
497         if (refCount == 0) {
498             if (objIAccessible != null)
499                 objIAccessible.dispose();
500             objIAccessible = null;
501                         
502             if (objIEnumVARIANT != null)
503                 objIEnumVARIANT.dispose();
504             objIEnumVARIANT = null;
505         }
506         return refCount;
507     }
508
509     int accDoDefaultAction(int /*long*/ variant) {
510         if (iaccessible == null) return COM.CO_E_OBJNOTCONNECTED;
511         // Currently, we don't let the application override this. Forward to the proxy.
512
int code = iaccessible.accDoDefaultAction(variant);
513         if (code == COM.E_INVALIDARG) code = COM.S_FALSE; // proxy doesn't know about app childID
514
return code;
515     }
516
517     int accHitTest(int xLeft, int yTop, int /*long*/ pvarChild) {
518         if (iaccessible == null) return COM.CO_E_OBJNOTCONNECTED;
519         if (accessibleControlListeners.size() == 0) {
520             return iaccessible.accHitTest(xLeft, yTop, pvarChild);
521         }
522
523         AccessibleControlEvent event = new AccessibleControlEvent(this);
524         event.childID = ACC.CHILDID_NONE;
525         event.x = xLeft;
526         event.y = yTop;
527         for (int i = 0; i < accessibleControlListeners.size(); i++) {
528             AccessibleControlListener listener = (AccessibleControlListener) accessibleControlListeners.elementAt(i);
529             listener.getChildAtPoint(event);
530         }
531         int childID = event.childID;
532         if (childID == ACC.CHILDID_NONE) {
533             return iaccessible.accHitTest(xLeft, yTop, pvarChild);
534         }
535         COM.MoveMemory(pvarChild, new short[] { COM.VT_I4 }, 2);
536         COM.MoveMemory(pvarChild + 8, new int[] { childIDToOs(childID) }, 4);
537         return COM.S_OK;
538     }
539     
540     int accLocation(int /*long*/ pxLeft, int /*long*/ pyTop, int /*long*/ pcxWidth, int /*long*/ pcyHeight, int /*long*/ variant) {
541         if (iaccessible == null) return COM.CO_E_OBJNOTCONNECTED;
542         VARIANT v = new VARIANT();
543         COM.MoveMemory(v, variant, VARIANT.sizeof);
544         if ((v.vt & 0xFFFF) != COM.VT_I4) return COM.E_INVALIDARG;
545
546         /* Get the default location from the OS. */
547         int osLeft = 0, osTop = 0, osWidth = 0, osHeight = 0;
548         int code = iaccessible.accLocation(pxLeft, pyTop, pcxWidth, pcyHeight, variant);
549         if (code == COM.E_INVALIDARG) code = COM.S_FALSE; // proxy doesn't know about app childID
550
if (accessibleControlListeners.size() == 0) return code;
551         if (code == COM.S_OK) {
552             int[] pLeft = new int[1], pTop = new int[1], pWidth = new int[1], pHeight = new int[1];
553             COM.MoveMemory(pLeft, pxLeft, 4);
554             COM.MoveMemory(pTop, pyTop, 4);
555             COM.MoveMemory(pWidth, pcxWidth, 4);
556             COM.MoveMemory(pHeight, pcyHeight, 4);
557             osLeft = pLeft[0]; osTop = pTop[0]; osWidth = pWidth[0]; osHeight = pHeight[0];
558         }
559
560         AccessibleControlEvent event = new AccessibleControlEvent(this);
561         event.childID = osToChildID((int)/*64*/v.lVal);
562         event.x = osLeft;
563         event.y = osTop;
564         event.width = osWidth;
565         event.height = osHeight;
566         for (int i = 0; i < accessibleControlListeners.size(); i++) {
567             AccessibleControlListener listener = (AccessibleControlListener) accessibleControlListeners.elementAt(i);
568             listener.getLocation(event);
569         }
570         OS.MoveMemory(pxLeft, new int[] { event.x }, 4);
571         OS.MoveMemory(pyTop, new int[] { event.y }, 4);
572         OS.MoveMemory(pcxWidth, new int[] { event.width }, 4);
573         OS.MoveMemory(pcyHeight, new int[] { event.height }, 4);
574         return COM.S_OK;
575     }
576     
577     int accNavigate(int navDir, int /*long*/ variant, int /*long*/ pvarEndUpAt) {
578         if (iaccessible == null) return COM.CO_E_OBJNOTCONNECTED;
579         // Currently, we don't let the application override this. Forward to the proxy.
580
int code = iaccessible.accNavigate(navDir, variant, pvarEndUpAt);
581         if (code == COM.E_INVALIDARG) code = COM.S_FALSE; // proxy doesn't know about app childID
582
return code;
583     }
584     
585     int accSelect(int flagsSelect, int /*long*/ variant) {
586         if (iaccessible == null) return COM.CO_E_OBJNOTCONNECTED;
587         // Currently, we don't let the application override this. Forward to the proxy.
588
int code = iaccessible.accSelect(flagsSelect, variant);
589         if (code == COM.E_INVALIDARG) code = COM.S_FALSE; // proxy doesn't know about app childID
590
return code;
591     }
592
593     /* get_accChild([in] varChild, [out] ppdispChild)
594      * Ownership of ppdispChild transfers from callee to caller so reference count on ppdispChild
595      * must be incremented before returning. The caller is responsible for releasing ppdispChild.
596      */

597     int get_accChild(int /*long*/ variant, int /*long*/ ppdispChild) {
598         if (iaccessible == null) return COM.CO_E_OBJNOTCONNECTED;
599         VARIANT v = new VARIANT();
600         COM.MoveMemory(v, variant, VARIANT.sizeof);
601         if ((v.vt & 0xFFFF) != COM.VT_I4) return COM.E_INVALIDARG;
602         if (accessibleControlListeners.size() == 0) {
603             int code = iaccessible.get_accChild(variant, ppdispChild);
604             if (code == COM.E_INVALIDARG) code = COM.S_FALSE; // proxy doesn't know about app childID
605
return code;
606         }
607
608         AccessibleControlEvent event = new AccessibleControlEvent(this);
609         event.childID = osToChildID((int)/*64*/v.lVal);
610         for (int i = 0; i < accessibleControlListeners.size(); i++) {
611             AccessibleControlListener listener = (AccessibleControlListener) accessibleControlListeners.elementAt(i);
612             listener.getChild(event);
613         }
614         Accessible accessible = event.accessible;
615         if (accessible != null) {
616             accessible.AddRef();
617             COM.MoveMemory(ppdispChild, new int /*long*/[] { accessible.objIAccessible.getAddress() }, OS.PTR_SIZEOF);
618             return COM.S_OK;
619         }
620         return COM.S_FALSE;
621     }
622     
623     int get_accChildCount(int /*long*/ pcountChildren) {
624         if (iaccessible == null) return COM.CO_E_OBJNOTCONNECTED;
625
626         /* Get the default child count from the OS. */
627         int osChildCount = 0;
628         int code = iaccessible.get_accChildCount(pcountChildren);
629         if (accessibleControlListeners.size() == 0) return code;
630         if (code == COM.S_OK) {
631             int[] pChildCount = new int[1];
632             COM.MoveMemory(pChildCount, pcountChildren, 4);
633             osChildCount = pChildCount[0];
634         }
635
636         AccessibleControlEvent event = new AccessibleControlEvent(this);
637         event.childID = ACC.CHILDID_SELF;
638         event.detail = osChildCount;
639         for (int i = 0; i < accessibleControlListeners.size(); i++) {
640             AccessibleControlListener listener = (AccessibleControlListener) accessibleControlListeners.elementAt(i);
641             listener.getChildCount(event);
642         }
643
644         COM.MoveMemory(pcountChildren, new int[] { event.detail }, 4);
645         return COM.S_OK;
646     }
647     
648     int get_accDefaultAction(int /*long*/ variant, int /*long*/ pszDefaultAction) {
649         if (iaccessible == null) return COM.CO_E_OBJNOTCONNECTED;
650         VARIANT v = new VARIANT();
651         COM.MoveMemory(v, variant, VARIANT.sizeof);
652         if ((v.vt & 0xFFFF) != COM.VT_I4) return COM.E_INVALIDARG;
653         
654         /* Get the default defaultAction from the OS. */
655         String JavaDoc osDefaultAction = null;
656         int code = iaccessible.get_accDefaultAction(variant, pszDefaultAction);
657         if (code == COM.E_INVALIDARG) code = COM.S_FALSE; // proxy doesn't know about app childID
658
if (accessibleControlListeners.size() == 0) return code;
659         if (code == COM.S_OK) {
660             int /*long*/[] pDefaultAction = new int /*long*/[1];
661             COM.MoveMemory(pDefaultAction, pszDefaultAction, OS.PTR_SIZEOF);
662             int size = COM.SysStringByteLen(pDefaultAction[0]);
663             if (size > 0) {
664                 char[] buffer = new char[(size + 1) /2];
665                 COM.MoveMemory(buffer, pDefaultAction[0], size);
666                 osDefaultAction = new String JavaDoc(buffer);
667             }
668         }
669
670         AccessibleControlEvent event = new AccessibleControlEvent(this);
671         event.childID = osToChildID((int)/*64*/v.lVal);
672         event.result = osDefaultAction;
673         for (int i = 0; i < accessibleControlListeners.size(); i++) {
674             AccessibleControlListener listener = (AccessibleControlListener) accessibleControlListeners.elementAt(i);
675             listener.getDefaultAction(event);
676         }
677         if (event.result == null) return code;
678         char[] data = (event.result + "\0").toCharArray();
679         int /*long*/ ptr = COM.SysAllocString(data);
680         COM.MoveMemory(pszDefaultAction, new int /*long*/[] { ptr }, OS.PTR_SIZEOF);
681         return COM.S_OK;
682     }
683     
684     int get_accDescription(int /*long*/ variant, int /*long*/ pszDescription) {
685         if (iaccessible == null) return COM.CO_E_OBJNOTCONNECTED;
686         VARIANT v = new VARIANT();
687         COM.MoveMemory(v, variant, VARIANT.sizeof);
688         if ((v.vt & 0xFFFF) != COM.VT_I4) return COM.E_INVALIDARG;
689         
690         /* Get the default description from the OS. */
691         String JavaDoc osDescription = null;
692         int code = iaccessible.get_accDescription(variant, pszDescription);
693         if (code == COM.E_INVALIDARG) code = COM.S_FALSE; // proxy doesn't know about app childID
694
// TEMPORARY CODE - process tree even if there are no apps listening
695
if (accessibleListeners.size() == 0 && !(control instanceof Tree)) return code;
696         if (code == COM.S_OK) {
697             int /*long*/[] pDescription = new int /*long*/[1];
698             COM.MoveMemory(pDescription, pszDescription, OS.PTR_SIZEOF);
699             int size = COM.SysStringByteLen(pDescription[0]);
700             if (size > 0) {
701                 char[] buffer = new char[(size + 1) /2];
702                 COM.MoveMemory(buffer, pDescription[0], size);
703                 osDescription = new String JavaDoc(buffer);
704             }
705         }
706         
707         AccessibleEvent event = new AccessibleEvent(this);
708         event.childID = osToChildID((int)/*64*/v.lVal);
709         event.result = osDescription;
710         
711         // TEMPORARY CODE
712
/* Currently our tree columns are emulated using custom draw,
713          * so we need to create the description using the tree column
714          * header text and tree item text. */

715         if (v.lVal != COM.CHILDID_SELF) {
716             if (control instanceof Tree) {
717                 Tree tree = (Tree) control;
718                 int columnCount = tree.getColumnCount ();
719                 if (columnCount > 1) {
720                     int /*long*/ hwnd = control.handle, hItem = 0;
721                     if (OS.COMCTL32_MAJOR >= 6) {
722                         hItem = OS.SendMessage (hwnd, OS.TVM_MAPACCIDTOHTREEITEM, v.lVal, 0);
723                     } else {
724                         hItem = v.lVal;
725                     }
726                     Widget widget = tree.getDisplay ().findWidget (hwnd, hItem);
727                     event.result = "";
728                     if (widget != null && widget instanceof TreeItem) {
729                         TreeItem item = (TreeItem) widget;
730                         for (int i = 1; i < columnCount; i++) {
731                             event.result += tree.getColumn(i).getText() + ": " + item.getText(i);
732                             if (i + 1 < columnCount) event.result += ", ";
733                         }
734                     }
735                 }
736             }
737         }
738         for (int i = 0; i < accessibleListeners.size(); i++) {
739             AccessibleListener listener = (AccessibleListener) accessibleListeners.elementAt(i);
740             listener.getDescription(event);
741         }
742         if (event.result == null) return code;
743         char[] data = (event.result + "\0").toCharArray();
744         int /*long*/ ptr = COM.SysAllocString(data);
745         COM.MoveMemory(pszDescription, new int /*long*/[] { ptr }, OS.PTR_SIZEOF);
746         return COM.S_OK;
747     }
748     
749     /* get_accFocus([out] int pvarChild)
750      * Ownership of pvarChild transfers from callee to caller so reference count on pvarChild
751      * must be incremented before returning. The caller is responsible for releasing pvarChild.
752      */

753     int get_accFocus(int /*long*/ pvarChild) {
754         if (iaccessible == null) return COM.CO_E_OBJNOTCONNECTED;
755
756         /* Get the default focus child from the OS. */
757         int osChild = ACC.CHILDID_NONE;
758         int code = iaccessible.get_accFocus(pvarChild);
759         if (accessibleControlListeners.size() == 0) return code;
760         if (code == COM.S_OK) {
761             short[] pvt = new short[1];
762             COM.MoveMemory(pvt, pvarChild, 2);
763             if (pvt[0] == COM.VT_I4) {
764                 int[] pChild = new int[1];
765                 COM.MoveMemory(pChild, pvarChild + 8, 4);
766                 osChild = osToChildID(pChild[0]);
767             }
768         }
769
770         AccessibleControlEvent event = new AccessibleControlEvent(this);
771         event.childID = osChild;
772         for (int i = 0; i < accessibleControlListeners.size(); i++) {
773             AccessibleControlListener listener = (AccessibleControlListener) accessibleControlListeners.elementAt(i);
774             listener.getFocus(event);
775         }
776         Accessible accessible = event.accessible;
777         if (accessible != null) {
778             accessible.AddRef();
779             COM.MoveMemory(pvarChild, new short[] { COM.VT_DISPATCH }, 2);
780             COM.MoveMemory(pvarChild + 8, new int /*long*/[] { accessible.objIAccessible.getAddress() }, OS.PTR_SIZEOF);
781             return COM.S_OK;
782         }
783         int childID = event.childID;
784         if (childID == ACC.CHILDID_NONE) {
785             COM.MoveMemory(pvarChild, new short[] { COM.VT_EMPTY }, 2);
786             return COM.S_FALSE;
787         }
788         if (childID == ACC.CHILDID_SELF) {
789             AddRef();
790             COM.MoveMemory(pvarChild, new short[] { COM.VT_DISPATCH }, 2);
791             COM.MoveMemory(pvarChild + 8, new int /*long*/[] { objIAccessible.getAddress() }, OS.PTR_SIZEOF);
792             return COM.S_OK;
793         }
794         COM.MoveMemory(pvarChild, new short[] { COM.VT_I4 }, 2);
795         COM.MoveMemory(pvarChild + 8, new int[] { childIDToOs(childID) }, 4);
796         return COM.S_OK;
797     }
798     
799     int get_accHelp(int /*long*/ variant, int /*long*/ pszHelp) {
800         if (iaccessible == null) return COM.CO_E_OBJNOTCONNECTED;
801         VARIANT v = new VARIANT();
802         COM.MoveMemory(v, variant, VARIANT.sizeof);
803         if ((v.vt & 0xFFFF) != COM.VT_I4) return COM.E_INVALIDARG;
804         
805         /* Get the default help string from the OS. */
806         String JavaDoc osHelp = null;
807         int code = iaccessible.get_accHelp(variant, pszHelp);
808         if (code == COM.E_INVALIDARG) code = COM.S_FALSE; // proxy doesn't know about app childID
809
if (accessibleListeners.size() == 0) return code;
810         if (code == COM.S_OK) {
811             int /*long*/[] pHelp = new int /*long*/[1];
812             COM.MoveMemory(pHelp, pszHelp, OS.PTR_SIZEOF);
813             int size = COM.SysStringByteLen(pHelp[0]);
814             if (size > 0) {
815                 char[] buffer = new char[(size + 1) /2];
816                 COM.MoveMemory(buffer, pHelp[0], size);
817                 osHelp = new String JavaDoc(buffer);
818             }
819         }
820
821         AccessibleEvent event = new AccessibleEvent(this);
822         event.childID = osToChildID((int)/*64*/v.lVal);
823         event.result = osHelp;
824         for (int i = 0; i < accessibleListeners.size(); i++) {
825             AccessibleListener listener = (AccessibleListener) accessibleListeners.elementAt(i);
826             listener.getHelp(event);
827         }
828         if (event.result == null) return code;
829         char[] data = (event.result + "\0").toCharArray();
830         int /*long*/ ptr = COM.SysAllocString(data);
831         COM.MoveMemory(pszHelp, new int /*long*/[] { ptr }, OS.PTR_SIZEOF);
832         return COM.S_OK;
833     }
834     
835     int get_accHelpTopic(int /*long*/ pszHelpFile, int /*long*/ variant, int /*long*/ pidTopic) {
836         if (iaccessible == null) return COM.CO_E_OBJNOTCONNECTED;
837         // Currently, we don't let the application override this. Forward to the proxy.
838
int code = iaccessible.get_accHelpTopic(pszHelpFile, variant, pidTopic);
839         if (code == COM.E_INVALIDARG) code = COM.S_FALSE; // proxy doesn't know about app childID
840
return code;
841     }
842
843     int get_accKeyboardShortcut(int /*long*/ variant, int /*long*/ pszKeyboardShortcut) {
844         if (iaccessible == null) return COM.CO_E_OBJNOTCONNECTED;
845         VARIANT v = new VARIANT();
846         COM.MoveMemory(v, variant, VARIANT.sizeof);
847         if ((v.vt & 0xFFFF) != COM.VT_I4) return COM.E_INVALIDARG;
848         
849         /* Get the default keyboard shortcut from the OS. */
850         String JavaDoc osKeyboardShortcut = null;
851         int code = iaccessible.get_accKeyboardShortcut(variant, pszKeyboardShortcut);
852         if (code == COM.E_INVALIDARG) code = COM.S_FALSE; // proxy doesn't know about app childID
853
if (accessibleListeners.size() == 0) return code;
854         if (code == COM.S_OK) {
855             int /*long*/[] pKeyboardShortcut = new int /*long*/[1];
856             COM.MoveMemory(pKeyboardShortcut, pszKeyboardShortcut, OS.PTR_SIZEOF);
857             int size = COM.SysStringByteLen(pKeyboardShortcut[0]);
858             if (size > 0) {
859                 char[] buffer = new char[(size + 1) /2];
860                 COM.MoveMemory(buffer, pKeyboardShortcut[0], size);
861                 osKeyboardShortcut = new String JavaDoc(buffer);
862             }
863         }
864
865         AccessibleEvent event = new AccessibleEvent(this);
866         event.childID = osToChildID((int)/*64*/v.lVal);
867         event.result = osKeyboardShortcut;
868         for (int i = 0; i < accessibleListeners.size(); i++) {
869             AccessibleListener listener = (AccessibleListener) accessibleListeners.elementAt(i);
870             listener.getKeyboardShortcut(event);
871         }
872         if (event.result == null) return code;
873         char[] data = (event.result + "\0").toCharArray();
874         int /*long*/ ptr = COM.SysAllocString(data);
875         COM.MoveMemory(pszKeyboardShortcut, new int /*long*/[] { ptr }, OS.PTR_SIZEOF);
876         return COM.S_OK;
877     }
878     
879     int get_accName(int /*long*/ variant, int /*long*/ pszName) {
880         if (iaccessible == null) return COM.CO_E_OBJNOTCONNECTED;
881         VARIANT v = new VARIANT();
882         COM.MoveMemory(v, variant, VARIANT.sizeof);
883         if ((v.vt & 0xFFFF) != COM.VT_I4) return COM.E_INVALIDARG;
884
885         /* Get the default name from the OS. */
886         String JavaDoc osName = null;
887         int code = iaccessible.get_accName(variant, pszName);
888         if (code == COM.E_INVALIDARG) code = COM.S_FALSE; // proxy doesn't know about app childID
889
if (accessibleListeners.size() == 0) return code;
890         if (code == COM.S_OK) {
891             int /*long*/[] pName = new int /*long*/[1];
892             COM.MoveMemory(pName, pszName, OS.PTR_SIZEOF);
893             int size = COM.SysStringByteLen(pName[0]);
894             if (size > 0) {
895                 char[] buffer = new char[(size + 1) /2];
896                 COM.MoveMemory(buffer, pName[0], size);
897                 osName = new String JavaDoc(buffer);
898             }
899         }
900
901         AccessibleEvent event = new AccessibleEvent(this);
902         event.childID = osToChildID((int)/*64*/v.lVal);
903         event.result = osName;
904         for (int i = 0; i < accessibleListeners.size(); i++) {
905             AccessibleListener listener = (AccessibleListener) accessibleListeners.elementAt(i);
906             listener.getName(event);
907         }
908         if (event.result == null) return code;
909         char[] data = (event.result + "\0").toCharArray();
910         int /*long*/ ptr = COM.SysAllocString(data);
911         COM.MoveMemory(pszName, new int /*long*/[] { ptr }, OS.PTR_SIZEOF);
912         return COM.S_OK;
913     }
914     
915     /* get_accParent([out] ppdispParent)
916      * Ownership of ppdispParent transfers from callee to caller so reference count on ppdispParent
917      * must be incremented before returning. The caller is responsible for releasing ppdispParent.
918      */

919     int get_accParent(int /*long*/ ppdispParent) {
920         if (iaccessible == null) return COM.CO_E_OBJNOTCONNECTED;
921         // Currently, we don't let the application override this. Forward to the proxy.
922
return iaccessible.get_accParent(ppdispParent);
923     }
924     
925     int get_accRole(int /*long*/ variant, int /*long*/ pvarRole) {
926         if (iaccessible == null) return COM.CO_E_OBJNOTCONNECTED;
927         VARIANT v = new VARIANT();
928         COM.MoveMemory(v, variant, VARIANT.sizeof);
929         if ((v.vt & 0xFFFF) != COM.VT_I4) return COM.E_INVALIDARG;
930
931         /* Get the default role from the OS. */
932         int osRole = COM.ROLE_SYSTEM_CLIENT;
933         int code = iaccessible.get_accRole(variant, pvarRole);
934         if (code == COM.E_INVALIDARG) code = COM.S_FALSE; // proxy doesn't know about app childID
935
// TEMPORARY CODE - process tree and table even if there are no apps listening
936
if (accessibleControlListeners.size() == 0 && !(control instanceof Tree || control instanceof Table)) return code;
937         if (code == COM.S_OK) {
938             short[] pvt = new short[1];
939             COM.MoveMemory(pvt, pvarRole, 2);
940             if (pvt[0] == COM.VT_I4) {
941                 int[] pRole = new int[1];
942                 COM.MoveMemory(pRole, pvarRole + 8, 4);
943                 osRole = pRole[0];
944             }
945         }
946
947         AccessibleControlEvent event = new AccessibleControlEvent(this);
948         event.childID = osToChildID((int)/*64*/v.lVal);
949         event.detail = osToRole(osRole);
950         // TEMPORARY CODE
951
/* Currently our checkbox table and tree are emulated using state mask
952          * images, so we need to specify 'checkbox' role for the items. */

953         if (v.lVal != COM.CHILDID_SELF) {
954             if (control instanceof Tree || control instanceof Table) {
955                 if ((control.getStyle() & SWT.CHECK) != 0) event.detail = ACC.ROLE_CHECKBUTTON;
956             }
957         }
958         for (int i = 0; i < accessibleControlListeners.size(); i++) {
959             AccessibleControlListener listener = (AccessibleControlListener) accessibleControlListeners.elementAt(i);
960             listener.getRole(event);
961         }
962         int role = roleToOs(event.detail);
963         COM.MoveMemory(pvarRole, new short[] { COM.VT_I4 }, 2);
964         COM.MoveMemory(pvarRole + 8, new int[] { role }, 4);
965         return COM.S_OK;
966     }
967     
968     /* get_accSelection([out] pvarChildren)
969      * Ownership of pvarChildren transfers from callee to caller so reference count on pvarChildren
970      * must be incremented before returning. The caller is responsible for releasing pvarChildren.
971      */

972     int get_accSelection(int /*long*/ pvarChildren) {
973         if (iaccessible == null) return COM.CO_E_OBJNOTCONNECTED;
974
975         /* Get the default selection from the OS. */
976         int osChild = ACC.CHILDID_NONE;
977         int code = iaccessible.get_accSelection(pvarChildren);
978         if (accessibleControlListeners.size() == 0) return code;
979         if (code == COM.S_OK) {
980             short[] pvt = new short[1];
981             COM.MoveMemory(pvt, pvarChildren, 2);
982             if (pvt[0] == COM.VT_I4) {
983                 int[] pChild = new int[1];
984                 COM.MoveMemory(pChild, pvarChildren + 8, 4);
985                 osChild = osToChildID(pChild[0]);
986             } else if (pvt[0] == COM.VT_UNKNOWN) {
987                 osChild = ACC.CHILDID_MULTIPLE;
988                 /* Should get IEnumVARIANT from punkVal field, and enumerate children... */
989             }
990         }
991
992         AccessibleControlEvent event = new AccessibleControlEvent(this);
993         event.childID = osChild;
994         for (int i = 0; i < accessibleControlListeners.size(); i++) {
995             AccessibleControlListener listener = (AccessibleControlListener) accessibleControlListeners.elementAt(i);
996             listener.getSelection(event);
997         }
998         Accessible accessible = event.accessible;
999         if (accessible != null) {
1000            accessible.AddRef();
1001            COM.MoveMemory(pvarChildren, new short[] { COM.VT_DISPATCH }, 2);
1002            COM.MoveMemory(pvarChildren + 8, new int /*long*/[] { accessible.objIAccessible.getAddress() }, OS.PTR_SIZEOF);
1003            return COM.S_OK;
1004        }
1005        int childID = event.childID;
1006        if (childID == ACC.CHILDID_NONE) {
1007            COM.MoveMemory(pvarChildren, new short[] { COM.VT_EMPTY }, 2);
1008            return COM.S_FALSE;
1009        }
1010        if (childID == ACC.CHILDID_MULTIPLE) {
1011            AddRef();
1012            COM.MoveMemory(pvarChildren, new short[] { COM.VT_UNKNOWN }, 2);
1013            COM.MoveMemory(pvarChildren + 8, new int /*long*/[] { objIAccessible.getAddress() }, OS.PTR_SIZEOF);
1014            return COM.S_OK;
1015        }
1016        if (childID == ACC.CHILDID_SELF) {
1017            AddRef();
1018            COM.MoveMemory(pvarChildren, new short[] { COM.VT_DISPATCH }, 2);
1019            COM.MoveMemory(pvarChildren + 8, new int /*long*/[] { objIAccessible.getAddress() }, OS.PTR_SIZEOF);
1020            return COM.S_OK;
1021        }
1022        COM.MoveMemory(pvarChildren, new short[] { COM.VT_I4 }, 2);
1023        COM.MoveMemory(pvarChildren + 8, new int[] { childIDToOs(childID) }, 4);
1024        return COM.S_OK;
1025    }
1026    
1027    int get_accState(int /*long*/ variant, int /*long*/ pvarState) {
1028        if (iaccessible == null) return COM.CO_E_OBJNOTCONNECTED;
1029        VARIANT v = new VARIANT();
1030        COM.MoveMemory(v, variant, VARIANT.sizeof);
1031        if ((v.vt & 0xFFFF) != COM.VT_I4) return COM.E_INVALIDARG;
1032
1033        /* Get the default state from the OS. */
1034        int osState = 0;
1035        int code = iaccessible.get_accState(variant, pvarState);
1036        if (code == COM.E_INVALIDARG) code = COM.S_FALSE; // proxy doesn't know about app childID
1037
// TEMPORARY CODE - process tree and table even if there are no apps listening
1038
if (accessibleControlListeners.size() == 0 && !(control instanceof Tree || control instanceof Table)) return code;
1039        if (code == COM.S_OK) {
1040            short[] pvt = new short[1];
1041            COM.MoveMemory(pvt, pvarState, 2);
1042            if (pvt[0] == COM.VT_I4) {
1043                int[] pState = new int[1];
1044                COM.MoveMemory(pState, pvarState + 8, 4);
1045                osState = pState[0];
1046            }
1047        }
1048
1049        AccessibleControlEvent event = new AccessibleControlEvent(this);
1050        event.childID = osToChildID((int)/*64*/v.lVal);
1051        event.detail = osToState(osState);
1052        // TEMPORARY CODE
1053
/* Currently our checkbox table and tree are emulated using state mask
1054         * images, so we need to determine if the item state is 'checked'. */

1055        if (v.lVal != COM.CHILDID_SELF) {
1056            if (control instanceof Tree && (control.getStyle() & SWT.CHECK) != 0) {
1057                int /*long*/ hwnd = control.handle;
1058                TVITEM tvItem = new TVITEM ();
1059                tvItem.mask = OS.TVIF_HANDLE | OS.TVIF_STATE;
1060                tvItem.stateMask = OS.TVIS_STATEIMAGEMASK;
1061                if (OS.COMCTL32_MAJOR >= 6) {
1062                    tvItem.hItem = OS.SendMessage (hwnd, OS.TVM_MAPACCIDTOHTREEITEM, v.lVal, 0);
1063                } else {
1064                    tvItem.hItem = v.lVal;
1065                }
1066                int /*long*/ result = OS.SendMessage (hwnd, OS.TVM_GETITEM, 0, tvItem);
1067                boolean checked = (result != 0) && (((tvItem.state >> 12) & 1) == 0);
1068                if (checked) event.detail |= ACC.STATE_CHECKED;
1069            } else if (control instanceof Table && (control.getStyle() & SWT.CHECK) != 0) {
1070                Table table = (Table) control;
1071                TableItem item = table.getItem(event.childID);
1072                if (item != null) {
1073                    if (item.getChecked()) event.detail |= ACC.STATE_CHECKED;
1074                }
1075            }
1076        }
1077        for (int i = 0; i < accessibleControlListeners.size(); i++) {
1078            AccessibleControlListener listener = (AccessibleControlListener) accessibleControlListeners.elementAt(i);
1079            listener.getState(event);
1080        }
1081        int state = stateToOs(event.detail);
1082        COM.MoveMemory(pvarState, new short[] { COM.VT_I4 }, 2);
1083        COM.MoveMemory(pvarState + 8, new int[] { state }, 4);
1084        return COM.S_OK;
1085    }
1086    
1087    int get_accValue(int /*long*/ variant, int /*long*/ pszValue) {
1088        if (iaccessible == null) return COM.CO_E_OBJNOTCONNECTED;
1089        VARIANT v = new VARIANT();
1090        COM.MoveMemory(v, variant, VARIANT.sizeof);
1091        if ((v.vt & 0xFFFF) != COM.VT_I4) return COM.E_INVALIDARG;
1092        
1093        /* Get the default value string from the OS. */
1094        String JavaDoc osValue = null;
1095        int code = iaccessible.get_accValue(variant, pszValue);
1096        if (code == COM.E_INVALIDARG) code = COM.S_FALSE; // proxy doesn't know about app childID
1097
if (accessibleControlListeners.size() == 0) return code;
1098        if (code == COM.S_OK) {
1099            int /*long*/[] pValue = new int /*long*/[1];
1100            COM.MoveMemory(pValue, pszValue, OS.PTR_SIZEOF);
1101            int size = COM.SysStringByteLen(pValue[0]);
1102            if (size > 0) {
1103                char[] buffer = new char[(size + 1) /2];
1104                COM.MoveMemory(buffer, pValue[0], size);
1105                osValue = new String JavaDoc(buffer);
1106            }
1107        }
1108
1109        AccessibleControlEvent event = new AccessibleControlEvent(this);
1110        event.childID = osToChildID((int)/*64*/v.lVal);
1111        event.result = osValue;
1112        for (int i = 0; i < accessibleControlListeners.size(); i++) {
1113            AccessibleControlListener listener = (AccessibleControlListener) accessibleControlListeners.elementAt(i);
1114            listener.getValue(event);
1115        }
1116        if (event.result == null) return code;
1117        char[] data = (event.result + "\0").toCharArray();
1118        int /*long*/ ptr = COM.SysAllocString(data);
1119        COM.MoveMemory(pszValue, new int /*long*/[] { ptr }, OS.PTR_SIZEOF);
1120        return COM.S_OK;
1121    }
1122    
1123    int put_accName(int /*long*/ variant, int /*long*/ szName) {
1124        // MSAA: this method is no longer supported
1125
if (iaccessible == null) return COM.CO_E_OBJNOTCONNECTED;
1126        // We don't implement this. Forward to the proxy.
1127
int code = iaccessible.put_accName(variant, szName);
1128        if (code == COM.E_INVALIDARG) code = COM.S_FALSE; // proxy doesn't know about app childID
1129
return code;
1130    }
1131    
1132    int put_accValue(int /*long*/ variant, int /*long*/ szValue) {
1133        // MSAA: this method is typically only used for edit controls
1134
if (iaccessible == null) return COM.CO_E_OBJNOTCONNECTED;
1135        // We don't implement this. Forward to the proxy.
1136
int code = iaccessible.put_accValue(variant, szValue);
1137        if (code == COM.E_INVALIDARG) code = COM.S_FALSE; // proxy doesn't know about app childID
1138
return code;
1139    }
1140
1141    /* IEnumVARIANT methods: Next, Skip, Reset, Clone */
1142    /* Retrieve the next celt items in the enumeration sequence.
1143     * If there are fewer than the requested number of elements left
1144     * in the sequence, retrieve the remaining elements.
1145     * The number of elements actually retrieved is returned in pceltFetched
1146     * (unless the caller passed in NULL for that parameter).
1147     */

1148     
1149     /* Next([in] celt, [out] rgvar, [in, out] pceltFetched)
1150     * Ownership of rgvar transfers from callee to caller so reference count on rgvar
1151     * must be incremented before returning. The caller is responsible for releasing rgvar.
1152     */

1153    int Next(int celt, int /*long*/ rgvar, int /*long*/ pceltFetched) {
1154        /* If there are no listeners, query the proxy for
1155         * its IEnumVariant, and get the Next items from it.
1156         */

1157        if (accessibleControlListeners.size() == 0) {
1158            int /*long*/[] ppvObject = new int /*long*/[1];
1159            int code = iaccessible.QueryInterface(COM.IIDIEnumVARIANT, ppvObject);
1160            if (code != COM.S_OK) return code;
1161            IEnumVARIANT ienumvariant = new IEnumVARIANT(ppvObject[0]);
1162            int[] celtFetched = new int[1];
1163            code = ienumvariant.Next(celt, rgvar, celtFetched);
1164            ienumvariant.Release();
1165            COM.MoveMemory(pceltFetched, celtFetched, 4);
1166            return code;
1167        }
1168
1169        if (rgvar == 0) return COM.E_INVALIDARG;
1170        if (pceltFetched == 0 && celt != 1) return COM.E_INVALIDARG;
1171        if (enumIndex == 0) {
1172            AccessibleControlEvent event = new AccessibleControlEvent(this);
1173            event.childID = ACC.CHILDID_SELF;
1174            for (int i = 0; i < accessibleControlListeners.size(); i++) {
1175                AccessibleControlListener listener = (AccessibleControlListener) accessibleControlListeners.elementAt(i);
1176                listener.getChildren(event);
1177            }
1178            variants = event.children;
1179        }
1180        Object JavaDoc[] nextItems = null;
1181        if (variants != null && celt >= 1) {
1182            int endIndex = enumIndex + celt - 1;
1183            if (endIndex > (variants.length - 1)) endIndex = variants.length - 1;
1184            if (enumIndex <= endIndex) {
1185                nextItems = new Object JavaDoc[endIndex - enumIndex + 1];
1186                for (int i = 0; i < nextItems.length; i++) {
1187                    Object JavaDoc child = variants[enumIndex];
1188                    if (child instanceof Integer JavaDoc) {
1189                        nextItems[i] = new Integer JavaDoc(childIDToOs(((Integer JavaDoc)child).intValue()));
1190                    } else {
1191                        nextItems[i] = child;
1192                    }
1193                    enumIndex++;
1194                }
1195            }
1196        }
1197        if (nextItems != null) {
1198            for (int i = 0; i < nextItems.length; i++) {
1199                Object JavaDoc nextItem = nextItems[i];
1200                if (nextItem instanceof Integer JavaDoc) {
1201                    int item = ((Integer JavaDoc) nextItem).intValue();
1202                    COM.MoveMemory(rgvar + i * 16, new short[] { COM.VT_I4 }, 2);
1203                    COM.MoveMemory(rgvar + i * 16 + 8, new int[] { item }, 4);
1204                } else {
1205                    Accessible accessible = (Accessible) nextItem;
1206                    accessible.AddRef();
1207                    COM.MoveMemory(rgvar + i * 16, new short[] { COM.VT_DISPATCH }, 2);
1208                    COM.MoveMemory(rgvar + i * 16 + 8, new int /*long*/[] { accessible.objIAccessible.getAddress() }, OS.PTR_SIZEOF);
1209                }
1210            }
1211            if (pceltFetched != 0)
1212                COM.MoveMemory(pceltFetched, new int[] {nextItems.length}, 4);
1213            if (nextItems.length == celt) return COM.S_OK;
1214        } else {
1215            if (pceltFetched != 0)
1216                COM.MoveMemory(pceltFetched, new int[] {0}, 4);
1217        }
1218        return COM.S_FALSE;
1219    }
1220    
1221    /* Skip over the specified number of elements in the enumeration sequence. */
1222    int Skip(int celt) {
1223        /* If there are no listeners, query the proxy
1224         * for its IEnumVariant, and tell it to Skip.
1225         */

1226        if (accessibleControlListeners.size() == 0) {
1227            int /*long*/[] ppvObject = new int /*long*/[1];
1228            int code = iaccessible.QueryInterface(COM.IIDIEnumVARIANT, ppvObject);
1229            if (code != COM.S_OK) return code;
1230            IEnumVARIANT ienumvariant = new IEnumVARIANT(ppvObject[0]);
1231            code = ienumvariant.Skip(celt);
1232            ienumvariant.Release();
1233            return code;
1234        }
1235
1236        if (celt < 1 ) return COM.E_INVALIDARG;
1237        enumIndex += celt;
1238        if (enumIndex > (variants.length - 1)) {
1239            enumIndex = variants.length - 1;
1240            return COM.S_FALSE;
1241        }
1242        return COM.S_OK;
1243    }
1244    
1245    /* Reset the enumeration sequence to the beginning. */
1246    int Reset() {
1247        /* If there are no listeners, query the proxy
1248         * for its IEnumVariant, and tell it to Reset.
1249         */

1250        if (accessibleControlListeners.size() == 0) {
1251            int /*long*/[] ppvObject = new int /*long*/[1];
1252            int code = (int)/*64*/iaccessible.QueryInterface(COM.IIDIEnumVARIANT, ppvObject);
1253            if (code != COM.S_OK) return code;
1254            IEnumVARIANT ienumvariant = new IEnumVARIANT(ppvObject[0]);
1255            code = ienumvariant.Reset();
1256            ienumvariant.Release();
1257            return code;
1258        }
1259        
1260        enumIndex = 0;
1261        return COM.S_OK;
1262    }
1263
1264     /* Clone([out] ppEnum)
1265     * Ownership of ppEnum transfers from callee to caller so reference count on ppEnum
1266     * must be incremented before returning. The caller is responsible for releasing ppEnum.
1267     */

1268    int Clone(int /*long*/ ppEnum) {
1269        /* If there are no listeners, query the proxy for
1270         * its IEnumVariant, and get the Clone from it.
1271         */

1272        if (accessibleControlListeners.size() == 0) {
1273            int /*long*/[] ppvObject = new int /*long*/[1];
1274            int code = iaccessible.QueryInterface(COM.IIDIEnumVARIANT, ppvObject);
1275            if (code != COM.S_OK) return code;
1276            IEnumVARIANT ienumvariant = new IEnumVARIANT(ppvObject[0]);
1277            int[] pEnum = new int[1];
1278            code = ienumvariant.Clone(pEnum);
1279            ienumvariant.Release();
1280            COM.MoveMemory(ppEnum, pEnum, 4);
1281            return code;
1282        }
1283
1284        if (ppEnum == 0) return COM.E_INVALIDARG;
1285        COM.MoveMemory(ppEnum, new int /*long*/[] { objIEnumVARIANT.getAddress()}, OS.PTR_SIZEOF);
1286        AddRef();
1287        return COM.S_OK;
1288    }
1289    
1290    int childIDToOs(int childID) {
1291        if (childID == ACC.CHILDID_SELF) return COM.CHILDID_SELF;
1292        /*
1293        * Feature of Windows:
1294        * In Windows XP, tree item ids are 1-based indices. Previous versions
1295        * of Windows use the tree item handle for the accessible child ID.
1296        * For backward compatibility, we still take a handle childID for tree
1297        * items on XP. All other childIDs are 1-based indices.
1298        */

1299        if (!(control instanceof Tree)) return childID + 1;
1300        if (OS.COMCTL32_MAJOR < 6) return childID;
1301        return (int)/*64*/OS.SendMessage (control.handle, OS.TVM_MAPHTREEITEMTOACCID, childID, 0);
1302    }
1303
1304    int osToChildID(int osChildID) {
1305        if (osChildID == COM.CHILDID_SELF) return ACC.CHILDID_SELF;
1306        /*
1307        * Feature of Windows:
1308        * In Windows XP, tree item ids are 1-based indices. Previous versions
1309        * of Windows use the tree item handle for the accessible child ID.
1310        * For backward compatibility, we still take a handle childID for tree
1311        * items on XP. All other childIDs are 1-based indices.
1312        */

1313        if (!(control instanceof Tree)) return osChildID - 1;
1314        if (OS.COMCTL32_MAJOR < 6) return osChildID;
1315        return (int)/*64*/OS.SendMessage (control.handle, OS.TVM_MAPACCIDTOHTREEITEM, osChildID, 0);
1316    }
1317    
1318    int stateToOs(int state) {
1319        int osState = 0;
1320        if ((state & ACC.STATE_SELECTED) != 0) osState |= COM.STATE_SYSTEM_SELECTED;
1321        if ((state & ACC.STATE_SELECTABLE) != 0) osState |= COM.STATE_SYSTEM_SELECTABLE;
1322        if ((state & ACC.STATE_MULTISELECTABLE) != 0) osState |= COM.STATE_SYSTEM_MULTISELECTABLE;
1323        if ((state & ACC.STATE_FOCUSED) != 0) osState |= COM.STATE_SYSTEM_FOCUSED;
1324        if ((state & ACC.STATE_FOCUSABLE) != 0) osState |= COM.STATE_SYSTEM_FOCUSABLE;
1325        if ((state & ACC.STATE_PRESSED) != 0) osState |= COM.STATE_SYSTEM_PRESSED;
1326        if ((state & ACC.STATE_CHECKED) != 0) osState |= COM.STATE_SYSTEM_CHECKED;
1327        if ((state & ACC.STATE_EXPANDED) != 0) osState |= COM.STATE_SYSTEM_EXPANDED;
1328        if ((state & ACC.STATE_COLLAPSED) != 0) osState |= COM.STATE_SYSTEM_COLLAPSED;
1329        if ((state & ACC.STATE_HOTTRACKED) != 0) osState |= COM.STATE_SYSTEM_HOTTRACKED;
1330        if ((state & ACC.STATE_BUSY) != 0) osState |= COM.STATE_SYSTEM_BUSY;
1331        if ((state & ACC.STATE_READONLY) != 0) osState |= COM.STATE_SYSTEM_READONLY;
1332        if ((state & ACC.STATE_INVISIBLE) != 0) osState |= COM.STATE_SYSTEM_INVISIBLE;
1333        if ((state & ACC.STATE_OFFSCREEN) != 0) osState |= COM.STATE_SYSTEM_OFFSCREEN;
1334        if ((state & ACC.STATE_SIZEABLE) != 0) osState |= COM.STATE_SYSTEM_SIZEABLE;
1335        if ((state & ACC.STATE_LINKED) != 0) osState |= COM.STATE_SYSTEM_LINKED;
1336        return osState;
1337    }
1338    
1339    int osToState(int osState) {
1340        int state = ACC.STATE_NORMAL;
1341        if ((osState & COM.STATE_SYSTEM_SELECTED) != 0) state |= ACC.STATE_SELECTED;
1342        if ((osState & COM.STATE_SYSTEM_SELECTABLE) != 0) state |= ACC.STATE_SELECTABLE;
1343        if ((osState & COM.STATE_SYSTEM_MULTISELECTABLE) != 0) state |= ACC.STATE_MULTISELECTABLE;
1344        if ((osState & COM.STATE_SYSTEM_FOCUSED) != 0) state |= ACC.STATE_FOCUSED;
1345        if ((osState & COM.STATE_SYSTEM_FOCUSABLE) != 0) state |= ACC.STATE_FOCUSABLE;
1346        if ((osState & COM.STATE_SYSTEM_PRESSED) != 0) state |= ACC.STATE_PRESSED;
1347        if ((osState & COM.STATE_SYSTEM_CHECKED) != 0) state |= ACC.STATE_CHECKED;
1348        if ((osState & COM.STATE_SYSTEM_EXPANDED) != 0) state |= ACC.STATE_EXPANDED;
1349        if ((osState & COM.STATE_SYSTEM_COLLAPSED) != 0) state |= ACC.STATE_COLLAPSED;
1350        if ((osState & COM.STATE_SYSTEM_HOTTRACKED) != 0) state |= ACC.STATE_HOTTRACKED;
1351        if ((osState & COM.STATE_SYSTEM_BUSY) != 0) state |= ACC.STATE_BUSY;
1352        if ((osState & COM.STATE_SYSTEM_READONLY) != 0) state |= ACC.STATE_READONLY;
1353        if ((osState & COM.STATE_SYSTEM_INVISIBLE) != 0) state |= ACC.STATE_INVISIBLE;
1354        if ((osState & COM.STATE_SYSTEM_OFFSCREEN) != 0) state |= ACC.STATE_OFFSCREEN;
1355        if ((osState & COM.STATE_SYSTEM_SIZEABLE) != 0) state |= ACC.STATE_SIZEABLE;
1356        if ((osState & COM.STATE_SYSTEM_LINKED) != 0) state |= ACC.STATE_LINKED;
1357        return state;
1358    }
1359
1360    int roleToOs(int role) {
1361        switch (role) {
1362            case ACC.ROLE_CLIENT_AREA: return COM.ROLE_SYSTEM_CLIENT;
1363            case ACC.ROLE_WINDOW: return COM.ROLE_SYSTEM_WINDOW;
1364            case ACC.ROLE_MENUBAR: return COM.ROLE_SYSTEM_MENUBAR;
1365            case ACC.ROLE_MENU: return COM.ROLE_SYSTEM_MENUPOPUP;
1366            case ACC.ROLE_MENUITEM: return COM.ROLE_SYSTEM_MENUITEM;
1367            case ACC.ROLE_SEPARATOR: return COM.ROLE_SYSTEM_SEPARATOR;
1368            case ACC.ROLE_TOOLTIP: return COM.ROLE_SYSTEM_TOOLTIP;
1369            case ACC.ROLE_SCROLLBAR: return COM.ROLE_SYSTEM_SCROLLBAR;
1370            case ACC.ROLE_DIALOG: return COM.ROLE_SYSTEM_DIALOG;
1371            case ACC.ROLE_LABEL: return COM.ROLE_SYSTEM_STATICTEXT;
1372            case ACC.ROLE_PUSHBUTTON: return COM.ROLE_SYSTEM_PUSHBUTTON;
1373            case ACC.ROLE_CHECKBUTTON: return COM.ROLE_SYSTEM_CHECKBUTTON;
1374            case ACC.ROLE_RADIOBUTTON: return COM.ROLE_SYSTEM_RADIOBUTTON;
1375            case ACC.ROLE_COMBOBOX: return COM.ROLE_SYSTEM_COMBOBOX;
1376            case ACC.ROLE_TEXT: return COM.ROLE_SYSTEM_TEXT;
1377            case ACC.ROLE_TOOLBAR: return COM.ROLE_SYSTEM_TOOLBAR;
1378            case ACC.ROLE_LIST: return COM.ROLE_SYSTEM_LIST;
1379            case ACC.ROLE_LISTITEM: return COM.ROLE_SYSTEM_LISTITEM;
1380            case ACC.ROLE_TABLE: return COM.ROLE_SYSTEM_TABLE;
1381            case ACC.ROLE_TABLECELL: return COM.ROLE_SYSTEM_CELL;
1382            case ACC.ROLE_TABLECOLUMNHEADER: return COM.ROLE_SYSTEM_COLUMNHEADER;
1383            case ACC.ROLE_TABLEROWHEADER: return COM.ROLE_SYSTEM_ROWHEADER;
1384            case ACC.ROLE_TREE: return COM.ROLE_SYSTEM_OUTLINE;
1385            case ACC.ROLE_TREEITEM: return COM.ROLE_SYSTEM_OUTLINEITEM;
1386            case ACC.ROLE_TABFOLDER: return COM.ROLE_SYSTEM_PAGETABLIST;
1387            case ACC.ROLE_TABITEM: return COM.ROLE_SYSTEM_PAGETAB;
1388            case ACC.ROLE_PROGRESSBAR: return COM.ROLE_SYSTEM_PROGRESSBAR;
1389            case ACC.ROLE_SLIDER: return COM.ROLE_SYSTEM_SLIDER;
1390            case ACC.ROLE_LINK: return COM.ROLE_SYSTEM_LINK;
1391        }
1392        return COM.ROLE_SYSTEM_CLIENT;
1393    }
1394
1395    int osToRole(int osRole) {
1396        switch (osRole) {
1397            case COM.ROLE_SYSTEM_CLIENT: return ACC.ROLE_CLIENT_AREA;
1398            case COM.ROLE_SYSTEM_WINDOW: return ACC.ROLE_WINDOW;
1399            case COM.ROLE_SYSTEM_MENUBAR: return ACC.ROLE_MENUBAR;
1400            case COM.ROLE_SYSTEM_MENUPOPUP: return ACC.ROLE_MENU;
1401            case COM.ROLE_SYSTEM_MENUITEM: return ACC.ROLE_MENUITEM;
1402            case COM.ROLE_SYSTEM_SEPARATOR: return ACC.ROLE_SEPARATOR;
1403            case COM.ROLE_SYSTEM_TOOLTIP: return ACC.ROLE_TOOLTIP;
1404            case COM.ROLE_SYSTEM_SCROLLBAR: return ACC.ROLE_SCROLLBAR;
1405            case COM.ROLE_SYSTEM_DIALOG: return ACC.ROLE_DIALOG;
1406            case COM.ROLE_SYSTEM_STATICTEXT: return ACC.ROLE_LABEL;
1407            case COM.ROLE_SYSTEM_PUSHBUTTON: return ACC.ROLE_PUSHBUTTON;
1408            case COM.ROLE_SYSTEM_CHECKBUTTON: return ACC.ROLE_CHECKBUTTON;
1409            case COM.ROLE_SYSTEM_RADIOBUTTON: return ACC.ROLE_RADIOBUTTON;
1410            case COM.ROLE_SYSTEM_COMBOBOX: return ACC.ROLE_COMBOBOX;
1411            case COM.ROLE_SYSTEM_TEXT: return ACC.ROLE_TEXT;
1412            case COM.ROLE_SYSTEM_TOOLBAR: return ACC.ROLE_TOOLBAR;
1413            case COM.ROLE_SYSTEM_LIST: return ACC.ROLE_LIST;
1414            case COM.ROLE_SYSTEM_LISTITEM: return ACC.ROLE_LISTITEM;
1415            case COM.ROLE_SYSTEM_TABLE: return ACC.ROLE_TABLE;
1416            case COM.ROLE_SYSTEM_CELL: return ACC.ROLE_TABLECELL;
1417            case COM.ROLE_SYSTEM_COLUMNHEADER: return ACC.ROLE_TABLECOLUMNHEADER;
1418            case COM.ROLE_SYSTEM_ROWHEADER: return ACC.ROLE_TABLEROWHEADER;
1419            case COM.ROLE_SYSTEM_OUTLINE: return ACC.ROLE_TREE;
1420            case COM.ROLE_SYSTEM_OUTLINEITEM: return ACC.ROLE_TREEITEM;
1421            case COM.ROLE_SYSTEM_PAGETABLIST: return ACC.ROLE_TABFOLDER;
1422            case COM.ROLE_SYSTEM_PAGETAB: return ACC.ROLE_TABITEM;
1423            case COM.ROLE_SYSTEM_PROGRESSBAR: return ACC.ROLE_PROGRESSBAR;
1424            case COM.ROLE_SYSTEM_SLIDER: return ACC.ROLE_SLIDER;
1425            case COM.ROLE_SYSTEM_LINK: return ACC.ROLE_LINK;
1426        }
1427        return ACC.ROLE_CLIENT_AREA;
1428    }
1429
1430    /* checkWidget was copied from Widget, and rewritten to work in this package */
1431    void checkWidget () {
1432        if (!isValidThread ()) SWT.error (SWT.ERROR_THREAD_INVALID_ACCESS);
1433        if (control.isDisposed ()) SWT.error (SWT.ERROR_WIDGET_DISPOSED);
1434    }
1435
1436    /* isValidThread was copied from Widget, and rewritten to work in this package */
1437    boolean isValidThread () {
1438        return control.getDisplay ().getThread () == Thread.currentThread ();
1439    }
1440}
1441
Popular Tags