KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*******************************************************************************
2  * Copyright (c) 2000, 2005 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.*;
15 import org.eclipse.swt.internal.*;
16 import org.eclipse.swt.internal.accessibility.gtk.*;
17 import org.eclipse.swt.internal.gtk.*;
18 import org.eclipse.swt.widgets.*;
19
20 class AccessibleObject {
21     int /*long*/ handle;
22     int /*long*/ parentType;
23     int index = -1, id = ACC.CHILDID_SELF;
24     Accessible accessible;
25     AccessibleObject parent;
26     Hashtable children = new Hashtable (9);
27     /*
28     * a lightweight object does not correspond to a concrete gtk widget, but
29     * to a logical child of a widget (eg.- a CTabItem, which is simply drawn)
30     */

31     boolean isLightweight = false;
32
33     static int /*long*/ actionNamePtr = -1;
34     static int /*long*/ descriptionPtr = -1;
35     static int /*long*/ keybindingPtr = -1;
36     static int /*long*/ namePtr = -1;
37     static final Hashtable AccessibleObjects = new Hashtable (9);
38     static final int /*long*/ ATK_ACTION_TYPE = ATK.g_type_from_name (Converter.wcsToMbcs (null, "AtkAction", true));
39     static final int /*long*/ ATK_COMPONENT_TYPE = ATK.g_type_from_name (Converter.wcsToMbcs (null, "AtkComponent", true));
40     static final int /*long*/ ATK_HYPERTEXT_TYPE = ATK.g_type_from_name (Converter.wcsToMbcs (null, "AtkHypertext", true));
41     static final int /*long*/ ATK_SELECTION_TYPE = ATK.g_type_from_name (Converter.wcsToMbcs (null, "AtkSelection", true));
42     static final int /*long*/ ATK_TEXT_TYPE = ATK.g_type_from_name (Converter.wcsToMbcs (null, "AtkText", true));
43     static final boolean DEBUG = Display.DEBUG;
44
45     AccessibleObject (int /*long*/ type, int /*long*/ widget, Accessible accessible, int /*long*/ parentType, boolean isLightweight) {
46         super ();
47         handle = ATK.g_object_new (type, 0);
48         this.parentType = parentType;
49         ATK.atk_object_initialize (handle, widget);
50         this.accessible = accessible;
51         this.isLightweight = isLightweight;
52         AccessibleObjects.put (new LONG (handle), this);
53         if (DEBUG) System.out.println("new AccessibleObject: " + handle);
54     }
55
56     void addChild (AccessibleObject child) {
57         children.put (new LONG (child.handle), child);
58         child.setParent (this);
59     }
60     
61     static int /*long*/ atkAction_get_keybinding (int /*long*/ atkObject, int /*long*/ index) {
62         if (DEBUG) System.out.println ("-->atkAction_get_keybinding");
63         AccessibleObject object = getAccessibleObject (atkObject);
64         if (object == null) return 0;
65         int /*long*/ parentResult = 0;
66         if (ATK.g_type_is_a (object.parentType, ATK_ACTION_TYPE)) {
67             int /*long*/ superType = ATK.g_type_interface_peek_parent (ATK.ATK_ACTION_GET_IFACE (object.handle));
68             AtkActionIface actionIface = new AtkActionIface ();
69             ATK.memmove (actionIface, superType);
70             if (actionIface.get_keybinding != 0) {
71                 parentResult = ATK.call (actionIface.get_keybinding, object.handle, index);
72             }
73         }
74         AccessibleListener[] listeners = object.getAccessibleListeners ();
75         if (listeners.length == 0) return parentResult;
76
77         AccessibleEvent event = new AccessibleEvent (object);
78         event.childID = object.id;
79         if (parentResult != 0) {
80             int length = OS.strlen (parentResult);
81             byte [] buffer = new byte [length];
82             OS.memmove (buffer, parentResult, length);
83             event.result = new String JavaDoc (Converter.mbcsToWcs (null, buffer));
84         }
85         for (int i = 0; i < listeners.length; i++) {
86             listeners [i].getKeyboardShortcut (event);
87         }
88         if (event.result == null) return parentResult;
89         if (keybindingPtr != -1) OS.g_free (keybindingPtr);
90         byte[] name = Converter.wcsToMbcs (null, event.result, true);
91         keybindingPtr = OS.g_malloc (name.length);
92         OS.memmove (keybindingPtr, name, name.length);
93         return keybindingPtr;
94     }
95
96     static int /*long*/ atkAction_get_name (int /*long*/ atkObject, int /*long*/ index) {
97         if (DEBUG) System.out.println ("-->atkAction_get_name");
98         AccessibleObject object = getAccessibleObject (atkObject);
99         if (object == null) return 0;
100         int /*long*/ parentResult = 0;
101         if (ATK.g_type_is_a (object.parentType, ATK_ACTION_TYPE)) {
102             int /*long*/ superType = ATK.g_type_interface_peek_parent (ATK.ATK_ACTION_GET_IFACE (object.handle));
103             AtkActionIface actionIface = new AtkActionIface ();
104             ATK.memmove (actionIface, superType);
105             if (actionIface.get_name != 0) {
106                 parentResult = ATK.call (actionIface.get_name, object.handle, index);
107             }
108         }
109         AccessibleControlListener[] listeners = object.getControlListeners ();
110         if (listeners.length == 0) return parentResult;
111
112         AccessibleControlEvent event = new AccessibleControlEvent (object);
113         event.childID = object.id;
114         if (parentResult != 0) {
115             int length = OS.strlen (parentResult);
116             byte [] buffer = new byte [length];
117             OS.memmove (buffer, parentResult, length);
118             event.result = new String JavaDoc (Converter.mbcsToWcs (null, buffer));
119         }
120         for (int i = 0; i < listeners.length; i++) {
121             listeners [i].getDefaultAction (event);
122         }
123         if (event.result == null) return parentResult;
124         if (actionNamePtr != -1) OS.g_free (actionNamePtr);
125         byte[] name = Converter.wcsToMbcs (null, event.result, true);
126         actionNamePtr = OS.g_malloc (name.length);
127         OS.memmove (actionNamePtr, name, name.length);
128         return actionNamePtr;
129     }
130
131     static int /*long*/ atkComponent_get_extents (int /*long*/ atkObject, int /*long*/ x, int /*long*/ y, int /*long*/ width, int /*long*/ height, int /*long*/ coord_type) {
132         if (DEBUG) System.out.println ("-->atkComponent_get_extents");
133         AccessibleObject object = getAccessibleObject (atkObject);
134         if (object == null) return 0;
135         OS.memmove (x, new int[] {0}, 4);
136         OS.memmove (y, new int[] {0}, 4);
137         OS.memmove (width, new int[] {0}, 4);
138         OS.memmove (height, new int[] {0}, 4);
139         if (ATK.g_type_is_a (object.parentType, ATK_COMPONENT_TYPE)) {
140             int /*long*/ superType = ATK.g_type_interface_peek_parent (ATK.ATK_COMPONENT_GET_IFACE (object.handle));
141             AtkComponentIface componentIface = new AtkComponentIface ();
142             ATK.memmove (componentIface, superType);
143             if (componentIface.get_extents != 0) {
144                 ATK.call (componentIface.get_extents, object.handle, x, y, width, height, coord_type);
145             }
146         }
147         AccessibleControlListener[] listeners = object.getControlListeners ();
148         if (listeners.length == 0) return 0;
149         
150         int[] parentX = new int [1], parentY = new int [1];
151         int[] parentWidth = new int [1], parentHeight = new int [1];
152         OS.memmove (parentX, x, 4);
153         OS.memmove (parentY, y, 4);
154         OS.memmove (parentWidth, width, 4);
155         OS.memmove (parentHeight, height, 4);
156         AccessibleControlEvent event = new AccessibleControlEvent (object);
157         event.childID = object.id;
158         event.x = parentX [0]; event.y = parentY [0];
159         event.width = parentWidth [0]; event.height = parentHeight [0];
160         if (coord_type == ATK.ATK_XY_WINDOW) {
161             /* translate control -> display, for filling in event to be dispatched */
162             int /*long*/ gtkAccessibleHandle = ATK.GTK_ACCESSIBLE (object.handle);
163             GtkAccessible gtkAccessible = new GtkAccessible ();
164             ATK.memmove (gtkAccessible, gtkAccessibleHandle);
165             int /*long*/ topLevel = ATK.gtk_widget_get_toplevel (gtkAccessible.widget);
166             int /*long*/ window = OS.GTK_WIDGET_WINDOW (topLevel);
167             int[] topWindowX = new int [1], topWindowY = new int [1];
168             OS.gdk_window_get_origin (window, topWindowX, topWindowY);
169             event.x += topWindowX [0];
170             event.y += topWindowY [0];
171         }
172         for (int i = 0; i < listeners.length; i++) {
173             listeners [i].getLocation (event);
174         }
175         if (coord_type == ATK.ATK_XY_WINDOW) {
176             /* translate display -> control, for answering to the OS */
177             int /*long*/ gtkAccessibleHandle = ATK.GTK_ACCESSIBLE (object.handle);
178             GtkAccessible gtkAccessible = new GtkAccessible ();
179             ATK.memmove (gtkAccessible, gtkAccessibleHandle);
180             int /*long*/ topLevel = ATK.gtk_widget_get_toplevel (gtkAccessible.widget);
181             int /*long*/ window = OS.GTK_WIDGET_WINDOW (topLevel);
182             int[] topWindowX = new int [1], topWindowY = new int [1];
183             OS.gdk_window_get_origin (window, topWindowX, topWindowY);
184             event.x -= topWindowX [0];
185             event.y -= topWindowY [0];
186         }
187         OS.memmove (x, new int[] {event.x}, 4);
188         OS.memmove (y, new int[] {event.y}, 4);
189         OS.memmove (width, new int[] {event.width}, 4);
190         OS.memmove (height, new int[] {event.height}, 4);
191         return 0;
192     }
193
194     static int /*long*/ atkComponent_get_position (int /*long*/ atkObject, int /*long*/ x, int /*long*/ y, int /*long*/ coord_type) {
195         if (DEBUG) System.out.println ("-->atkComponent_get_position, object: " + atkObject + " x: " + x + " y: " + y + " coord: " + coord_type);
196         AccessibleObject object = getAccessibleObject (atkObject);
197         if (object == null) return 0;
198         OS.memmove (x, new int[] {0}, 4);
199         OS.memmove (y, new int[] {0}, 4);
200         if (ATK.g_type_is_a (object.parentType, ATK_COMPONENT_TYPE)) {
201             int /*long*/ superType = ATK.g_type_interface_peek_parent (ATK.ATK_COMPONENT_GET_IFACE (object.handle));
202             AtkComponentIface componentIface = new AtkComponentIface ();
203             ATK.memmove (componentIface, superType);
204             if (componentIface.get_extents != 0) {
205                 ATK.call (componentIface.get_position, object.handle, x, y, coord_type);
206             }
207         }
208         AccessibleControlListener[] listeners = object.getControlListeners ();
209         if (listeners.length == 0) return 0;
210         
211         int[] parentX = new int [1], parentY = new int [1];
212         OS.memmove (parentX, x, 4);
213         OS.memmove (parentY, y, 4);
214         AccessibleControlEvent event = new AccessibleControlEvent (object);
215         event.childID = object.id;
216         event.x = parentX [0]; event.y = parentY [0];
217         if (coord_type == ATK.ATK_XY_WINDOW) {
218             /* translate control -> display, for filling in event to be dispatched */
219             int /*long*/ gtkAccessibleHandle = ATK.GTK_ACCESSIBLE (object.handle);
220             GtkAccessible gtkAccessible = new GtkAccessible ();
221             ATK.memmove (gtkAccessible, gtkAccessibleHandle);
222             int /*long*/ topLevel = ATK.gtk_widget_get_toplevel (gtkAccessible.widget);
223             int /*long*/ window = OS.GTK_WIDGET_WINDOW (topLevel);
224             int[] topWindowX = new int [1], topWindowY = new int [1];
225             OS.gdk_window_get_origin (window, topWindowX, topWindowY);
226             event.x += topWindowX [0];
227             event.y += topWindowY [0];
228         }
229         for (int i = 0; i < listeners.length; i++) {
230             listeners [i].getLocation (event);
231         }
232         if (coord_type == ATK.ATK_XY_WINDOW) {
233             /* translate display -> control, for answering to the OS */
234             int /*long*/ gtkAccessibleHandle = ATK.GTK_ACCESSIBLE (object.handle);
235             GtkAccessible gtkAccessible = new GtkAccessible ();
236             ATK.memmove (gtkAccessible, gtkAccessibleHandle);
237             int /*long*/ topLevel = ATK.gtk_widget_get_toplevel (gtkAccessible.widget);
238             int /*long*/ window = OS.GTK_WIDGET_WINDOW (topLevel);
239             int[] topWindowX = new int [1], topWindowY = new int [1];
240             OS.gdk_window_get_origin (window, topWindowX, topWindowY);
241             event.x -= topWindowX [0];
242             event.y -= topWindowY [0];
243         }
244         OS.memmove (x, new int[] {event.x}, 4);
245         OS.memmove (y, new int[] {event.y}, 4);
246         return 0;
247     }
248
249     static int /*long*/ atkComponent_get_size (int /*long*/ atkObject, int /*long*/ width, int /*long*/ height, int /*long*/ coord_type) {
250         if (DEBUG) System.out.println ("-->atkComponent_get_size");
251         AccessibleObject object = getAccessibleObject (atkObject);
252         if (object == null) return 0;
253         OS.memmove (width, new int[] {0}, 4);
254         OS.memmove (height, new int[] {0}, 4);
255         if (ATK.g_type_is_a (object.parentType, ATK_COMPONENT_TYPE)) {
256             int /*long*/ superType = ATK.g_type_interface_peek_parent (ATK.ATK_COMPONENT_GET_IFACE (object.handle));
257             AtkComponentIface componentIface = new AtkComponentIface ();
258             ATK.memmove (componentIface, superType);
259             if (componentIface.get_extents != 0) {
260                 ATK.call (componentIface.get_size, object.handle, width, height, coord_type);
261             }
262         }
263         AccessibleControlListener[] listeners = object.getControlListeners ();
264         if (listeners.length == 0) return 0;
265         
266         int[] parentWidth = new int [1], parentHeight = new int [1];
267         OS.memmove (parentWidth, width, 4);
268         OS.memmove (parentHeight, height, 4);
269         AccessibleControlEvent event = new AccessibleControlEvent (object);
270         event.childID = object.id;
271         event.width = parentWidth [0]; event.height = parentHeight [0];
272         for (int i = 0; i < listeners.length; i++) {
273             listeners [i].getLocation (event);
274         }
275         OS.memmove (width, new int[] {event.width}, 4);
276         OS.memmove (height, new int[] {event.height}, 4);
277         return 0;
278     }
279
280     static int /*long*/ atkComponent_ref_accessible_at_point (int /*long*/ atkObject, int /*long*/ x, int /*long*/ y, int /*long*/ coord_type) {
281         if (DEBUG) System.out.println ("-->atkComponent_ref_accessible_at_point");
282         AccessibleObject object = getAccessibleObject (atkObject);
283         if (object == null) return 0;
284         int /*long*/ parentResult = 0;
285         if (ATK.g_type_is_a (object.parentType, ATK_COMPONENT_TYPE)) {
286             int /*long*/ superType = ATK.g_type_interface_peek_parent (ATK.ATK_COMPONENT_GET_IFACE (object.handle));
287             AtkComponentIface componentIface = new AtkComponentIface ();
288             ATK.memmove (componentIface, superType);
289             if (componentIface.ref_accessible_at_point != 0) {
290                 parentResult = ATK.call (componentIface.ref_accessible_at_point, object.handle, x, y, coord_type);
291             }
292         }
293         AccessibleControlListener[] listeners = object.getControlListeners ();
294         if (listeners.length == 0) return parentResult;
295         
296         AccessibleControlEvent event = new AccessibleControlEvent (object);
297         event.childID = object.id;
298         event.x = (int)/*64*/x; event.y = (int)/*64*/y;
299         if (coord_type == ATK.ATK_XY_WINDOW) {
300             /* translate control -> display, for filling in the event to be dispatched */
301             int /*long*/ gtkAccessibleHandle = ATK.GTK_ACCESSIBLE (object.handle);
302             GtkAccessible gtkAccessible = new GtkAccessible ();
303             ATK.memmove (gtkAccessible, gtkAccessibleHandle);
304             int /*long*/ topLevel = ATK.gtk_widget_get_toplevel (gtkAccessible.widget);
305             int /*long*/ window = OS.GTK_WIDGET_WINDOW (topLevel);
306             int[] topWindowX = new int [1], topWindowY = new int [1];
307             OS.gdk_window_get_origin (window, topWindowX, topWindowY);
308             event.x += topWindowX [0];
309             event.y += topWindowY [0];
310         }
311         for (int i = 0; i < listeners.length; i++) {
312             listeners [i].getChildAtPoint (event);
313         }
314         if (event.childID == object.id) event.childID = ACC.CHILDID_SELF;
315         AccessibleObject accObj = object.getChildByID (event.childID);
316         if (accObj != null) {
317             if (parentResult > 0) OS.g_object_unref (parentResult);
318             OS.g_object_ref (accObj.handle);
319             return accObj.handle;
320         }
321         return parentResult;
322     }
323
324     static int /*long*/ atkHypertext_get_link (int /*long*/ atkObject, int /*long*/ link_index) {
325         if (DEBUG) System.out.println ("-->atkHypertext_get_link");
326         return 0;
327     }
328
329     static int /*long*/ atkHypertext_get_n_links (int /*long*/ atkObject) {
330         if (DEBUG) System.out.println ("-->atkHypertext_get_n_links");
331         return 0; /* read hyperlink's name */
332     }
333
334     static int /*long*/ atkHypertext_get_link_index (int /*long*/ atkObject, int /*long*/ char_index) {
335         if (DEBUG) System.out.println ("-->atkHypertext_get_link_index");
336         return 0;
337     }
338
339     static int /*long*/ atkObject_get_description (int /*long*/ atkObject) {
340         if (DEBUG) System.out.println ("-->atkObject_get_description");
341         AccessibleObject object = getAccessibleObject (atkObject);
342         if (object == null) return 0;
343         int /*long*/ parentResult = 0;
344         int /*long*/ superType = ATK.g_type_class_peek (object.parentType);
345         AtkObjectClass objectClass = new AtkObjectClass ();
346         ATK.memmove (objectClass, superType);
347         if (objectClass.get_description != 0) {
348             parentResult = ATK.call (objectClass.get_description, object.handle);
349         }
350         AccessibleListener[] listeners = object.getAccessibleListeners ();
351         if (listeners.length == 0) return parentResult;
352             
353         AccessibleEvent event = new AccessibleEvent (object);
354         event.childID = object.id;
355         if (parentResult != 0) {
356             int length = OS.strlen (parentResult);
357             byte [] buffer = new byte [length];
358             OS.memmove (buffer, parentResult, length);
359             event.result = new String JavaDoc (Converter.mbcsToWcs (null, buffer));
360         }
361         for (int i = 0; i < listeners.length; i++) {
362             listeners [i].getDescription (event);
363         }
364         if (event.result == null) return parentResult;
365         if (descriptionPtr != -1) OS.g_free (descriptionPtr);
366         byte[] name = Converter.wcsToMbcs (null, event.result, true);
367         descriptionPtr = OS.g_malloc (name.length);
368         OS.memmove (descriptionPtr, name, name.length);
369         return descriptionPtr;
370     }
371
372     static int /*long*/ atkObject_get_name (int /*long*/ atkObject) {
373         if (DEBUG) System.out.println ("-->atkObject_get_name: " + atkObject);
374         AccessibleObject object = getAccessibleObject (atkObject);
375         if (object == null) return 0;
376         int /*long*/ parentResult = 0;
377         int /*long*/ superType = ATK.g_type_class_peek (object.parentType);
378         AtkObjectClass objectClass = new AtkObjectClass ();
379         ATK.memmove (objectClass, superType);
380         if (objectClass.get_name != 0) {
381             parentResult = ATK.call (objectClass.get_name, object.handle);
382         }
383         AccessibleListener[] listeners = object.getAccessibleListeners ();
384         if (listeners.length == 0) return parentResult;
385         
386         AccessibleEvent event = new AccessibleEvent (object);
387         event.childID = object.id;
388         if (parentResult != 0) {
389             int length = OS.strlen (parentResult);
390             byte [] buffer = new byte [length];
391             OS.memmove (buffer, parentResult, length);
392             event.result = new String JavaDoc (Converter.mbcsToWcs (null, buffer));
393         }
394         for (int i = 0; i < listeners.length; i++) {
395             listeners [i].getName (event);
396         }
397         if (event.result == null) return parentResult;
398         if (namePtr != -1) OS.g_free (namePtr);
399         byte[] name = Converter.wcsToMbcs (null, event.result, true);
400         namePtr = OS.g_malloc (name.length);
401         OS.memmove (namePtr, name, name.length);
402         return namePtr;
403     }
404
405     static int /*long*/ atkObject_get_n_children (int /*long*/ atkObject) {
406         if (DEBUG) System.out.println ("-->atkObject_get_n_children: " + atkObject);
407         AccessibleObject object = getAccessibleObject (atkObject);
408         if (object == null) return 0;
409         int /*long*/ parentResult = 0;
410         int /*long*/ superType = ATK.g_type_class_peek (object.parentType);
411         AtkObjectClass objectClass = new AtkObjectClass ();
412         ATK.memmove (objectClass, superType);
413         if (objectClass.get_n_children != 0) {
414             parentResult = ATK.call (objectClass.get_n_children, object.handle);
415         }
416         AccessibleControlListener[] listeners = object.getControlListeners ();
417         if (listeners.length == 0) return parentResult;
418             
419         AccessibleControlEvent event = new AccessibleControlEvent (object);
420         event.childID = object.id;
421         event.detail = (int)/*64*/parentResult;
422         for (int i = 0; i < listeners.length; i++) {
423             listeners [i].getChildCount (event);
424         }
425         return event.detail;
426     }
427
428     static int /*long*/ atkObject_get_index_in_parent (int /*long*/ atkObject) {
429         if (DEBUG) System.out.println ("-->atkObjectCB_get_index_in_parent. ");
430         AccessibleObject object = getAccessibleObject (atkObject);
431         if (object == null) return 0;
432         if (object.index != -1) return object.index;
433         int /*long*/ superType = ATK.g_type_class_peek (object.parentType);
434         AtkObjectClass objectClass = new AtkObjectClass ();
435         ATK.memmove (objectClass, superType);
436         if (objectClass.get_index_in_parent == 0) return 0;
437         return ATK.call (objectClass.get_index_in_parent,object. handle);
438     }
439
440     static int /*long*/ atkObject_get_parent (int /*long*/ atkObject) {
441         if (DEBUG) System.out.println ("-->atkObject_get_parent: " + atkObject);
442         AccessibleObject object = getAccessibleObject (atkObject);
443         if (object == null) return 0;
444         if (object.parent != null) return object.parent.handle;
445         int /*long*/ superType = ATK.g_type_class_peek (object.parentType);
446         AtkObjectClass objectClass = new AtkObjectClass ();
447         ATK.memmove (objectClass, superType);
448         if (objectClass.get_parent == 0) return 0;
449         return ATK.call (objectClass.get_parent, object.handle);
450     }
451
452     static int /*long*/ atkObject_get_role (int /*long*/ atkObject) {
453         if (DEBUG) System.out.println ("-->atkObject_get_role: " + atkObject);
454         AccessibleObject object = getAccessibleObject (atkObject);
455         if (object == null) return 0;
456         if (object.getAccessibleListeners ().length != 0) {
457             AccessibleControlListener[] listeners = object.getControlListeners ();
458             AccessibleControlEvent event = new AccessibleControlEvent (object);
459             event.childID = object.id;
460             event.detail = -1;
461             for (int i = 0; i < listeners.length; i++) {
462                 listeners [i].getRole (event);
463             }
464             if (event.detail != -1) {
465                 switch (event.detail) {
466                     /* Convert from win32 role values to atk role values */
467                     case ACC.ROLE_CHECKBUTTON: return ATK.ATK_ROLE_CHECK_BOX;
468                     case ACC.ROLE_CLIENT_AREA: return ATK.ATK_ROLE_DRAWING_AREA;
469                     case ACC.ROLE_COMBOBOX: return ATK.ATK_ROLE_COMBO_BOX;
470                     case ACC.ROLE_DIALOG: return ATK.ATK_ROLE_DIALOG;
471                     case ACC.ROLE_LABEL: return ATK.ATK_ROLE_LABEL;
472                     case ACC.ROLE_LINK: return ATK.ATK_ROLE_TEXT;
473                     case ACC.ROLE_LIST: return ATK.ATK_ROLE_LIST;
474                     case ACC.ROLE_LISTITEM: return ATK.ATK_ROLE_LIST_ITEM;
475                     case ACC.ROLE_MENU: return ATK.ATK_ROLE_MENU;
476                     case ACC.ROLE_MENUBAR: return ATK.ATK_ROLE_MENU_BAR;
477                     case ACC.ROLE_MENUITEM: return ATK.ATK_ROLE_MENU_ITEM;
478                     case ACC.ROLE_PROGRESSBAR: return ATK.ATK_ROLE_PROGRESS_BAR;
479                     case ACC.ROLE_PUSHBUTTON: return ATK.ATK_ROLE_PUSH_BUTTON;
480                     case ACC.ROLE_SCROLLBAR: return ATK.ATK_ROLE_SCROLL_BAR;
481                     case ACC.ROLE_SEPARATOR: return ATK.ATK_ROLE_SEPARATOR;
482                     case ACC.ROLE_SLIDER: return ATK.ATK_ROLE_SLIDER;
483                     case ACC.ROLE_TABLE: return ATK.ATK_ROLE_TABLE;
484                     case ACC.ROLE_TABLECELL: return ATK.ATK_ROLE_TABLE_CELL;
485                     case ACC.ROLE_TABLECOLUMNHEADER: return ATK.ATK_ROLE_TABLE_COLUMN_HEADER;
486                     case ACC.ROLE_TABLEROWHEADER: return ATK.ATK_ROLE_TABLE_ROW_HEADER;
487                     case ACC.ROLE_TABFOLDER: return ATK.ATK_ROLE_PAGE_TAB_LIST;
488                     case ACC.ROLE_TABITEM: return ATK.ATK_ROLE_PAGE_TAB;
489                     case ACC.ROLE_TEXT: return ATK.ATK_ROLE_TEXT;
490                     case ACC.ROLE_TOOLBAR: return ATK.ATK_ROLE_TOOL_BAR;
491                     case ACC.ROLE_TOOLTIP: return ATK.ATK_ROLE_TOOL_TIP;
492                     case ACC.ROLE_TREE: return ATK.ATK_ROLE_TREE;
493                     case ACC.ROLE_TREEITEM: return ATK.ATK_ROLE_LIST_ITEM;
494                     case ACC.ROLE_RADIOBUTTON: return ATK.ATK_ROLE_RADIO_BUTTON;
495                     case ACC.ROLE_WINDOW: return ATK.ATK_ROLE_WINDOW;
496                 }
497             }
498         }
499         int /*long*/ superType = ATK.g_type_class_peek (object.parentType);
500         AtkObjectClass objectClass = new AtkObjectClass ();
501         ATK.memmove (objectClass, superType);
502         if (objectClass.get_role == 0) return 0;
503         return ATK.call (objectClass.get_role, object.handle);
504     }
505
506     static int /*long*/ atkObject_ref_child (int /*long*/ atkObject, int /*long*/ index) {
507         if (DEBUG) System.out.println ("-->atkObject_ref_child: " + index + " of: " + atkObject);
508         AccessibleObject object = getAccessibleObject (atkObject);
509         if (object == null) return 0;
510         object.updateChildren ();
511         AccessibleObject accObject = object.getChildByIndex ((int)/*64*/index);
512         if (accObject != null) {
513             OS.g_object_ref (accObject.handle);
514             return accObject.handle;
515         }
516         int /*long*/ superType = ATK.g_type_class_peek (object.parentType);
517         AtkObjectClass objectClass = new AtkObjectClass ();
518         ATK.memmove (objectClass, superType);
519         if (objectClass.ref_child == 0) return 0;
520         return ATK.call (objectClass.ref_child, object.handle, index);
521     }
522
523     static int /*long*/ atkObject_ref_state_set (int /*long*/ atkObject) {
524         if (DEBUG) System.out.println ("-->atkObject_ref_state_set");
525         AccessibleObject object = getAccessibleObject (atkObject);
526         if (object == null) return 0;
527         int /*long*/ parentResult = 0;
528         int /*long*/ superType = ATK.g_type_class_peek (object.parentType);
529         AtkObjectClass objectClass = new AtkObjectClass ();
530         ATK.memmove (objectClass, superType);
531         if (objectClass.ref_state_set != 0) {
532             parentResult = ATK.call (objectClass.ref_state_set, object.handle);
533         }
534         AccessibleControlListener[] listeners = object.getControlListeners ();
535         if (listeners.length == 0) return parentResult;
536
537         int /*long*/ set = parentResult;
538         AccessibleControlEvent event = new AccessibleControlEvent (object);
539         event.childID = object.id;
540         event.detail = -1;
541         for (int i = 0; i < listeners.length; i++) {
542             listeners [i].getState (event);
543         }
544         if (event.detail != -1) {
545             /* Convert from win32 state values to atk state values */
546             int state = event.detail;
547             if ((state & ACC.STATE_BUSY) != 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_BUSY);
548             if ((state & ACC.STATE_CHECKED) != 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_CHECKED);
549             if ((state & ACC.STATE_EXPANDED) != 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_EXPANDED);
550             if ((state & ACC.STATE_FOCUSABLE) != 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_FOCUSABLE);
551             if ((state & ACC.STATE_FOCUSED) != 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_FOCUSED);
552             if ((state & ACC.STATE_HOTTRACKED) != 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_ARMED);
553             if ((state & ACC.STATE_INVISIBLE) == 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_VISIBLE);
554             if ((state & ACC.STATE_MULTISELECTABLE) != 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_MULTISELECTABLE);
555             if ((state & ACC.STATE_OFFSCREEN) == 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_SHOWING);
556             if ((state & ACC.STATE_PRESSED) != 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_PRESSED);
557             if ((state & ACC.STATE_READONLY) == 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_EDITABLE);
558             if ((state & ACC.STATE_SELECTABLE) != 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_SELECTABLE);
559             if ((state & ACC.STATE_SELECTED) != 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_SELECTED);
560             if ((state & ACC.STATE_SIZEABLE) != 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_RESIZABLE);
561             /* Note: STATE_COLLAPSED, STATE_LINKED and STATE_NORMAL have no ATK equivalents */
562         }
563         return set;
564     }
565
566     static int /*long*/ atkSelection_is_child_selected (int /*long*/ atkObject, int /*long*/ index) {
567         if (DEBUG) System.out.println ("-->atkSelection_is_child_selected");
568         AccessibleObject object = getAccessibleObject (atkObject);
569         if (object == null) return 0;
570         int /*long*/ parentResult = 0;
571         if (ATK.g_type_is_a (object.parentType, ATK_SELECTION_TYPE)) {
572             int /*long*/ superType = ATK.g_type_interface_peek_parent (ATK.ATK_SELECTION_GET_IFACE (object.handle));
573             AtkSelectionIface selectionIface = new AtkSelectionIface ();
574             ATK.memmove (selectionIface, superType);
575             if (selectionIface.is_child_selected != 0) {
576                 parentResult = ATK.call (selectionIface.is_child_selected, object.handle, index);
577             }
578         }
579         AccessibleControlListener[] listeners = object.getControlListeners ();
580         if (listeners.length == 0) return parentResult;
581             
582         AccessibleControlEvent event = new AccessibleControlEvent (object);
583         event.childID = object.id;
584         for (int i = 0; i < listeners.length; i++) {
585             listeners [i].getSelection (event);
586         }
587         AccessibleObject accessibleObject = object.getChildByID (event.childID);
588         if (accessibleObject != null) {
589             return accessibleObject.index == index ? 1 : 0;
590         }
591         return parentResult;
592     }
593
594     static int /*long*/ atkSelection_ref_selection (int /*long*/ atkObject, int /*long*/ index) {
595         if (DEBUG) System.out.println ("-->atkSelection_ref_selection");
596         AccessibleObject object = getAccessibleObject (atkObject);
597         if (object == null) return 0;
598         int /*long*/ parentResult = 0;
599         if (ATK.g_type_is_a (object.parentType, ATK_SELECTION_TYPE)) {
600             int /*long*/ superType = ATK.g_type_interface_peek_parent (ATK.ATK_SELECTION_GET_IFACE (object.handle));
601             AtkSelectionIface selectionIface = new AtkSelectionIface ();
602             ATK.memmove (selectionIface, superType);
603             if (selectionIface.ref_selection != 0) {
604                 parentResult = ATK.call (selectionIface.ref_selection, object.handle, index);
605             }
606         }
607         AccessibleControlListener[] listeners = object.getControlListeners ();
608         if (listeners.length == 0) return parentResult;
609             
610         AccessibleControlEvent event = new AccessibleControlEvent (object);
611         event.childID = object.id;
612         for (int i = 0; i < listeners.length; i++) {
613             listeners [i].getSelection (event);
614         }
615         AccessibleObject accObj = object.getChildByID (event.childID);
616         if (accObj != null) {
617             if (parentResult > 0) OS.g_object_unref (parentResult);
618             OS.g_object_ref (accObj.handle);
619             return accObj.handle;
620         }
621         return parentResult;
622     }
623
624     static int /*long*/ atkText_get_caret_offset (int /*long*/ atkObject) {
625         if (DEBUG) System.out.println ("-->atkText_get_caret_offset");
626         AccessibleObject object = getAccessibleObject (atkObject);
627         if (object == null) return 0;
628         int /*long*/ parentResult = 0;
629         if (ATK.g_type_is_a (object.parentType, ATK_TEXT_TYPE)) {
630             int /*long*/ superType = ATK.g_type_interface_peek_parent (ATK.ATK_TEXT_GET_IFACE (object.handle));
631             AtkTextIface textIface = new AtkTextIface ();
632             ATK.memmove (textIface, superType);
633             if (textIface.get_caret_offset != 0) {
634                 parentResult = ATK.call (textIface.get_caret_offset, object.handle);
635             }
636         }
637         AccessibleTextListener[] listeners = object.getTextListeners ();
638         if (listeners.length == 0) return parentResult;
639         
640         AccessibleTextEvent event = new AccessibleTextEvent (object);
641         event.childID = object.id;
642         event.offset = (int)/*64*/parentResult;
643         for (int i = 0; i < listeners.length; i++) {
644             listeners [i].getCaretOffset (event);
645         }
646         return event.offset;
647     }
648     
649     static int /*long*/ atkText_get_character_at_offset (int /*long*/ atkObject, int /*long*/ offset) {
650         if (DEBUG) System.out.println ("-->atkText_get_character_at_offset");
651         AccessibleObject object = getAccessibleObject (atkObject);
652         if (object == null) return 0;
653         String JavaDoc text = object.getText ();
654         if (text != null) return (int)text.charAt ((int)/*64*/offset); // TODO
655
if (ATK.g_type_is_a (object.parentType, ATK_TEXT_TYPE)) {
656             int /*long*/ superType = ATK.g_type_class_peek (object.parentType);
657             AtkTextIface textIface = new AtkTextIface ();
658             ATK.memmove (textIface, superType);
659             if (textIface.get_character_at_offset != 0) {
660                 return ATK.call (textIface.get_character_at_offset, object.handle, offset);
661             }
662         }
663         return 0;
664     }
665
666     static int /*long*/ atkText_get_character_count (int /*long*/ atkObject) {
667         if (DEBUG) System.out.println ("-->atkText_get_character_count");
668         AccessibleObject object = getAccessibleObject (atkObject);
669         if (object == null) return 0;
670         String JavaDoc text = object.getText ();
671         if (text != null) return text.length ();
672         if (ATK.g_type_is_a (object.parentType, ATK_TEXT_TYPE)) {
673             int /*long*/ superType = ATK.g_type_class_peek (object.parentType);
674             AtkTextIface textIface = new AtkTextIface ();
675             ATK.memmove (textIface, superType);
676             if (textIface.get_character_count != 0) {
677                 return ATK.call (textIface.get_character_count, object.handle);
678             }
679         }
680         return 0;
681     }
682
683     static int /*long*/ atkText_get_n_selections (int /*long*/ atkObject) {
684         if (DEBUG) System.out.println ("-->atkText_get_n_selections");
685         AccessibleObject object = getAccessibleObject (atkObject);
686         if (object == null) return 0;
687         int /*long*/ parentResult = 0;
688         if (ATK.g_type_is_a (object.parentType, ATK_TEXT_TYPE)) {
689             int /*long*/ superType = ATK.g_type_interface_peek_parent (ATK.ATK_TEXT_GET_IFACE (object.handle));
690             AtkTextIface textIface = new AtkTextIface ();
691             ATK.memmove (textIface, superType);
692             if (textIface.get_n_selections != 0) {
693                 parentResult = ATK.call (textIface.get_n_selections, object.handle);
694             }
695         }
696         AccessibleTextListener[] listeners = object.getTextListeners ();
697         if (listeners.length == 0) return parentResult;
698
699         AccessibleTextEvent event = new AccessibleTextEvent (object);
700         event.childID = object.id;
701         for (int i = 0; i < listeners.length; i++) {
702             listeners [i].getSelectionRange (event);
703         }
704         return event.length == 0 ? parentResult : 1;
705     }
706
707     static int /*long*/ atkText_get_selection (int /*long*/ atkObject, int /*long*/ selection_num, int /*long*/ start_offset, int /*long*/ end_offset) {
708         if (DEBUG) System.out.println ("-->atkText_get_selection");
709         AccessibleObject object = getAccessibleObject (atkObject);
710         if (object == null) return 0;
711         OS.memmove (start_offset, new int[] {0}, 4);
712         OS.memmove (end_offset, new int[] {0}, 4);
713         if (ATK.g_type_is_a (object.parentType, ATK_TEXT_TYPE)) {
714             int /*long*/ superType = ATK.g_type_interface_peek_parent (ATK.ATK_TEXT_GET_IFACE (object.handle));
715             AtkTextIface textIface = new AtkTextIface ();
716             ATK.memmove (textIface, superType);
717             if (textIface.get_selection != 0) {
718                 ATK.call (textIface.get_selection, object.handle, selection_num, start_offset, end_offset);
719             }
720         }
721         AccessibleTextListener[] listeners = object.getTextListeners ();
722         if (listeners.length == 0) return 0;
723
724         AccessibleTextEvent event = new AccessibleTextEvent (object);
725         event.childID = object.id;
726         int[] parentStart = new int [1];
727         int[] parentEnd = new int [1];
728         OS.memmove (parentStart, start_offset, 4);
729         OS.memmove (parentEnd, end_offset, 4);
730         event.offset = parentStart [0];
731         event.length = parentEnd [0] - parentStart [0];
732         for (int i = 0; i < listeners.length; i++) {
733             listeners [i].getSelectionRange (event);
734         }
735         OS.memmove (start_offset, new int[] {event.offset}, 4);
736         OS.memmove (end_offset, new int[] {event.offset + event.length}, 4);
737         return 0;
738     }
739
740     static int /*long*/ atkText_get_text (int /*long*/ atkObject, int /*long*/ start_offset, int /*long*/ end_offset) {
741         if (DEBUG) System.out.println ("-->atkText_get_text: " + start_offset + "," + end_offset);
742         AccessibleObject object = getAccessibleObject (atkObject);
743         if (object == null) return 0;
744         String JavaDoc text = object.getText ();
745         if (text.length () > 0) {
746             if (end_offset == -1) {
747                 end_offset = text.length ();
748             } else {
749                 end_offset = Math.min (end_offset, text.length ());
750             }
751             start_offset = Math.min (start_offset, end_offset);
752             text = text.substring ((int)/*64*/start_offset, (int)/*64*/end_offset);
753             byte[] bytes = Converter.wcsToMbcs (null, text, true);
754             int /*long*/ result = OS.g_malloc (bytes.length);
755             OS.memmove (result, bytes, bytes.length);
756             return result;
757         }
758         return 0;
759     }
760
761     static int /*long*/ atkText_get_text_after_offset (int /*long*/ atkObject, int /*long*/ offset_value, int /*long*/ boundary_type, int /*long*/ start_offset, int /*long*/ end_offset) {
762         if (DEBUG) System.out.println ("-->atkText_get_text_after_offset");
763         AccessibleObject object = getAccessibleObject (atkObject);
764         if (object == null) return 0;
765         int offset = (int)/*64*/offset_value;
766         String JavaDoc text = object.getText ();
767         if (text.length () > 0) {
768             int length = text.length ();
769             offset = Math.min (offset, length - 1);
770             int startBounds = offset;
771             int endBounds = offset;
772             switch ((int)/*64*/boundary_type) {
773                 case ATK.ATK_TEXT_BOUNDARY_CHAR: {
774                     if (length > offset) endBounds++;
775                     break;
776                 }
777                 case ATK.ATK_TEXT_BOUNDARY_WORD_START: {
778                     int wordStart1 = nextIndexOfChar (text, " !?.\n", offset - 1);
779                     if (wordStart1 == -1) {
780                         startBounds = endBounds = length;
781                         break;
782                     }
783                     wordStart1 = nextIndexOfNotChar (text, " !?.\n", wordStart1);
784                     if (wordStart1 == length) {
785                         startBounds = endBounds = length;
786                         break;
787                     }
788                     startBounds = wordStart1;
789                     int wordStart2 = nextIndexOfChar (text, " !?.\n", wordStart1);
790                     if (wordStart2 == -1) {
791                         endBounds = length;
792                         break;
793                     }
794                     endBounds = nextIndexOfNotChar (text, " !?.\n", wordStart2);
795                     break;
796                 }
797                 case ATK.ATK_TEXT_BOUNDARY_WORD_END: {
798                     int previousWordEnd = previousIndexOfNotChar (text, " \n", offset);
799                     if (previousWordEnd == -1 || previousWordEnd != offset - 1) {
800                         offset = nextIndexOfNotChar (text, " \n", offset);
801                     }
802                     if (offset == -1) {
803                         startBounds = endBounds = length;
804                         break;
805                     }
806                     int wordEnd1 = nextIndexOfChar (text, " !?.\n", (int)/*64*/offset);
807                     if (wordEnd1 == -1) {
808                         startBounds = endBounds = length;
809                         break;
810                     }
811                     wordEnd1 = nextIndexOfNotChar (text, "!?.", wordEnd1);
812                     if (wordEnd1 == length) {
813                         startBounds = endBounds = length;
814                         break;
815                     }
816                     startBounds = wordEnd1;
817                     int wordEnd2 = nextIndexOfNotChar (text, " \n", wordEnd1);
818                     if (wordEnd2 == length) {
819                         startBounds = endBounds = length;
820                         break;
821                     }
822                     wordEnd2 = nextIndexOfChar (text, " !?.\n", wordEnd2);
823                     if (wordEnd2 == -1) {
824                         endBounds = length;
825                         break;
826                     }
827                     endBounds = nextIndexOfNotChar (text, "!?.", wordEnd2);
828                     break;
829                 }
830                 case ATK.ATK_TEXT_BOUNDARY_SENTENCE_START: {
831                     int previousSentenceEnd = previousIndexOfChar (text, "!?.", offset);
832                     int previousText = previousIndexOfNotChar (text, " !?.\n", offset);
833                     int sentenceStart1 = 0;
834                     if (previousSentenceEnd >= previousText) {
835                         sentenceStart1 = nextIndexOfNotChar (text, " !?.\n", offset);
836                     } else {
837                         sentenceStart1 = nextIndexOfChar (text, "!?.", offset);
838                         if (sentenceStart1 == -1) {
839                             startBounds = endBounds = length;
840                             break;
841                         }
842                         sentenceStart1 = nextIndexOfNotChar (text, " !?.\n", sentenceStart1);
843                     }
844                     if (sentenceStart1 == length) {
845                         startBounds = endBounds = length;
846                         break;
847                     }
848                     startBounds = sentenceStart1;
849                     int sentenceStart2 = nextIndexOfChar (text, "!?.", sentenceStart1);
850                     if (sentenceStart2 == -1) {
851                         endBounds = length;
852                         break;
853                     }
854                     endBounds = nextIndexOfNotChar (text, " !?.\n", sentenceStart2);
855                     break;
856                 }
857                 case ATK.ATK_TEXT_BOUNDARY_SENTENCE_END: {
858                     int sentenceEnd1 = nextIndexOfChar (text, "!?.", offset);
859                     if (sentenceEnd1 == -1) {
860                         startBounds = endBounds = length;
861                         break;
862                     }
863                     sentenceEnd1 = nextIndexOfNotChar (text, "!?.", sentenceEnd1);
864                     if (sentenceEnd1 == length) {
865                         startBounds = endBounds = length;
866                         break;
867                     }
868                     startBounds = sentenceEnd1;
869                     int sentenceEnd2 = nextIndexOfNotChar (text, " \n", sentenceEnd1);
870                     if (sentenceEnd2 == length) {
871                         startBounds = endBounds = length;
872                         break;
873                     }
874                     sentenceEnd2 = nextIndexOfChar (text, "!?.", sentenceEnd2);
875                     if (sentenceEnd2 == -1) {
876                         endBounds = length;
877                         break;
878                     }
879                     endBounds = nextIndexOfNotChar (text, "!?.", sentenceEnd2);
880                     break;
881                 }
882                 case ATK.ATK_TEXT_BOUNDARY_LINE_START: {
883                     int lineStart1 = text.indexOf ('\n', offset - 1);
884                     if (lineStart1 == -1) {
885                         startBounds = endBounds = length;
886                         break;
887                     }
888                     lineStart1 = nextIndexOfNotChar (text, "\n", lineStart1);
889                     if (lineStart1 == length) {
890                         startBounds = endBounds = length;
891                         break;
892                     }
893                     startBounds = lineStart1;
894                     int lineStart2 = text.indexOf ('\n', lineStart1);
895                     if (lineStart2 == -1) {
896                         endBounds = length;
897                         break;
898                     }
899                     lineStart2 = nextIndexOfNotChar (text, "\n", lineStart2);
900                     endBounds = lineStart2;
901                     break;
902                 }
903                 case ATK.ATK_TEXT_BOUNDARY_LINE_END: {
904                     int lineEnd1 = nextIndexOfChar (text, "\n", offset);
905                     if (lineEnd1 == -1) {
906                         startBounds = endBounds = length;
907                         break;
908                     }
909                     startBounds = lineEnd1;
910                     if (startBounds == length) {
911                         endBounds = length;
912                         break;
913                     }
914                     int lineEnd2 = nextIndexOfChar (text, "\n", lineEnd1 + 1);
915                     if (lineEnd2 == -1) {
916                         endBounds = length;
917                         break;
918                     }
919                     endBounds = lineEnd2;
920                     break;
921                 }
922             }
923             OS.memmove (start_offset, new int[] {startBounds}, 4);
924             OS.memmove (end_offset, new int[] {endBounds}, 4);
925             text = text.substring (startBounds, endBounds);
926             byte[] bytes = Converter.wcsToMbcs (null, text, true);
927             int /*long*/ result = OS.g_malloc (bytes.length);
928             OS.memmove (result, bytes, bytes.length);
929             return result;
930         }
931         return 0;
932     }
933
934     static int /*long*/ atkText_get_text_at_offset (int /*long*/ atkObject, int /*long*/ offset_value, int /*long*/ boundary_type, int /*long*/ start_offset, int /*long*/ end_offset) {
935         if (DEBUG) System.out.println ("-->atkText_get_text_at_offset: " + offset_value + " start: " + start_offset + " end: " + end_offset);
936         AccessibleObject object = getAccessibleObject (atkObject);
937         if (object == null) return 0;
938         int offset = (int)/*64*/offset_value;
939         String JavaDoc text = object.getText ();
940         if (text.length () > 0) {
941             int length = text.length ();
942             offset = Math.min (offset, length - 1);
943             int startBounds = offset;
944             int endBounds = offset;
945             switch ((int)/*64*/boundary_type) {
946                 case ATK.ATK_TEXT_BOUNDARY_CHAR: {
947                     if (length > offset) endBounds++;
948                     break;
949                 }
950                 case ATK.ATK_TEXT_BOUNDARY_WORD_START: {
951                     int wordStart1 = previousIndexOfNotChar (text, " !?.\n", offset);
952                     if (wordStart1 == -1) {
953                         startBounds = endBounds = 0;
954                         break;
955                     }
956                     wordStart1 = previousIndexOfChar (text, " !?.\n", wordStart1) + 1;
957                     if (wordStart1 == -1) {
958                         startBounds = 0;
959                         break;
960                     }
961                     startBounds = wordStart1;
962                     int wordStart2 = nextIndexOfChar (text, " !?.\n", wordStart1);
963                     endBounds = nextIndexOfNotChar (text, " !?.\n", wordStart2);
964                     break;
965                 }
966                 case ATK.ATK_TEXT_BOUNDARY_WORD_END: {
967                     int wordEnd1 = previousIndexOfNotChar (text, "!?.", offset + 1);
968                     wordEnd1 = previousIndexOfChar (text, " !?.\n", wordEnd1);
969                     wordEnd1 = previousIndexOfNotChar (text, " \n", wordEnd1 + 1);
970                     if (wordEnd1 == -1) {
971                         startBounds = endBounds = 0;
972                         break;
973                     }
974                     startBounds = wordEnd1 + 1;
975                     int wordEnd2 = nextIndexOfNotChar (text, " \n", startBounds);
976                     if (wordEnd2 == length) {
977                         endBounds = startBounds;
978                         break;
979                     }
980                     wordEnd2 = nextIndexOfChar (text, " !?.\n", wordEnd2);
981                     if (wordEnd2 == -1) {
982                         endBounds = startBounds;
983                         break;
984                     }
985                     endBounds = nextIndexOfNotChar (text, "!?.", wordEnd2);
986                     break;
987                 }
988                 case ATK.ATK_TEXT_BOUNDARY_SENTENCE_START: {
989                     int sentenceStart1 = previousIndexOfNotChar (text, " !?.\n", offset + 1);
990                     if (sentenceStart1 == -1) {
991                         startBounds = endBounds = 0;
992                         break;
993                     }
994                     sentenceStart1 = previousIndexOfChar (text, "!?.", sentenceStart1) + 1;
995                     startBounds = nextIndexOfNotChar (text, " \n", sentenceStart1);
996                     int sentenceStart2 = nextIndexOfChar (text, "!?.", startBounds);
997                     endBounds = nextIndexOfNotChar (text, " !?.\n", sentenceStart2);
998                     break;
999                 }
1000                case ATK.ATK_TEXT_BOUNDARY_SENTENCE_END: {
1001                    int sentenceEnd1 = previousIndexOfNotChar (text, "!?.", offset + 1);
1002                    sentenceEnd1 = previousIndexOfChar (text, "!?.", sentenceEnd1);
1003                    sentenceEnd1 = previousIndexOfNotChar (text, " \n", sentenceEnd1 + 1);
1004                    if (sentenceEnd1 == -1) {
1005                        startBounds = endBounds = 0;
1006                        break;
1007                    }
1008                    startBounds = sentenceEnd1 + 1;
1009                    int sentenceEnd2 = nextIndexOfNotChar (text, " \n", startBounds);
1010                    if (sentenceEnd2 == length) {
1011                        endBounds = startBounds;
1012                        break;
1013                    }
1014                    sentenceEnd2 = nextIndexOfChar (text, "!?.", sentenceEnd2);
1015                    if (sentenceEnd2 == -1) {
1016                        endBounds = startBounds;
1017                        break;
1018                    }
1019                    endBounds = nextIndexOfNotChar (text, "!?.", sentenceEnd2);
1020                    break;
1021                }
1022                case ATK.ATK_TEXT_BOUNDARY_LINE_START: {
1023                    startBounds = previousIndexOfChar (text, "\n", offset) + 1;
1024                    int lineEnd2 = nextIndexOfChar (text, "\n", startBounds);
1025                    if (lineEnd2 < length) lineEnd2++;
1026                    endBounds = lineEnd2;
1027                    break;
1028                }
1029                case ATK.ATK_TEXT_BOUNDARY_LINE_END: {
1030                    int lineEnd1 = previousIndexOfChar (text, "\n", offset);
1031                    if (lineEnd1 == -1) {
1032                        startBounds = endBounds = 0;
1033                        break;
1034                    }
1035                    startBounds = lineEnd1;
1036                    endBounds = nextIndexOfChar (text, "\n", lineEnd1 + 1);
1037                }
1038            }
1039            OS.memmove (start_offset, new int[] {startBounds}, 4);
1040            OS.memmove (end_offset, new int[] {endBounds}, 4);
1041            text = text.substring (startBounds, endBounds);
1042            byte[] bytes = Converter.wcsToMbcs (null, text, true);
1043            int /*long*/ result = OS.g_malloc (bytes.length);
1044            OS.memmove (result, bytes, bytes.length);
1045            return result;
1046        }
1047        return 0;
1048    }
1049
1050    static int /*long*/ atkText_get_text_before_offset (int /*long*/ atkObject, int /*long*/ offset_value, int /*long*/ boundary_type, int /*long*/ start_offset, int /*long*/ end_offset) {
1051        if (DEBUG) System.out.println ("-->atkText_get_text_before_offset");
1052        AccessibleObject object = getAccessibleObject (atkObject);
1053        if (object == null) return 0;
1054        int offset = (int)/*64*/offset_value;
1055        String JavaDoc text = object.getText ();
1056        if (text.length () > 0) {
1057            int length = text.length ();
1058            offset = Math.min (offset, length - 1);
1059            int startBounds = offset;
1060            int endBounds = offset;
1061            switch ((int)/*64*/boundary_type) {
1062                case ATK.ATK_TEXT_BOUNDARY_CHAR: {
1063                    if (length >= offset && offset > 0) startBounds--;
1064                    break;
1065                }
1066                case ATK.ATK_TEXT_BOUNDARY_WORD_START: {
1067                    int wordStart1 = previousIndexOfChar (text, " !?.\n", offset - 1);
1068                    if (wordStart1 == -1) {
1069                        startBounds = endBounds = 0;
1070                        break;
1071                    }
1072                    int wordStart2 = previousIndexOfNotChar (text, " !?.\n", wordStart1);
1073                    if (wordStart2 == -1) {
1074                        startBounds = endBounds = 0;
1075                        break;
1076                    }
1077                    endBounds = wordStart1 + 1;
1078                    startBounds = previousIndexOfChar (text, " !?.\n", wordStart2) + 1;
1079                    break;
1080                }
1081                case ATK.ATK_TEXT_BOUNDARY_WORD_END: {
1082                    int wordEnd1 =previousIndexOfChar (text, " !?.\n", offset);
1083                    if (wordEnd1 == -1) {
1084                        startBounds = endBounds = 0;
1085                        break;
1086                    }
1087                    wordEnd1 = previousIndexOfNotChar (text, " \n", wordEnd1 + 1);
1088                    if (wordEnd1 == -1) {
1089                        startBounds = endBounds = 0;
1090                        break;
1091                    }
1092                    endBounds = wordEnd1 + 1;
1093                    int wordEnd2 = previousIndexOfNotChar (text, " !?.\n", endBounds);
1094                    wordEnd2 = previousIndexOfChar (text, " !?.\n", wordEnd2);
1095                    if (wordEnd2 == -1) {
1096                        startBounds = 0;
1097                        break;
1098                    }
1099                    startBounds = previousIndexOfNotChar (text, " \n", wordEnd2 + 1) + 1;
1100                    break;
1101                }
1102                case ATK.ATK_TEXT_BOUNDARY_SENTENCE_START: {
1103                    int sentenceStart1 = previousIndexOfChar (text, "!?.", offset);
1104                    if (sentenceStart1 == -1) {
1105                        startBounds = endBounds = 0;
1106                        break;
1107                    }
1108                    int sentenceStart2 = previousIndexOfNotChar (text, "!?.", sentenceStart1);
1109                    if (sentenceStart2 == -1) {
1110                        startBounds = endBounds = 0;
1111                        break;
1112                    }
1113                    endBounds = sentenceStart1 + 1;
1114                    startBounds = previousIndexOfChar (text, "!?.", sentenceStart2) + 1;
1115                    break;
1116                }
1117                case ATK.ATK_TEXT_BOUNDARY_SENTENCE_END: {
1118                    int sentenceEnd1 = previousIndexOfChar (text, "!?.", offset);
1119                    if (sentenceEnd1 == -1) {
1120                        startBounds = endBounds = 0;
1121                        break;
1122                    }
1123                    sentenceEnd1 = previousIndexOfNotChar (text, " \n", sentenceEnd1 + 1);
1124                    if (sentenceEnd1 == -1) {
1125                        startBounds = endBounds = 0;
1126                        break;
1127                    }
1128                    endBounds = sentenceEnd1 + 1;
1129                    int sentenceEnd2 = previousIndexOfNotChar (text, "!?.", endBounds);
1130                    sentenceEnd2 = previousIndexOfChar (text, "!?.", sentenceEnd2);
1131                    if (sentenceEnd2 == -1) {
1132                        startBounds = 0;
1133                        break;
1134                    }
1135                    startBounds = previousIndexOfNotChar (text, " \n", sentenceEnd2 + 1) + 1;
1136                    break;
1137                }
1138                case ATK.ATK_TEXT_BOUNDARY_LINE_START: {
1139                    int lineStart1 = previousIndexOfChar (text, "\n", offset);
1140                    if (lineStart1 == -1) {
1141                        startBounds = endBounds = 0;
1142                        break;
1143                    }
1144                    endBounds = lineStart1 + 1;
1145                    startBounds = previousIndexOfChar (text, "\n", lineStart1) + 1;
1146                    break;
1147                }
1148                case ATK.ATK_TEXT_BOUNDARY_LINE_END: {
1149                    int lineEnd1 = previousIndexOfChar (text, "\n", offset);
1150                    if (lineEnd1 == -1) {
1151                        startBounds = endBounds = 0;
1152                        break;
1153                    }
1154                    endBounds = lineEnd1;
1155                    startBounds = previousIndexOfChar (text, "\n", lineEnd1);
1156                    if (startBounds == -1) startBounds = 0;
1157                    break;
1158                }
1159            }
1160            OS.memmove (start_offset, new int[] {startBounds}, 4);
1161            OS.memmove (end_offset, new int[] {endBounds}, 4);
1162            text = text.substring (startBounds, endBounds);
1163            byte[] bytes = Converter.wcsToMbcs (null, text, true);
1164            int /*long*/ result = OS.g_malloc (bytes.length);
1165            OS.memmove (result, bytes, bytes.length);
1166            return result;
1167        }
1168        return 0;
1169    }
1170
1171    AccessibleListener[] getAccessibleListeners () {
1172        if (accessible == null) return new AccessibleListener [0];
1173        return accessible.getAccessibleListeners ();
1174    }
1175
1176    static AccessibleObject getAccessibleObject (int /*long*/ atkObject) {
1177        return (AccessibleObject)AccessibleObjects.get (new LONG (atkObject));
1178    }
1179    
1180    AccessibleObject getChildByHandle (int /*long*/ handle) {
1181        return (AccessibleObject) children.get (new LONG (handle));
1182    }
1183
1184    AccessibleObject getChildByID (int childId) {
1185        if (childId == ACC.CHILDID_SELF) return this;
1186        Enumeration elements = children.elements ();
1187        while (elements.hasMoreElements ()) {
1188            AccessibleObject object = (AccessibleObject) elements.nextElement ();
1189            if (object.id == childId) return object;
1190        }
1191        return null;
1192    }
1193    
1194    AccessibleObject getChildByIndex (int childIndex) {
1195        Enumeration elements = children.elements ();
1196        while (elements.hasMoreElements ()) {
1197            AccessibleObject object = (AccessibleObject) elements.nextElement ();
1198            if (object.index == childIndex) return object;
1199        }
1200        return null;
1201    }
1202    
1203    AccessibleControlListener[] getControlListeners () {
1204        if (accessible == null) return new AccessibleControlListener [0];
1205        return accessible.getControlListeners ();
1206    }
1207
1208    String JavaDoc getText () {
1209        int /*long*/ parentResult = 0;
1210        String JavaDoc parentText = ""; //$NON-NLS-1$
1211
if (ATK.g_type_is_a (parentType, ATK_TEXT_TYPE)) {
1212            int /*long*/ superType = ATK.g_type_interface_peek_parent (ATK.ATK_TEXT_GET_IFACE (handle));
1213            AtkTextIface textIface = new AtkTextIface ();
1214            ATK.memmove (textIface, superType);
1215            int /*long*/ characterCount = 0;
1216            if (textIface.get_character_count != 0) {
1217                characterCount = ATK.call (textIface.get_character_count, handle);
1218            }
1219            if (characterCount > 0 && textIface.get_text != 0) {
1220                parentResult = ATK.call (textIface.get_text, handle, 0, characterCount);
1221                if (parentResult != 0) {
1222                    int length = OS.strlen (parentResult);
1223                    byte [] buffer = new byte [length];
1224                    OS.memmove (buffer, parentResult, length);
1225                    parentText = new String JavaDoc (Converter.mbcsToWcs (null, buffer));
1226                }
1227            }
1228        }
1229        AccessibleControlListener[] controlListeners = getControlListeners ();
1230        if (controlListeners.length == 0) return parentText;
1231        AccessibleControlEvent event = new AccessibleControlEvent (this);
1232        event.childID = id;
1233        event.result = parentText;
1234        for (int i = 0; i < controlListeners.length; i++) {
1235            controlListeners [i].getValue (event);
1236        }
1237        return event.result;
1238    }
1239    
1240    AccessibleTextListener[] getTextListeners () {
1241        if (accessible == null) return new AccessibleTextListener [0];
1242        return accessible.getTextListeners ();
1243    }
1244
1245    static int /*long*/ gObjectClass_finalize (int /*long*/ atkObject) {
1246        int /*long*/ superType = ATK.g_type_class_peek_parent (ATK.G_OBJECT_GET_CLASS (atkObject));
1247        int /*long*/ gObjectClass = ATK.G_OBJECT_CLASS (superType);
1248        GObjectClass objectClassStruct = new GObjectClass ();
1249        ATK.memmove (objectClassStruct, gObjectClass);
1250        ATK.call (objectClassStruct.finalize, atkObject);
1251        AccessibleObject object = getAccessibleObject (atkObject);
1252        if (object != null) {
1253            AccessibleObjects.remove (new LONG (atkObject));
1254            object.release ();
1255        }
1256        return 0;
1257    }
1258    
1259    static int nextIndexOfChar (String JavaDoc string, String JavaDoc searchChars, int startIndex) {
1260        int result = string.length ();
1261        for (int i = 0; i < searchChars.length (); i++) {
1262            char current = searchChars.charAt (i);
1263            int index = string.indexOf (current, startIndex);
1264            if (index != -1) result = Math.min (result, index);
1265        }
1266        return result;
1267    }
1268
1269    static int nextIndexOfNotChar (String JavaDoc string, String JavaDoc searchChars, int startIndex) {
1270        int length = string.length ();
1271        int index = startIndex;
1272        while (index < length) {
1273            char current = string.charAt (index);
1274            if (searchChars.indexOf (current) == -1) break;
1275            index++;
1276        }
1277        return index;
1278    }
1279
1280    static int previousIndexOfChar (String JavaDoc string, String JavaDoc searchChars, int startIndex) {
1281        int result = -1;
1282        if (startIndex < 0) return result;
1283        string = string.substring (0, startIndex);
1284        for (int i = 0; i < searchChars.length (); i++) {
1285            char current = searchChars.charAt (i);
1286            int index = string.lastIndexOf (current);
1287            if (index != -1) result = Math.max (result, index);
1288        }
1289        return result;
1290    }
1291
1292    static int previousIndexOfNotChar (String JavaDoc string, String JavaDoc searchChars, int startIndex) {
1293        if (startIndex < 0) return -1;
1294        int index = startIndex - 1;
1295        while (index >= 0) {
1296            char current = string.charAt (index);
1297            if (searchChars.indexOf (current) == -1) break;
1298            index--;
1299        }
1300        return index;
1301    }
1302
1303    void release () {
1304        if (DEBUG) System.out.println("AccessibleObject.release: " + handle);
1305        accessible = null;
1306        Enumeration elements = children.elements ();
1307        while (elements.hasMoreElements ()) {
1308            AccessibleObject child = (AccessibleObject) elements.nextElement ();
1309            if (child.isLightweight) OS.g_object_unref (child.handle);
1310        }
1311        if (parent != null) parent.removeChild (this, false);
1312    }
1313    
1314    void removeChild (AccessibleObject child, boolean unref) {
1315        children.remove (new LONG (child.handle));
1316        if (unref && child.isLightweight) OS.g_object_unref (child.handle);
1317    }
1318    
1319    void selectionChanged () {
1320        OS.g_signal_emit_by_name (handle, ATK.selection_changed);
1321    }
1322    
1323    void setFocus (int childID) {
1324        updateChildren ();
1325        AccessibleObject accObject = getChildByID (childID);
1326        if (accObject != null) {
1327            ATK.atk_focus_tracker_notify (accObject.handle);
1328        }
1329    }
1330
1331    void setParent (AccessibleObject parent) {
1332        this.parent = parent;
1333    }
1334    
1335    void textCaretMoved(int index) {
1336        OS.g_signal_emit_by_name (handle, ATK.text_caret_moved, index);
1337    }
1338
1339    void textChanged(int type, int startIndex, int length) {
1340        if (type == ACC.TEXT_DELETE) {
1341            OS.g_signal_emit_by_name (handle, ATK.text_changed_delete, startIndex, length);
1342        } else {
1343            OS.g_signal_emit_by_name (handle, ATK.text_changed_insert, startIndex, length);
1344        }
1345    }
1346
1347    void textSelectionChanged() {
1348        OS.g_signal_emit_by_name (handle, ATK.text_selection_changed);
1349    }
1350
1351    void updateChildren () {
1352        if (isLightweight) return;
1353        AccessibleControlListener[] listeners = getControlListeners ();
1354        if (listeners.length == 0) return;
1355
1356        AccessibleControlEvent event = new AccessibleControlEvent (this);
1357        for (int i = 0; i < listeners.length; i++) {
1358            listeners [i].getChildren (event);
1359        }
1360        if (event.children != null && event.children.length > 0) {
1361            Vector idsToKeep = new Vector (children.size ());
1362            if (event.children [0] instanceof Integer JavaDoc) {
1363                /* an array of child id's (Integers) was answered */
1364                int /*long*/ parentType = AccessibleFactory.getDefaultParentType ();
1365                for (int i = 0; i < event.children.length; i++) {
1366                    AccessibleObject object = getChildByIndex (i);
1367                    if (object == null) {
1368                        int /*long*/ childType = AccessibleFactory.getChildType (accessible, i);
1369                        object = new AccessibleObject (childType, 0, accessible, parentType, true);
1370                        AccessibleObjects.put (new LONG (object.handle), object);
1371                        addChild (object);
1372                        object.index = i;
1373                    }
1374                    try {
1375                        object.id = ((Integer JavaDoc)event.children[i]).intValue ();
1376                    } catch (ClassCastException JavaDoc e) {
1377                        /* a non-ID value was given so don't set the ID */
1378                    }
1379                    idsToKeep.addElement (new LONG (object.handle));
1380                }
1381            } else {
1382                /* an array of Accessible children was answered */
1383                int childIndex = 0;
1384                for (int i = 0; i < event.children.length; i++) {
1385                    AccessibleObject object = null;
1386                    try {
1387                        object = ((Accessible)event.children [i]).accessibleObject;
1388                    } catch (ClassCastException JavaDoc e) {
1389                        /* a non-Accessible value was given so nothing to do here */
1390                    }
1391                    if (object != null) {
1392                        object.index = childIndex++;
1393                        idsToKeep.addElement (new LONG (object.handle));
1394                    }
1395                }
1396            }
1397            /* remove old children that were not provided as children anymore */
1398            Enumeration ids = children.keys ();
1399            while (ids.hasMoreElements ()) {
1400                LONG id = (LONG)ids.nextElement ();
1401                if (!idsToKeep.contains (id)) {
1402                    AccessibleObject object = (AccessibleObject) children.get (id);
1403                    removeChild (object, true);
1404                }
1405            }
1406        }
1407    }
1408}
1409
Popular Tags