changeset 42:787b5413b0ce

accessibility package
author Frank Benoit <benoit@tionex.de>
date Fri, 11 Jan 2008 05:07:22 +0100
parents c83c51423d03
children ecf39b275c8d
files dsss.conf dwt/accessibility/ACC.d dwt/accessibility/Accessible.d dwt/accessibility/AccessibleAdapter.d dwt/accessibility/AccessibleControlAdapter.d dwt/accessibility/AccessibleControlEvent.d dwt/accessibility/AccessibleControlListener.d dwt/accessibility/AccessibleEvent.d dwt/accessibility/AccessibleFactory.d dwt/accessibility/AccessibleListener.d dwt/accessibility/AccessibleObject.d dwt/accessibility/AccessibleTextAdapter.d dwt/accessibility/AccessibleTextEvent.d dwt/accessibility/AccessibleTextListener.d dwt/internal/accessibility/gtk/ATK.d dwt/internal/c/atk.d dwt/internal/c/gdk.d dwt/internal/c/gdkx.d dwt/internal/c/gtk.d dwt/internal/c/gtk_unix_print_2_0.d dwt/internal/c/pango.d dwt/internal/c/pangocairo.d dwt/internal/gtk/OS.d dwt/widgets/Display.d dwt/widgets/Shell.d todo.txt
diffstat 26 files changed, 3349 insertions(+), 27 deletions(-) [+]
line wrap: on
line diff
--- a/dsss.conf	Thu Jan 10 08:21:49 2008 +0100
+++ b/dsss.conf	Fri Jan 11 05:07:22 2008 +0100
@@ -1,3 +1,27 @@
 [dwt]
 type=library
 
+[helloworld.d]
+buildflags+=-L-lgtk-x11-2.0
+buildflags+=-L-lgdk-x11-2.0
+buildflags+=-L-latk-1.0
+buildflags+=-L-lgdk_pixbuf-2.0
+buildflags+=-L-lm
+buildflags+=-L-lpangocairo-1.0
+buildflags+=-L-lfontconfig
+buildflags+=-L-lXext
+buildflags+=-L-lXrender
+buildflags+=-L-lXinerama
+buildflags+=-L-lXi
+buildflags+=-L-lXrandr
+buildflags+=-L-lXcursor
+buildflags+=-L-lXcomposite
+buildflags+=-L-lXdamage
+buildflags+=-L-lX11
+buildflags+=-L-lXfixes
+buildflags+=-L-lpango-1.0
+buildflags+=-L-lgobject-2.0
+buildflags+=-L-lgmodule-2.0
+buildflags+=-L-ldl
+buildflags+=-L-lglib-2.0
+buildflags+=-L-lcairo
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwt/accessibility/ACC.d	Fri Jan 11 05:07:22 2008 +0100
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+module dwt.accessibility.ACC;
+
+
+/**
+ * Class ACC contains all the constants used in defining an
+ * Accessible object.
+ *
+ * @since 2.0
+ */
+public class ACC {
+	public static const int STATE_NORMAL = 0x00000000;
+	public static const int STATE_SELECTED = 0x00000002;
+	public static const int STATE_SELECTABLE = 0x00200000;
+	public static const int STATE_MULTISELECTABLE = 0x1000000;
+	public static const int STATE_FOCUSED = 0x00000004;
+	public static const int STATE_FOCUSABLE = 0x00100000;
+	public static const int STATE_PRESSED = 0x8;
+	public static const int STATE_CHECKED = 0x10;
+	public static const int STATE_EXPANDED = 0x200;
+	public static const int STATE_COLLAPSED = 0x400;
+	public static const int STATE_HOTTRACKED = 0x80;
+	public static const int STATE_BUSY = 0x800;
+	public static const int STATE_READONLY = 0x40;
+	public static const int STATE_INVISIBLE = 0x8000;
+	public static const int STATE_OFFSCREEN = 0x10000;
+	public static const int STATE_SIZEABLE = 0x20000;
+	public static const int STATE_LINKED = 0x400000;
+
+	public static const int ROLE_CLIENT_AREA = 0xa;
+	public static const int ROLE_WINDOW = 0x9;
+	public static const int ROLE_MENUBAR = 0x2;
+	public static const int ROLE_MENU = 0xb;
+	public static const int ROLE_MENUITEM = 0xc;
+	public static const int ROLE_SEPARATOR = 0x15;
+	public static const int ROLE_TOOLTIP = 0xd;
+	public static const int ROLE_SCROLLBAR = 0x3;
+	public static const int ROLE_DIALOG = 0x12;
+	public static const int ROLE_LABEL = 0x29;
+	public static const int ROLE_PUSHBUTTON = 0x2b;
+	public static const int ROLE_CHECKBUTTON = 0x2c;
+	public static const int ROLE_RADIOBUTTON = 0x2d;
+	public static const int ROLE_COMBOBOX = 0x2e;
+	public static const int ROLE_TEXT = 0x2a;
+	public static const int ROLE_TOOLBAR = 0x16;
+	public static const int ROLE_LIST = 0x21;
+	public static const int ROLE_LISTITEM = 0x22;
+	public static const int ROLE_TABLE = 0x18;
+	public static const int ROLE_TABLECELL = 0x1d;
+	public static const int ROLE_TABLECOLUMNHEADER = 0x19;
+	/** @deprecated use ROLE_TABLECOLUMNHEADER */
+	public static const int ROLE_TABLECOLUMN = ROLE_TABLECOLUMNHEADER;
+	public static const int ROLE_TABLEROWHEADER = 0x1a;
+	public static const int ROLE_TREE = 0x23;
+	public static const int ROLE_TREEITEM = 0x24;
+	public static const int ROLE_TABFOLDER = 0x3c;
+	public static const int ROLE_TABITEM = 0x25;
+	public static const int ROLE_PROGRESSBAR = 0x30;
+	public static const int ROLE_SLIDER = 0x33;
+	public static const int ROLE_LINK = 0x1e;
+
+	public static const int CHILDID_SELF = -1;
+	public static const int CHILDID_NONE = -2;
+	public static const int CHILDID_MULTIPLE = -3;
+
+	public static const int TEXT_INSERT = 0;
+	public static const int TEXT_DELETE = 1;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwt/accessibility/Accessible.d	Fri Jan 11 05:07:22 2008 +0100
@@ -0,0 +1,392 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+module dwt.accessibility.Accessible;
+
+import dwt.accessibility.AccessibleListener;
+import dwt.accessibility.AccessibleTextListener;
+import dwt.accessibility.AccessibleControlListener;
+import dwt.accessibility.AccessibleControlListener;
+import dwt.accessibility.AccessibleFactory;
+import dwt.accessibility.AccessibleObject;
+import tango.core.Thread;
+import dwt.SWT;
+//import dwt.events.*;
+import dwt.internal.gtk.OS;
+import dwt.widgets.Control;
+import tango.core.Array;
+import dwt.events.DisposeListener;
+import dwt.events.DisposeEvent;
+
+/**
+ * Instances of this class provide a bridge between application
+ * code and assistive technology clients. Many platforms provide
+ * default accessible behavior for most widgets, and this class
+ * allows that default behavior to be overridden. Applications
+ * can get the default Accessible object for a control by sending
+ * it <code>getAccessible</code>, and then add an accessible listener
+ * to override simple items like the name and help string, or they
+ * can add an accessible control listener to override complex items.
+ * As a rule of thumb, an application would only want to use the
+ * accessible control listener to implement accessibility for a
+ * custom control.
+ *
+ * @see Control#getAccessible
+ * @see AccessibleListener
+ * @see AccessibleEvent
+ * @see AccessibleControlListener
+ * @see AccessibleControlEvent
+ *
+ * @since 2.0
+ */
+public class Accessible {
+	AccessibleListener[] accessibleListeners;
+	AccessibleControlListener[] controlListeners;
+	AccessibleTextListener[] textListeners;
+	AccessibleObject accessibleObject;
+	Control control;
+
+	this (Control control) {
+		this.control = control;
+		AccessibleFactory.registerAccessible (this);
+		control.addDisposeListener (new class () DisposeListener {
+			public void widgetDisposed (DisposeEvent e) {
+				release ();
+			}
+		});
+	}
+
+	/**
+	 * Adds the listener to the collection of listeners who will
+	 * be notified when an accessible client asks for certain strings,
+	 * such as name, description, help, or keyboard shortcut. The
+	 * listener is notified by sending it one of the messages defined
+	 * in the <code>AccessibleListener</code> interface.
+	 *
+	 * @param listener the listener that should be notified when the receiver
+	 * is asked for a name, description, help, or keyboard shortcut string
+	 *
+	 * @exception IllegalArgumentException <ul>
+	 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+	 * </ul>
+	 * @exception SWTException <ul>
+	 *    <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
+	 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
+	 * </ul>
+	 *
+	 * @see AccessibleListener
+	 * @see #removeAccessibleListener
+	 */
+	public void addAccessibleListener (AccessibleListener listener) {
+		checkWidget ();
+		if (listener is null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
+		accessibleListeners ~= listener;
+	}
+
+	/**
+	 * Adds the listener to the collection of listeners who will
+	 * be notified when an accessible client asks for custom control
+	 * specific information. The listener is notified by sending it
+	 * one of the messages defined in the <code>AccessibleControlListener</code>
+	 * interface.
+	 *
+	 * @param listener the listener that should be notified when the receiver
+	 * is asked for custom control specific information
+	 *
+	 * @exception IllegalArgumentException <ul>
+	 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+	 * </ul>
+	 * @exception SWTException <ul>
+	 *    <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
+	 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
+	 * </ul>
+	 *
+	 * @see AccessibleControlListener
+	 * @see #removeAccessibleControlListener
+	 */
+	public void addAccessibleControlListener (AccessibleControlListener listener) {
+		checkWidget ();
+		if (listener is null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
+		controlListeners ~= listener;
+	}
+
+	/**
+	 * Adds the listener to the collection of listeners who will
+	 * be notified when an accessible client asks for custom text control
+	 * specific information. The listener is notified by sending it
+	 * one of the messages defined in the <code>AccessibleTextListener</code>
+	 * interface.
+	 *
+	 * @param listener the listener that should be notified when the receiver
+	 * is asked for custom text control specific information
+	 *
+	 * @exception IllegalArgumentException <ul>
+	 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+	 * </ul>
+	 * @exception SWTException <ul>
+	 *    <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
+	 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
+	 * </ul>
+	 *
+	 * @see AccessibleTextListener
+	 * @see #removeAccessibleTextListener
+	 *
+	 * @since 3.0
+	 */
+	public void addAccessibleTextListener (AccessibleTextListener listener) {
+		checkWidget ();
+		if (listener is null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
+		textListeners ~= listener;
+	}
+
+	/**
+	 * Returns the control for this Accessible object.
+	 *
+	 * @return the receiver's control
+	 * @since 3.0
+	 */
+	public Control getControl() {
+		return control;
+	}
+
+	/* checkWidget was copied from Widget, and rewritten to work in this package */
+	void checkWidget () {
+		if (!isValidThread ()) SWT.error (SWT.ERROR_THREAD_INVALID_ACCESS);
+		if (control.isDisposed ()) SWT.error (SWT.ERROR_WIDGET_DISPOSED);
+	}
+
+	AccessibleListener[] getAccessibleListeners () {
+		if (accessibleListeners.length is 0 ) return null;
+		return accessibleListeners.dup;
+	}
+
+	GtkWidget* getControlHandle () {
+		return control.handle;
+	}
+
+	AccessibleControlListener[] getControlListeners () {
+		if (controlListeners.length is 0) return null;
+		return controlListeners.dup;
+	}
+
+	AccessibleTextListener[] getTextListeners () {
+		if (textListeners.length is 0) return null;
+		return textListeners.dup;
+	}
+
+	/**
+	 * Invokes platform specific functionality to allocate a new accessible object.
+	 * <p>
+	 * <b>IMPORTANT:</b> This method is <em>not</em> part of the public
+	 * API for <code>Accessible</code>. It is marked public only so that it
+	 * can be shared within the packages provided by SWT. It is not
+	 * available on all platforms, and should never be called from
+	 * application code.
+	 * </p>
+	 *
+	 * @param control the control to get the accessible object for
+	 * @return the platform specific accessible object
+	 */
+	public static Accessible internal_new_Accessible (Control control) {
+		return new Accessible (control);
+	}
+
+	/* isValidThread was copied from Widget, and rewritten to work in this package */
+	bool isValidThread () {
+		return control.getDisplay ().getThread () is Thread.getThis ();
+	}
+
+	void release () {
+		AccessibleFactory.unregisterAccessible (/*Accessible.*/this);
+		if (accessibleObject !is null) {
+			accessibleObject.release ();
+			accessibleObject = null;
+		}
+		accessibleListeners = null;
+		controlListeners = null;
+		textListeners = null;
+	}
+	/**
+	 * Removes the listener from the collection of listeners who will
+	 * be notified when an accessible client asks for custom control
+	 * specific information.
+	 *
+	 * @param listener the listener that should no longer be notified when the receiver
+	 * is asked for custom control specific information
+	 *
+	 * @exception IllegalArgumentException <ul>
+	 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+	 * </ul>
+	 * @exception SWTException <ul>
+	 *    <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
+	 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
+	 * </ul>
+	 *
+	 * @see AccessibleControlListener
+	 * @see #addAccessibleControlListener
+	 */
+	public void removeAccessibleControlListener (AccessibleControlListener listener) {
+		checkWidget ();
+		if (listener is null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
+		remove( controlListeners, listener, delegate bool(AccessibleControlListener a1, AccessibleControlListener a2 ){ return a1 is a2; });
+	}
+
+	/**
+	 * Removes the listener from the collection of listeners who will
+	 * be notified when an accessible client asks for certain strings,
+	 * such as name, description, help, or keyboard shortcut.
+	 *
+	 * @param listener the listener that should no longer be notified when the receiver
+	 * is asked for a name, description, help, or keyboard shortcut string
+	 *
+	 * @exception IllegalArgumentException <ul>
+	 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+	 * </ul>
+	 * @exception SWTException <ul>
+	 *    <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
+	 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
+	 * </ul>
+	 *
+	 * @see AccessibleListener
+	 * @see #addAccessibleListener
+	 */
+	public void removeAccessibleListener (AccessibleListener listener) {
+		checkWidget ();
+		if (listener is null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
+		remove( accessibleListeners, listener, delegate bool( AccessibleListener a1, AccessibleListener a2 ){ return a1 is a2; });
+	}
+
+	/**
+	 * Removes the listener from the collection of listeners who will
+	 * be notified when an accessible client asks for custom text control
+	 * specific information.
+	 *
+	 * @param listener the listener that should no longer be notified when the receiver
+	 * is asked for custom text control specific information
+	 *
+	 * @exception IllegalArgumentException <ul>
+	 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+	 * </ul>
+	 * @exception SWTException <ul>
+	 *    <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
+	 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
+	 * </ul>
+	 *
+	 * @see AccessibleTextListener
+	 * @see #addAccessibleTextListener
+	 *
+	 * @since 3.0
+	 */
+	public void removeAccessibleTextListener (AccessibleTextListener listener) {
+		checkWidget ();
+		if (listener is null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
+		remove( textListeners, listener, delegate bool(AccessibleTextListener a1, AccessibleTextListener a2 ){ return a1 is a2; });
+	}
+
+	/**
+	 * Sends a message to accessible clients that the child selection
+	 * within a custom container control has changed.
+	 *
+	 * @exception SWTException <ul>
+	 *    <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
+	 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
+	 * </ul>
+	 *
+	 * @since 3.0
+	 */
+	public void selectionChanged () {
+		checkWidget ();
+		if (accessibleObject !is null) {
+			accessibleObject.selectionChanged ();
+		}
+	}
+
+	/**
+	 * Sends a message to accessible clients indicating that the focus
+	 * has changed within a custom control.
+	 *
+	 * @param childID an identifier specifying a child of the control
+	 *
+	 * @exception SWTException <ul>
+	 *    <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
+	 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
+	 * </ul>
+	 */
+	public void setFocus (int childID) {
+		checkWidget ();
+		if (accessibleObject !is null) {
+			accessibleObject.setFocus (childID);
+		}
+	}
+
+	/**
+	 * Sends a message to accessible clients that the text
+	 * caret has moved within a custom control.
+	 *
+	 * @param index the new caret index within the control
+	 *
+	 * @exception SWTException <ul>
+	 *    <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
+	 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
+	 * </ul>
+	 *
+	 * @since 3.0
+	 */
+	public void textCaretMoved (int index) {
+		checkWidget ();
+		if (accessibleObject !is null) {
+			accessibleObject.textCaretMoved (index);
+		}
+	}
+
+	/**
+	 * Sends a message to accessible clients that the text
+	 * within a custom control has changed.
+	 *
+	 * @param type the type of change, one of <code>ACC.NOTIFY_TEXT_INSERT</code>
+	 * or <code>ACC.NOTIFY_TEXT_DELETE</code>
+	 * @param startIndex the text index within the control where the insertion or deletion begins
+	 * @param length the non-negative length in characters of the insertion or deletion
+	 *
+	 * @exception SWTException <ul>
+	 *    <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
+	 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
+	 * </ul>
+	 *
+	 * @see ACC#TEXT_INSERT
+	 * @see ACC#TEXT_DELETE
+	 *
+	 * @since 3.0
+	 */
+	public void textChanged (int type, int startIndex, int length) {
+		checkWidget ();
+		if (accessibleObject !is null) {
+			accessibleObject.textChanged (type, startIndex, length);
+		}
+	}
+
+	/**
+	 * Sends a message to accessible clients that the text
+	 * selection has changed within a custom control.
+	 *
+	 * @exception SWTException <ul>
+	 *    <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li>
+	 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li>
+	 * </ul>
+	 *
+	 * @since 3.0
+	 */
+	public void textSelectionChanged () {
+		checkWidget ();
+		if (accessibleObject !is null) {
+			accessibleObject.textSelectionChanged ();
+		}
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwt/accessibility/AccessibleAdapter.d	Fri Jan 11 05:07:22 2008 +0100
@@ -0,0 +1,130 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+module dwt.accessibility.AccessibleAdapter;
+
+import dwt.accessibility.AccessibleListener;
+import dwt.accessibility.AccessibleEvent;
+
+/**
+ * This adapter class provides default implementations for the
+ * methods described by the <code>AccessibleListener</code> interface.
+ * <p>
+ * Classes that wish to deal with <code>AccessibleEvent</code>s can
+ * extend this class and override only the methods that they are
+ * interested in.
+ * </p><p>
+ * Note: Accessibility clients use child identifiers to specify
+ * whether they want information about a control or one of its children.
+ * Child identifiers are increasing integers beginning with 0.
+ * The identifier CHILDID_SELF represents the control itself.
+ * </p>
+ *
+ * @see AccessibleListener
+ * @see AccessibleEvent
+ *
+ * @since 2.0
+ */
+public abstract class AccessibleAdapter : AccessibleListener {
+
+	/**
+	 * Sent when an accessibility client requests the name
+	 * of the control, or the name of a child of the control.
+	 * The default behavior is to do nothing.
+	 * <p>
+	 * Return the name of the control or specified child in the
+	 * <code>result</code> field of the event object. Returning
+	 * an empty string tells the client that the control or child
+	 * does not have a name, and returning null tells the client
+	 * to use the platform name.
+	 * </p>
+	 *
+	 * @param e an event object containing the following fields:<ul>
+	 *    <li>childID [IN] - an identifier specifying the control or one of its children</li>
+	 *    <li>result [OUT] - the requested name string, or null</li>
+	 * </ul>
+	 */
+	public void getName(AccessibleEvent e) {
+	}
+
+	/**
+	 * Sent when an accessibility client requests the help string
+	 * of the control, or the help string of a child of the control.
+	 * The default behavior is to do nothing.
+	 * <p>
+	 * The information in this property should be similar to the help
+	 * provided by toolTipText. It describes what the control or child
+	 * does or how to use it, as opposed to getDescription, which
+	 * describes appearance.
+	 * </p><p>
+	 * Return the help string of the control or specified child in
+	 * the <code>result</code> field of the event object. Returning
+	 * an empty string tells the client that the control or child
+	 * does not have a help string, and returning null tells the
+	 * client to use the platform help string.
+	 * </p>
+	 *
+	 * @param e an event object containing the following fields:<ul>
+	 *    <li>childID [IN] - an identifier specifying the control or one of its children</li>
+	 *    <li>result [OUT] - the requested help string, or null</li>
+	 * </ul>
+	 */
+	public void getHelp(AccessibleEvent e) {
+	}
+
+	/**
+	 * Sent when an accessibility client requests the keyboard shortcut
+	 * of the control, or the keyboard shortcut of a child of the control.
+	 * The default behavior is to do nothing.
+	 * <p>
+	 * A keyboard shortcut can either be a mnemonic, or an accelerator.
+	 * As a general rule, if the control or child can receive keyboard focus,
+	 * then you should expose its mnemonic, and if it cannot receive keyboard
+	 * focus, then you should expose its accelerator.
+	 * </p><p>
+	 * Return the keyboard shortcut string of the control or specified child
+	 * in the <code>result</code> field of the event object. Returning an
+	 * empty string tells the client that the control or child does not
+	 * have a keyboard shortcut string, and returning null tells the client
+	 * to use the platform keyboard shortcut string.
+	 * </p>
+	 *
+	 * @param e an event object containing the following fields:<ul>
+	 *    <li>childID [IN] - an identifier specifying the control or one of its children</li>
+	 *    <li>result [OUT] - the requested keyboard shortcut string (example: "ALT+N"), or null</li>
+	 * </ul>
+	 */
+	public void getKeyboardShortcut(AccessibleEvent e) {
+	}
+
+	/**
+	 * Sent when an accessibility client requests a description
+	 * of the control, or a description of a child of the control.
+	 * The default behavior is to do nothing.
+	 * <p>
+	 * This is a textual description of the control or child's visual
+	 * appearance, which is typically only necessary if it cannot be
+	 * determined from other properties such as role.
+	 * </p><p>
+	 * Return the description of the control or specified child in
+	 * the <code>result</code> field of the event object. Returning
+	 * an empty string tells the client that the control or child
+	 * does not have a description, and returning null tells the
+	 * client to use the platform description.
+	 * </p>
+	 *
+	 * @param e an event object containing the following fields:<ul>
+	 *    <li>childID [IN] - an identifier specifying the control or one of its children</li>
+	 *    <li>result [OUT] - the requested description string, or null</li>
+	 * </ul>
+	 */
+	public void getDescription(AccessibleEvent e) {
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwt/accessibility/AccessibleControlAdapter.d	Fri Jan 11 05:07:22 2008 +0100
@@ -0,0 +1,253 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+module dwt.accessibility.AccessibleControlAdapter;
+
+import dwt.accessibility.AccessibleControlListener;
+import dwt.accessibility.AccessibleControlEvent;
+
+/**
+ * This adapter class provides default implementations for the
+ * methods described by the <code>AccessibleControlListener</code> interface.
+ * <p>
+ * Classes that wish to deal with <code>AccessibleControlEvent</code>s can
+ * extend this class and override only the methods that they are
+ * interested in.
+ * </p><p>
+ * Note: Accessibility clients use child identifiers to specify
+ * whether they want information about a control or one of its children.
+ * Child identifiers are increasing integers beginning with 0.
+ * The identifier CHILDID_SELF represents the control itself.
+ * When returning a child identifier to a client, you may use CHILDID_NONE
+ * to indicate that no child or control has the required information.
+ * </p><p>
+ * Note: This adapter is typically used by implementors of
+ * a custom control to provide very detailed information about
+ * the control instance to accessibility clients.
+ * </p>
+ *
+ * @see AccessibleControlListener
+ * @see AccessibleControlEvent
+ *
+ * @since 2.0
+ */
+public abstract class AccessibleControlAdapter : AccessibleControlListener {
+
+	/**
+	 * Sent when an accessibility client requests the identifier
+	 * of the control child at the specified display coordinates.
+	 * The default behavior is to do nothing.
+	 * <p>
+	 * Return the identifier of the child at display point (x, y)
+	 * in the <code>childID</code> field of the event object.
+	 * Return CHILDID_SELF if point (x, y) is in the control itself
+	 * and not in any child. Return CHILDID_NONE if point (x, y)
+	 * is not contained in either the control or any of its children.
+	 * </p>
+	 *
+	 * @param e an event object containing the following fields:<ul>
+	 *    <li>x, y [IN] - the specified point in display coordinates</li>
+	 *    <li>childID [Typical OUT] - the ID of the child at point, or CHILDID_SELF, or CHILDID_NONE</li>
+	 *    <li>accessible [Optional OUT] - the accessible object for the control or child may be returned instead of the childID</li>
+	 * </ul>
+	 */
+	public void getChildAtPoint(AccessibleControlEvent e) {
+	}
+
+	/**
+	 * Sent when an accessibility client requests the location
+	 * of the control, or the location of a child of the control.
+	 * The default behavior is to do nothing.
+	 * <p>
+	 * Return a rectangle describing the location of the specified
+	 * control or child in the <code>x, y, width, and height</code>
+	 * fields of the event object.
+	 * </p>
+	 *
+	 * @param e an event object containing the following fields:<ul>
+	 *    <li>childID [IN] - an identifier specifying the control or one of its children</li>
+	 *    <li>x, y, width, height [OUT] - the control or child location in display coordinates</li>
+	 * </ul>
+	 */
+	public void getLocation(AccessibleControlEvent e) {
+	}
+
+	/**
+	 * Sent when an accessibility client requests the accessible object
+	 * for a child of the control.
+	 * The default behavior is to do nothing.
+	 * <p>
+	 * Return an <code>Accessible</code> for the specified control or
+	 * child in the <code>accessible</code> field of the event object.
+	 * Return null if the specified child does not have its own
+	 * <code>Accessible</code>.
+	 * </p>
+	 *
+	 * @param e an event object containing the following fields:<ul>
+	 *    <li>childID [IN] - an identifier specifying a child of the control</li>
+	 *    <li>accessible [OUT] - an Accessible for the specified childID, or null if one does not exist</li>
+	 * </ul>
+	 */
+	public void getChild(AccessibleControlEvent e) {
+	}
+
+	/**
+	 * Sent when an accessibility client requests the number of
+	 * children in the control.
+	 * The default behavior is to do nothing.
+	 * <p>
+	 * Return the number of child items in the <code>detail</code>
+	 * field of the event object.
+	 * </p>
+	 *
+	 * @param e an event object containing the following fields:<ul>
+	 *    <li>detail [OUT] - the number of child items in this control</li>
+	 * </ul>
+	 */
+	public void getChildCount(AccessibleControlEvent e) {
+	}
+
+	/**
+	 * Sent when an accessibility client requests the default action
+	 * of the control, or the default action of a child of the control.
+	 * The default behavior is to do nothing.
+	 * <p>
+	 * This string is typically a verb describing what the user does to it.
+	 * For example, a Push Button's default action is "Press", a Check Button's
+	 * is "Check" or "UnCheck", and List items have the default action "Double Click".
+	 * </p><p>
+	 * Return a string describing the default action of the specified
+	 * control or child in the <code>result</code> field of the event object.
+	 * Returning null tells the client to use the platform default action string.
+	 * </p>
+	 *
+	 * @param e an event object containing the following fields:<ul>
+	 *    <li>childID [IN] - an identifier specifying the control or one of its children</li>
+	 *    <li>result [OUT] - the requested default action string, or null</li>
+	 * </ul>
+	 */
+	public void getDefaultAction(AccessibleControlEvent e) {
+	}
+
+	/**
+	 * Sent when an accessibility client requests the identity of
+	 * the child or control that has keyboard focus.
+	 * The default behavior is to do nothing.
+	 * <p>
+	 * Return the identifier of the child that has focus in the
+	 * <code>childID</code> field of the event object.
+	 * Return CHILDID_SELF if the control itself has keyboard focus.
+	 * Return CHILDID_NONE if neither the control nor any of its children has focus.
+	 * </p>
+	 *
+	 * @param e an event object containing the following fields:<ul>
+	 *    <li>childID [Typical OUT] - the ID of the child with focus, or CHILDID_SELF, or CHILDID_NONE</li>
+	 *    <li>accessible [Optional OUT] - the accessible object for a child may be returned instead of its childID</li>
+	 * </ul>
+	 */
+	public void getFocus(AccessibleControlEvent e) {
+	}
+
+	/**
+	 * Sent when an accessibility client requests the role
+	 * of the control, or the role of a child of the control.
+	 * The default behavior is to do nothing.
+	 * <p>
+	 * Return a role constant (constant defined in ACC beginning with ROLE_)
+	 * that describes the role of the specified control or child in the
+	 * <code>detail</code> field of the event object.
+	 * </p>
+	 *
+	 * @param e an event object containing the following fields:<ul>
+	 *    <li>childID [IN] - an identifier specifying the control or one of its children</li>
+	 *    <li>detail [OUT] - a role constant describing the role of the control or child</li>
+	 * </ul>
+	 */
+	public void getRole(AccessibleControlEvent e) {
+	}
+
+	/**
+	 * Sent when an accessibility client requests the identity of
+	 * the child or control that is currently selected.
+	 * The default behavior is to do nothing.
+	 * <p>
+	 * Return the identifier of the selected child in the
+	 * <code>childID</code> field of the event object.
+	 * Return CHILDID_SELF if the control itself is selected.
+	 * Return CHILDID_MULTIPLE if multiple children are selected, and return an array of childIDs in the <code>children</code> field.
+	 * Return CHILDID_NONE if neither the control nor any of its children are selected.
+	 * </p>
+	 *
+	 * @param e an event object containing the following fields:<ul>
+	 *    <li>childID [Typical OUT] - the ID of the selected child, or CHILDID_SELF, or CHILDID_MULTIPLE, or CHILDID_NONE</li>
+	 *    <li>accessible [Optional OUT] - the accessible object for the control or child may be returned instead of the childID</li>
+	 * </ul>
+	 */
+	public void getSelection(AccessibleControlEvent e) {
+	}
+
+	/**
+	 * Sent when an accessibility client requests the state
+	 * of the control, or the state of a child of the control.
+	 * The default behavior is to do nothing.
+	 * <p>
+	 * Return a state mask (mask bit constants defined in ACC beginning with STATE_)
+	 * that describes the current state of the specified control or child in the
+	 * <code>detail</code> field of the event object.
+	 * </p>
+	 *
+	 * @param e an event object containing the following fields:<ul>
+	 *    <li>childID [IN] - an identifier specifying the control or one of its children</li>
+	 *    <li>detail [OUT] - a state mask describing the current state of the control or child</li>
+	 * </ul>
+	 */
+	public void getState(AccessibleControlEvent e) {
+	}
+
+	/**
+	 * Sent when an accessibility client requests the value
+	 * of the control, or the value of a child of the control.
+	 * The default behavior is to do nothing.
+	 * <p>
+	 * Many controls do not return a value. Examples of controls
+	 * that do are: Combo returns the text string, Text returns
+	 * its contents, ProgressBar returns a string representing a
+	 * percentage, and Tree items return a string representing
+	 * their level in the tree.
+	 * </p><p>
+	 * Return a string describing the value of the specified control
+	 * or child in the <code>result</code> field of the event object.
+	 * Returning null tells the client to use the platform value string.
+	 * </p>
+	 *
+	 * @param e an event object containing the following fields:<ul>
+	 *    <li>childID [IN] - an identifier specifying the control or one of its children</li>
+	 *    <li>result [OUT] - the requested value string, or null</li>
+	 * </ul>
+	 */
+	public void getValue(AccessibleControlEvent e) {
+	}
+
+	/**
+	 * Sent when an accessibility client requests the children of the control.
+	 * The default behavior is to do nothing.
+	 * <p>
+	 * Return the children as an array of childIDs in the <code>children</code>
+	 * field of the event object.
+	 * </p>
+	 *
+	 * @param e an event object containing the following fields:<ul>
+	 *    <li>children [Typical OUT] - an array of childIDs</li>
+	 *    <li>accessible [Optional OUT] - an array of accessible objects for the children may be returned instead of the childIDs</li>
+	 * </ul>
+	 */
+	public void getChildren(AccessibleControlEvent e) {
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwt/accessibility/AccessibleControlEvent.d	Fri Jan 11 05:07:22 2008 +0100
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+module dwt.accessibility.AccessibleControlEvent;
+
+import dwt.accessibility.Accessible;
+
+import dwt.internal.SWTEventObject;
+import tango.text.convert.Format;
+
+/**
+ * Instances of this class are sent as a result of
+ * accessibility clients sending messages to controls
+ * asking for detailed information about the implementation
+ * of the control instance. Typically, only implementors
+ * of custom controls need to listen for this event.
+ * <p>
+ * Note: The meaning of each field depends on the
+ * message that was sent.
+ * </p>
+ *
+ * @see AccessibleControlListener
+ * @see AccessibleControlAdapter
+ *
+ * @since 2.0
+ */
+public class AccessibleControlEvent : SWTEventObject {
+	public int childID;			// IN/OUT
+	public Accessible accessible;	// OUT
+	public int x, y;				// IN/OUT
+	public int width, height;		// OUT
+	public int detail;			// IN/OUT
+	public char[] result;			// OUT
+	public Object children[];		// [OUT]
+
+	//static final long serialVersionUID = 3257281444169529141L;
+
+/**
+ * Constructs a new instance of this class.
+ *
+ * @param source the object that fired the event
+ */
+public this(Object source) {
+	super(source);
+}
+
+/**
+ * Returns a string containing a concise, human-readable
+ * description of the receiver.
+ *
+ * @return a string representation of the event
+ */
+public char[] toString () {
+	return Format( "AccessibleControlEvent {childID={} accessible={} x={} y={} width={} heigth={} detail={} result={}",
+        childID, accessible, x, y, width, height, detail, result);
+}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwt/accessibility/AccessibleControlListener.d	Fri Jan 11 05:07:22 2008 +0100
@@ -0,0 +1,233 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+module dwt.accessibility.AccessibleControlListener;
+
+import dwt.accessibility.AccessibleControlEvent;
+import dwt.internal.SWTEventListener;
+
+/**
+ * Classes that implement this interface provide methods
+ * that deal with the events that are generated when an
+ * accessibility client sends a message to a control.
+ * <p>
+ * After creating an instance of a class that implements
+ * this interface it can be added to a control using the
+ * <code>addAccessibleControlListener</code> method and removed
+ * using the <code>removeAccessibleControlListener</code> method.
+ * When a client requests information the appropriate method
+ * will be invoked.
+ * </p><p>
+ * Note: Accessibility clients use child identifiers to specify
+ * whether they want information about a control or one of its children.
+ * Child identifiers are increasing integers beginning with 0.
+ * The identifier CHILDID_SELF represents the control itself.
+ * </p><p>
+ * Note: This interface is typically used by implementors of
+ * a custom control to provide very detailed information about
+ * the control instance to accessibility clients.
+ * </p>
+ *
+ * @see AccessibleControlAdapter
+ * @see AccessibleControlEvent
+ *
+ * @since 2.0
+ */
+public interface AccessibleControlListener : SWTEventListener {
+
+	/**
+	 * Sent when an accessibility client requests the identifier
+	 * of the control child at the specified display coordinates.
+	 * <p>
+	 * Return the identifier of the child at display point (x, y)
+	 * in the <code>childID</code> field of the event object.
+	 * Return CHILDID_SELF if point (x, y) is in the control itself
+	 * and not in any child. Return CHILDID_NONE if point (x, y)
+	 * is not contained in either the control or any of its children.
+	 * </p>
+	 *
+	 * @param e an event object containing the following fields:<ul>
+	 *    <li>x, y [IN] - the specified point in display coordinates</li>
+	 *    <li>childID [Typical OUT] - the ID of the child at point, or CHILDID_SELF, or CHILDID_NONE</li>
+	 *    <li>accessible [Optional OUT] - the accessible object for the control or child may be returned instead of the childID</li>
+	 * </ul>
+	 */
+	public void getChildAtPoint(AccessibleControlEvent e);
+
+	/**
+	 * Sent when an accessibility client requests the location
+	 * of the control, or the location of a child of the control.
+	 * <p>
+	 * Return a rectangle describing the location of the specified
+	 * control or child in the <code>x, y, width, and height</code>
+	 * fields of the event object.
+	 * </p>
+	 *
+	 * @param e an event object containing the following fields:<ul>
+	 *    <li>childID [IN] - an identifier specifying the control or one of its children</li>
+	 *    <li>x, y, width, height [OUT] - the control or child location in display coordinates</li>
+	 * </ul>
+	 */
+	public void getLocation(AccessibleControlEvent e);
+
+	/**
+	 * Sent when an accessibility client requests the accessible object
+	 * for a child of the control.
+	 * <p>
+	 * Return an <code>Accessible</code> for the specified control or
+	 * child in the <code>accessible</code> field of the event object.
+	 * Return null if the specified child does not have its own
+	 * <code>Accessible</code>.
+	 * </p>
+	 *
+	 * @param e an event object containing the following fields:<ul>
+	 *    <li>childID [IN] - an identifier specifying a child of the control</li>
+	 *    <li>accessible [OUT] - an Accessible for the specified childID, or null if one does not exist</li>
+	 * </ul>
+	 */
+	public void getChild(AccessibleControlEvent e);
+
+	/**
+	 * Sent when an accessibility client requests the number of
+	 * children in the control.
+	 * <p>
+	 * Return the number of child items in the <code>detail</code>
+	 * field of the event object.
+	 * </p>
+	 *
+	 * @param e an event object containing the following fields:<ul>
+	 *    <li>detail [OUT] - the number of child items in this control</li>
+	 * </ul>
+	 */
+	public void getChildCount(AccessibleControlEvent e);
+
+	/**
+	 * Sent when an accessibility client requests the default action
+	 * of the control, or the default action of a child of the control.
+	 * <p>
+	 * This string is typically a verb describing what the user does to it.
+	 * For example, a Push Button's default action is "Press", a Check Button's
+	 * is "Check" or "UnCheck", and List items have the default action "Double Click".
+	 * </p><p>
+	 * Return a string describing the default action of the specified
+	 * control or child in the <code>result</code> field of the event object.
+	 * Returning null tells the client to use the platform default action string.
+	 * </p>
+	 *
+	 * @param e an event object containing the following fields:<ul>
+	 *    <li>childID [IN] - an identifier specifying the control or one of its children</li>
+	 *    <li>result [OUT] - the requested default action string, or null</li>
+	 * </ul>
+	 */
+	public void getDefaultAction(AccessibleControlEvent e);
+
+	/**
+	 * Sent when an accessibility client requests the identity of
+	 * the child or control that has keyboard focus.
+	 * <p>
+	 * Return the identifier of the child that has focus in the
+	 * <code>childID</code> field of the event object.
+	 * Return CHILDID_SELF if the control itself has keyboard focus.
+	 * Return CHILDID_NONE if neither the control nor any of its children has focus.
+	 * </p>
+	 *
+	 * @param e an event object containing the following fields:<ul>
+	 *    <li>childID [Typical OUT] - the ID of the child with focus, or CHILDID_SELF, or CHILDID_NONE</li>
+	 *    <li>accessible [Optional OUT] - the accessible object for a child may be returned instead of its childID</li>
+	 * </ul>
+	 */
+	public void getFocus(AccessibleControlEvent e);
+
+	/**
+	 * Sent when an accessibility client requests the role
+	 * of the control, or the role of a child of the control.
+	 * <p>
+	 * Return a role constant (constant defined in ACC beginning with ROLE_)
+	 * that describes the role of the specified control or child in the
+	 * <code>detail</code> field of the event object.
+	 * </p>
+	 *
+	 * @param e an event object containing the following fields:<ul>
+	 *    <li>childID [IN] - an identifier specifying the control or one of its children</li>
+	 *    <li>detail [OUT] - a role constant describing the role of the control or child</li>
+	 * </ul>
+	 */
+	public void getRole(AccessibleControlEvent e);
+
+	/**
+	 * Sent when an accessibility client requests the identity of
+	 * the child or control that is currently selected.
+	 * <p>
+	 * Return the identifier of the selected child in the
+	 * <code>childID</code> field of the event object.
+	 * Return CHILDID_SELF if the control itself is selected.
+	 * Return CHILDID_MULTIPLE if multiple children are selected, and return an array of childIDs in the <code>children</code> field.
+	 * Return CHILDID_NONE if neither the control nor any of its children are selected.
+	 * </p>
+	 *
+	 * @param e an event object containing the following fields:<ul>
+	 *    <li>childID [Typical OUT] - the ID of the selected child, or CHILDID_SELF, or CHILDID_MULTIPLE, or CHILDID_NONE</li>
+	 *    <li>accessible [Optional OUT] - the accessible object for the control or child may be returned instead of the childID</li>
+	 * </ul>
+	 */
+	public void getSelection(AccessibleControlEvent e);
+
+	/**
+	 * Sent when an accessibility client requests the state
+	 * of the control, or the state of a child of the control.
+	 * <p>
+	 * Return a state mask (mask bit constants defined in ACC beginning with STATE_)
+	 * that describes the current state of the specified control or child in the
+	 * <code>detail</code> field of the event object.
+	 * </p>
+	 *
+	 * @param e an event object containing the following fields:<ul>
+	 *    <li>childID [IN] - an identifier specifying the control or one of its children</li>
+	 *    <li>detail [OUT] - a state mask describing the current state of the control or child</li>
+	 * </ul>
+	 */
+	public void getState(AccessibleControlEvent e);
+
+	/**
+	 * Sent when an accessibility client requests the value
+	 * of the control, or the value of a child of the control.
+	 * <p>
+	 * Many controls do not return a value. Examples of controls
+	 * that do are: Combo returns the text string, Text returns
+	 * its contents, ProgressBar returns a string representing a
+	 * percentage, and Tree items return a string representing
+	 * their level in the tree.
+	 * </p><p>
+	 * Return a string describing the value of the specified control
+	 * or child in the <code>result</code> field of the event object.
+	 * Returning null tells the client to use the platform value string.
+	 * </p>
+	 *
+	 * @param e an event object containing the following fields:<ul>
+	 *    <li>childID [IN] - an identifier specifying the control or one of its children</li>
+	 *    <li>result [OUT] - the requested value string, or null</li>
+	 * </ul>
+	 */
+	public void getValue(AccessibleControlEvent e);
+
+	/**
+	 * Sent when an accessibility client requests the children of the control.
+	 * <p>
+	 * Return the children as an array of childIDs in the <code>children</code>
+	 * field of the event object.
+	 * </p>
+	 *
+	 * @param e an event object containing the following fields:<ul>
+	 *    <li>children [Typical OUT] - an array of childIDs</li>
+	 *    <li>children [Optional OUT] - an array of accessible objects for the children may be returned instead of the childIDs</li>
+	 * </ul>
+	 */
+	public void getChildren(AccessibleControlEvent e);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwt/accessibility/AccessibleEvent.d	Fri Jan 11 05:07:22 2008 +0100
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+module dwt.accessibility.AccessibleEvent;
+
+
+import dwt.internal.SWTEventObject;
+import tango.text.convert.Format;
+
+/**
+ * Instances of this class are sent as a result of
+ * accessibility clients sending messages to controls
+ * asking for information about the control instance.
+ * <p>
+ * Note: The meaning of the result field depends
+ * on the message that was sent.
+ * </p>
+ *
+ * @see AccessibleListener
+ * @see AccessibleAdapter
+ *
+ * @since 2.0
+ */
+public class AccessibleEvent : SWTEventObject {
+	/**
+	 * The value of this field is set by an accessibility client
+	 * before the accessible listener method is called.
+	 * ChildID can be CHILDID_SELF, representing the control itself,
+	 * or a 0-based integer representing a specific child of the control.
+	 */
+	public int childID;
+
+	/**
+	 * The value of this field must be set in the accessible listener
+	 * method before returning.
+	 * What to set it to depends on the listener method called, and
+	 * the childID specified by the client.
+	 */
+	public char[] result;
+
+	//static final long serialVersionUID = 3257567304224026934L;
+
+/**
+ * Constructs a new instance of this class.
+ *
+ * @param source the object that fired the event
+ */
+public this(Object source) {
+	super(source);
+}
+
+/**
+ * Returns a string containing a concise, human-readable
+ * description of the receiver.
+ *
+ * @return a string representation of the event
+ */
+public char[] toString () {
+	return Format( "AccessibleEvent {childID={} result={}}", childID, result );
+}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwt/accessibility/AccessibleFactory.d	Fri Jan 11 05:07:22 2008 +0100
@@ -0,0 +1,301 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+module dwt.accessibility.AccessibleFactory;
+
+
+import dwt.internal.accessibility.gtk.ATK;
+import dwt.internal.gtk.OS;
+import dwt.accessibility.Accessible;
+import dwt.accessibility.ACC;
+import dwt.accessibility.AccessibleObject;
+import dwt.accessibility.AccessibleControlEvent;
+import dwt.accessibility.AccessibleControlListener;
+
+import dwt.SWT;
+
+import tango.stdc.stringz;
+import tango.io.Stdout;
+
+class AccessibleFactory {
+	AtkObjectFactory * handle;
+	uint objectParentType;
+	char* widgetTypeName;
+
+	//Callback atkObjectFactoryCB_create_accessible;
+	//Callback gTypeInfo_base_init_factory;
+	Accessible[GtkWidget*] accessibles;
+
+	static long[char[]] Types;
+	static AccessibleFactory[long] Factories;
+
+    static const uint DefaultParentType; //$NON-NLS-1$
+	static const char[] FACTORY_PARENTTYPENAME = "AtkObjectFactory";
+	static const char[] SWT_TYPE_PREFIX = "SWT";
+	static const char[] CHILD_TYPENAME = "Child";
+	static const char[] FACTORY_TYPENAME = "SWTFactory";
+	static const int[] actionRoles = [
+		ACC.ROLE_CHECKBUTTON, ACC.ROLE_COMBOBOX, ACC.ROLE_LINK,
+		ACC.ROLE_MENUITEM, ACC.ROLE_PUSHBUTTON, ACC.ROLE_RADIOBUTTON,
+	];
+	static const int[] hypertextRoles = [ACC.ROLE_LINK];
+	static const int[] selectionRoles = [
+		ACC.ROLE_LIST, ACC.ROLE_TABFOLDER, ACC.ROLE_TABLE, ACC.ROLE_TREE,
+	];
+	static const int[] textRoles = [
+		ACC.ROLE_COMBOBOX, ACC.ROLE_LINK, ACC.ROLE_LABEL, ACC.ROLE_TEXT,
+	];
+
+	/* AT callbacks*/
+	/* interface definitions */
+	static GTypeInfo* ObjectIfaceDefinition;
+	static const GInterfaceInfo* ActionIfaceDefinition;
+	static const GInterfaceInfo* ComponentIfaceDefinition;
+	static const GInterfaceInfo* HypertextIfaceDefinition;
+	static const GInterfaceInfo* SelectionIfaceDefinition;
+	static const GInterfaceInfo* TextIfaceDefinition;
+
+    static this(){
+        DefaultParentType = OS.g_type_from_name ("GtkAccessible"); //$NON-NLS-1$
+		/* Action interface */
+		ActionIfaceDefinition = cast(GInterfaceInfo*)OS.g_malloc (GInterfaceInfo.sizeof);
+        ActionIfaceDefinition.interface_init = &AccessibleFactory.initActionIfaceCB;
+		/* Component interface */
+		ComponentIfaceDefinition = cast(GInterfaceInfo*)OS.g_malloc (GInterfaceInfo.sizeof);
+        ComponentIfaceDefinition.interface_init = &AccessibleFactory.initComponentIfaceCB;
+		/* Hypertext interface */
+		HypertextIfaceDefinition = cast(GInterfaceInfo*)OS.g_malloc (GInterfaceInfo.sizeof);
+        HypertextIfaceDefinition.interface_init = &AccessibleFactory.initHypertextIfaceCB;
+		/* Selection interface */
+		SelectionIfaceDefinition = cast(GInterfaceInfo*)OS.g_malloc (GInterfaceInfo.sizeof);
+        SelectionIfaceDefinition.interface_init = &AccessibleFactory.initSelectionIfaceCB;
+		/* Text interface */
+		TextIfaceDefinition =cast(GInterfaceInfo*) OS.g_malloc (GInterfaceInfo.sizeof);
+        TextIfaceDefinition.interface_init = &AccessibleFactory.initTextIfaceCB;
+	}
+
+	private this (int /*long*/ widgetType) {
+		widgetTypeName = OS.g_type_name (widgetType);
+		char[] factoryName = FACTORY_TYPENAME ~ fromUtf8z( widgetTypeName ) ~ \0;
+		if (OS.g_type_from_name (factoryName.ptr) is 0) {
+			/* register the factory */
+			auto registry = ATK.atk_get_default_registry ();
+			auto previousFactory = ATK.atk_registry_get_factory (registry, widgetType);
+			objectParentType = ATK.atk_object_factory_get_accessible_type (previousFactory);
+			if (objectParentType is 0) objectParentType = DefaultParentType;
+			auto factoryParentType = OS.g_type_from_name (FACTORY_PARENTTYPENAME.ptr);
+            auto typeInfo = cast(GTypeInfo*) OS.g_malloc (GTypeInfo.sizeof);
+            typeInfo.base_init = &gTypeInfo_base_init_factory;
+			typeInfo.class_size = AtkObjectFactoryClass.sizeof;
+			typeInfo.instance_size = AtkObjectFactory.sizeof;
+			auto swtFactoryType = OS.g_type_register_static (factoryParentType, factoryName.ptr, typeInfo, 0);
+			ATK.atk_registry_set_factory_type (registry, widgetType, swtFactoryType);
+			handle = ATK.atk_registry_get_factory (registry, widgetType);
+		}
+	}
+
+	void addAccessible (Accessible accessible) {
+		auto controlHandle = accessible.getControlHandle ();
+		accessibles[controlHandle] = accessible;
+		ATK.atk_object_factory_create_accessible (handle, cast(GObject*)controlHandle);
+	}
+
+	private static extern(C) AtkObject* atkObjectFactory_create_accessible (GObject* widget) {
+        auto widgetType = OS.G_OBJECT_TYPE ( cast(GTypeInstance*)widget);
+        if( auto factory = widgetType in Factories ){
+            with( *factory ){
+                Accessible accessible = accessibles[ cast(GtkWidget*) widget ];
+                if (accessible is null) {
+                    /*
+                    * we don't care about this control, so create it with the parent's
+                    * type so that its accessibility callbacks will not pass though here
+                    */
+                    auto result = cast(AtkObject*) OS.g_object_new (objectParentType, null);
+                    ATK.atk_object_initialize (result, cast(void*)widget);
+                    return result;
+                }
+                /* if an atk object has already been created for this widget then just return it */
+                if (accessible.accessibleObject !is null) {
+                    return accessible.accessibleObject.handle;
+                }
+                char[] buffer = fromUtf8z( widgetTypeName ).dup;
+                auto type = getType (buffer, accessible, objectParentType, ACC.CHILDID_SELF);
+                AccessibleObject object = new AccessibleObject (type, cast(GtkWidget*)widget, accessible, objectParentType, false);
+                accessible.accessibleObject = object;
+                return object.handle;
+            }
+        }
+        else{
+            Stdout.formatln( "AccessibleFactory.atkObjectFactoryCB_create_accessible cannot find factory instance" );
+        }
+	}
+
+	static int /*long*/ getChildType (Accessible accessible, int childIndex) {
+		return getType (CHILD_TYPENAME, accessible, DefaultParentType, childIndex);
+	}
+
+	static int /*long*/ getDefaultParentType () {
+		return DefaultParentType;
+	}
+
+	static int /*long*/ getType (char[] widgetTypeName, Accessible accessible, int /*long*/ parentType, int childId) {
+		AccessibleControlEvent event = new AccessibleControlEvent (accessible);
+		event.childID = childId;
+		AccessibleControlListener[] listeners = accessible.getControlListeners ();
+		for (int i = 0; i < listeners.length; i++) {
+			listeners [i].getRole (event);
+		}
+		bool action = false, hypertext = false, selection = false, text = false;
+		if (event.detail !is 0) {	/* a role was specified */
+			for (int i = 0; i < actionRoles.length; i++) {
+				if (event.detail is actionRoles [i]) {
+					action = true;
+					break;
+				}
+			}
+			for (int i = 0; i < hypertextRoles.length; i++) {
+				if (event.detail is hypertextRoles [i]) {
+					hypertext = true;
+					break;
+				}
+			}
+			for (int i = 0; i < selectionRoles.length; i++) {
+				if (event.detail is selectionRoles [i]) {
+					selection = true;
+					break;
+				}
+			}
+			for (int i = 0; i < textRoles.length; i++) {
+				if (event.detail is textRoles [i]) {
+					text = true;
+					break;
+				}
+			}
+		} else {
+			action = hypertext = selection = text = true;
+		}
+		char[] swtTypeName = SWT_TYPE_PREFIX.dup;
+		swtTypeName ~= widgetTypeName;
+		if (action) swtTypeName ~= "Action"; //$NON-NLS-1$
+		if (hypertext) swtTypeName ~= "Hypertext"; //$NON-NLS-1$
+		if (selection) swtTypeName ~= "Selection"; //$NON-NLS-1$
+		if (text) swtTypeName ~= "Text"; //$NON-NLS-1$
+
+		int /*long*/ type = 0;
+        if (swtTypeName in Types ) {
+			type = Types[swtTypeName];
+		} else {
+			/* define the type */
+            GTypeQuery* query = new GTypeQuery ();
+			OS.g_type_query (parentType, query);
+
+            GTypeInfo* typeInfo = new GTypeInfo ();
+			typeInfo.base_init = &gTypeInfo_base_init_type;
+			typeInfo.class_size = query.class_size;
+			typeInfo.instance_size = query.instance_size;
+			ObjectIfaceDefinition = typeInfo;
+
+			type = OS.g_type_register_static (parentType, toStringz( swtTypeName ), ObjectIfaceDefinition, 0);
+			OS.g_type_add_interface_static (type, AccessibleObject.ATK_COMPONENT_TYPE, ComponentIfaceDefinition);
+			if (action) OS.g_type_add_interface_static (type, AccessibleObject.ATK_ACTION_TYPE, ActionIfaceDefinition);
+			if (hypertext) OS.g_type_add_interface_static (type, AccessibleObject.ATK_HYPERTEXT_TYPE, HypertextIfaceDefinition);
+			if (selection) OS.g_type_add_interface_static (type, AccessibleObject.ATK_SELECTION_TYPE, SelectionIfaceDefinition);
+			if (text) OS.g_type_add_interface_static (type, AccessibleObject.ATK_TEXT_TYPE, TextIfaceDefinition);
+			Types[swtTypeName] = type;
+		}
+		return type;
+	}
+
+	private static extern(C) void gTypeInfo_base_init_factory (void* klass) {
+		auto atkObjectFactoryClass = ATK.ATK_OBJECT_FACTORY_CLASS (klass);
+		atkObjectFactoryClass.create_accessible = &atkObjectFactory_create_accessible;
+	}
+
+	private static extern(C) void gTypeInfo_base_init_type (void* klass) {
+		auto objectClass = cast(AtkObjectClass*)klass;
+        objectClass.get_name = &AccessibleObject.atkObject_get_name;
+		objectClass.get_description = &AccessibleObject.atkObject_get_description;
+		objectClass.get_n_children = &AccessibleObject.atkObject_get_n_children;
+		objectClass.get_role = &AccessibleObject.atkObject_get_role;
+		objectClass.get_parent = &AccessibleObject.atkObject_get_parent;
+		objectClass.ref_state_set = &AccessibleObject.atkObject_ref_state_set;
+		objectClass.get_index_in_parent = &AccessibleObject.atkObject_get_index_in_parent;
+		objectClass.ref_child = &AccessibleObject.atkObject_ref_child;
+
+        GObjectClass* gObjectClass = OS.G_OBJECT_CLASS ( cast(GTypeClass*)klass);
+		gObjectClass.finalize = &AccessibleObject.gObjectClass_finalize;
+	}
+
+	private static extern(C) void initActionIfaceCB ( void* g_iface, void* iface_data ) {
+        auto iface = cast(AtkActionIface*)g_iface;
+		iface.get_keybinding =  &AccessibleObject.atkAction_get_keybinding;
+		iface.get_name =  &AccessibleObject.atkAction_get_name;
+	}
+
+	private static extern(C) void initComponentIfaceCB ( void* g_iface, void* iface_data ) {
+        auto iface = cast(AtkComponentIface*)g_iface;
+		iface.get_extents = &AccessibleObject.atkComponent_get_extents;
+		iface.get_position = &AccessibleObject.atkComponent_get_position;
+		iface.get_size = &AccessibleObject.atkComponent_get_size;
+		iface.ref_accessible_at_point = &AccessibleObject.atkComponent_ref_accessible_at_point;
+	}
+
+	private static extern(C) void initHypertextIfaceCB ( void* g_iface, void* iface_data ) {
+        auto iface = cast(AtkHypertextIface*)g_iface;
+		iface.get_link = &AccessibleObject.atkHypertext_get_link;
+		iface.get_link_index = &AccessibleObject.atkHypertext_get_link_index;
+		iface.get_n_links = &AccessibleObject.atkHypertext_get_n_links;
+	}
+
+	private static extern(C) void initSelectionIfaceCB ( void* g_iface, void* iface_data ) {
+        auto iface = cast(AtkSelectionIface*)g_iface;
+		iface.is_child_selected = &AccessibleObject.atkSelection_is_child_selected;
+		iface.ref_selection = &AccessibleObject.atkSelection_ref_selection;
+	}
+
+	private static extern(C) void initTextIfaceCB ( void* g_iface, void* iface_data ) {
+        auto iface = cast(AtkTextIface*)g_iface;
+		iface.get_caret_offset = &AccessibleObject.atkText_get_caret_offset;
+		iface.get_character_at_offset = &AccessibleObject.atkText_get_character_at_offset;
+		iface.get_character_count = &AccessibleObject.atkText_get_character_count;
+		iface.get_n_selections = &AccessibleObject.atkText_get_n_selections;
+		iface.get_selection = &AccessibleObject.atkText_get_selection;
+		iface.get_text = &AccessibleObject.atkText_get_text;
+		iface.get_text_after_offset = &AccessibleObject.atkText_get_text_after_offset;
+		iface.get_text_at_offset = &AccessibleObject.atkText_get_text_at_offset;
+		iface.get_text_before_offset = &AccessibleObject.atkText_get_text_before_offset;
+	}
+
+	static void registerAccessible (Accessible accessible) {
+		/* If DefaultParentType is 0 then OS accessibility is not active */
+		if (DefaultParentType is 0) return;
+		auto controlHandle = accessible.getControlHandle ();
+		auto widgetType = OS.G_OBJECT_TYPE ( cast(GTypeInstance*)controlHandle);
+		AccessibleFactory factory = Factories[widgetType];
+		if (factory is null) {
+			factory = new AccessibleFactory (widgetType);
+			Factories[widgetType] = factory;
+		}
+		factory.addAccessible (accessible);
+	}
+
+	void removeAccessible (Accessible accessible) {
+		accessibles.remove (accessible.getControlHandle ());
+	}
+
+	static void unregisterAccessible (Accessible accessible) {
+		auto controlHandle = accessible.getControlHandle ();
+		auto widgetType = OS.G_OBJECT_TYPE (cast(GTypeInstance*)controlHandle);
+		AccessibleFactory factory = Factories[widgetType];
+		if (factory !is null) {
+			factory.removeAccessible (accessible);
+		}
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwt/accessibility/AccessibleListener.d	Fri Jan 11 05:07:22 2008 +0100
@@ -0,0 +1,127 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+module dwt.accessibility.AccessibleListener;
+
+
+import dwt.internal.SWTEventListener;
+import dwt.accessibility.AccessibleEvent;
+
+/**
+ * Classes that implement this interface provide methods
+ * that deal with the events that are generated when an
+ * accessibility client sends a message to a control.
+ * <p>
+ * After creating an instance of a class that implements
+ * this interface it can be added to a control using the
+ * <code>addAccessibleListener</code> method and removed
+ * using the <code>removeAccessibleListener</code> method.
+ * When a client requests information, the appropriate method
+ * will be invoked.
+ * </p><p>
+ * Note: Accessibility clients use child identifiers to specify
+ * whether they want information about a control or one of its children.
+ * Child identifiers are increasing integers beginning with 0.
+ * The identifier CHILDID_SELF represents the control itself.
+ * </p>
+ *
+ * @see AccessibleAdapter
+ * @see AccessibleEvent
+ *
+ * @since 2.0
+ */
+public interface AccessibleListener : SWTEventListener {
+
+	/**
+	 * Sent when an accessibility client requests the name
+	 * of the control, or the name of a child of the control.
+	 * <p>
+	 * Return the name of the control or specified child in the
+	 * <code>result</code> field of the event object. Returning
+	 * an empty string tells the client that the control or child
+	 * does not have a name, and returning null tells the client
+	 * to use the platform name.
+	 * </p>
+	 *
+	 * @param e an event object containing the following fields:<ul>
+	 *    <li>childID [IN] - an identifier specifying the control or one of its children</li>
+	 *    <li>result [OUT] - the requested name string, or null</li>
+	 * </ul>
+	 */
+	public void getName(AccessibleEvent e);
+
+	/**
+	 * Sent when an accessibility client requests the help string
+	 * of the control, or the help string of a child of the control.
+	 * <p>
+	 * The information in this property should be similar to the help
+	 * provided by toolTipText. It describes what the control or child
+	 * does or how to use it, as opposed to getDescription, which
+	 * describes appearance.
+	 * </p><p>
+	 * Return the help string of the control or specified child in
+	 * the <code>result</code> field of the event object. Returning
+	 * an empty string tells the client that the control or child
+	 * does not have a help string, and returning null tells the
+	 * client to use the platform help string.
+	 * </p>
+	 *
+	 * @param e an event object containing the following fields:<ul>
+	 *    <li>childID [IN] - an identifier specifying the control or one of its children</li>
+	 *    <li>result [OUT] - the requested help string, or null</li>
+	 * </ul>
+	 */
+	public void getHelp(AccessibleEvent e);
+
+	/**
+	 * Sent when an accessibility client requests the keyboard shortcut
+	 * of the control, or the keyboard shortcut of a child of the control.
+	 * <p>
+	 * A keyboard shortcut can either be a mnemonic, or an accelerator.
+	 * As a general rule, if the control or child can receive keyboard focus,
+	 * then you should expose its mnemonic, and if it cannot receive keyboard
+	 * focus, then you should expose its accelerator.
+	 * </p><p>
+	 * Return the keyboard shortcut string of the control or specified child
+	 * in the <code>result</code> field of the event object. Returning an
+	 * empty string tells the client that the control or child does not
+	 * have a keyboard shortcut string, and returning null tells the client
+	 * to use the platform keyboard shortcut string.
+	 * </p>
+	 *
+	 * @param e an event object containing the following fields:<ul>
+	 *    <li>childID [IN] - an identifier specifying the control or one of its children</li>
+	 *    <li>result [OUT] - the requested keyboard shortcut string (example: "ALT+N"), or null</li>
+	 * </ul>
+	 */
+	public void getKeyboardShortcut(AccessibleEvent e);
+
+	/**
+	 * Sent when an accessibility client requests a description
+	 * of the control, or a description of a child of the control.
+	 * <p>
+	 * This is a textual description of the control or child's visual
+	 * appearance, which is typically only necessary if it cannot be
+	 * determined from other properties such as role.
+	 * </p><p>
+	 * Return the description of the control or specified child in
+	 * the <code>result</code> field of the event object. Returning
+	 * an empty string tells the client that the control or child
+	 * does not have a description, and returning null tells the
+	 * client to use the platform description.
+	 * </p>
+	 *
+	 * @param e an event object containing the following fields:<ul>
+	 *    <li>childID [IN] - an identifier specifying the control or one of its children</li>
+	 *    <li>result [OUT] - the requested description string, or null</li>
+	 * </ul>
+	 */
+	public void getDescription(AccessibleEvent e);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwt/accessibility/AccessibleObject.d	Fri Jan 11 05:07:22 2008 +0100
@@ -0,0 +1,1377 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+module dwt.accessibility.AccessibleObject;
+
+import dwt.internal.accessibility.gtk.ATK;
+import dwt.internal.gtk.OS;
+import dwt.accessibility.Accessible;
+import dwt.accessibility.AccessibleListener;
+import dwt.accessibility.AccessibleControlListener;
+import dwt.accessibility.AccessibleTextListener;
+import dwt.accessibility.AccessibleEvent;
+import dwt.accessibility.AccessibleControlEvent;
+import dwt.accessibility.AccessibleTextEvent;
+import dwt.accessibility.ACC;
+import dwt.accessibility.AccessibleFactory;
+import dwt.widgets.Display;
+import dwt.dwthelper.Integer;
+import tango.io.Stdout;
+import tango.stdc.stringz;
+import tango.text.Util;
+import Math = tango.math.Math;
+
+class AccessibleObject {
+	AtkObject* handle;
+	int /*long*/ parentType;
+	int index = -1, id = ACC.CHILDID_SELF;
+	Accessible accessible;
+	AccessibleObject parent;
+    AccessibleObject[AtkObject*] children;
+	/*
+	* a lightweight object does not correspond to a concrete gtk widget, but
+	* to a logical child of a widget (eg.- a CTabItem, which is simply drawn)
+	*/
+	bool isLightweight = false;
+
+	static char[] actionNamePtr;
+	static char[] descriptionPtr;
+	static char[] keybindingPtr;
+	static char[] namePtr;
+    static AccessibleObject[AtkObject*] AccessibleObjects;
+	static const uint ATK_ACTION_TYPE;
+	static const uint ATK_COMPONENT_TYPE;
+	static const uint ATK_HYPERTEXT_TYPE;
+	static const uint ATK_SELECTION_TYPE;
+	static const uint ATK_TEXT_TYPE;
+	static const bool DEBUG;
+
+    static this(){
+        DEBUG = Display.DEBUG;
+        ATK_ACTION_TYPE = ATK.g_type_from_name ("AtkAction");
+        ATK_COMPONENT_TYPE = ATK.g_type_from_name ("AtkComponent");
+        ATK_HYPERTEXT_TYPE = ATK.g_type_from_name ("AtkHypertext");
+        ATK_SELECTION_TYPE = ATK.g_type_from_name ("AtkSelection");
+        ATK_TEXT_TYPE = ATK.g_type_from_name ("AtkText");
+    }
+
+	this (int /*long*/ type, GtkWidget* widget, Accessible accessible, int /*long*/ parentType, bool isLightweight) {
+		handle = cast(AtkObject*)ATK.g_object_new (type, null);
+		this.parentType = parentType;
+		ATK.atk_object_initialize (handle, widget);
+		this.accessible = accessible;
+		this.isLightweight = isLightweight;
+		AccessibleObjects[handle] = this;
+		if (DEBUG) Stdout.formatln("new AccessibleObject: {}", handle);
+	}
+
+	void addChild (AccessibleObject child) {
+		children[child.handle] = child;
+		child.setParent (this);
+	}
+
+	package static extern(C) char* atkAction_get_keybinding (void* obj, int index) {
+        auto atkObject = cast(AtkObject*)obj;
+		if (DEBUG) Stdout.formatln ("-->atkAction_get_keybinding");
+		AccessibleObject object = getAccessibleObject (atkObject);
+		if (object is null) return null;
+		char* parentResult;
+		if (ATK.g_type_is_a (object.parentType, ATK_ACTION_TYPE)) {
+			auto superType = cast(AtkActionIface*)ATK.g_type_interface_peek_parent (ATK.ATK_ACTION_GET_IFACE (object.handle));
+			AtkActionIface* actionIface = superType;
+			if (actionIface.get_keybinding !is null) {
+				parentResult = actionIface.get_keybinding( object.handle, index );
+			}
+		}
+		AccessibleListener[] listeners = object.getAccessibleListeners ();
+		if (listeners.length is 0) return parentResult;
+
+		AccessibleEvent event = new AccessibleEvent (object);
+		event.childID = object.id;
+		if (parentResult !is null) {
+            char[] res = fromUtf8z( parentResult );
+			event.result = res.dup;
+		}
+		for (int i = 0; i < listeners.length; i++) {
+			listeners [i].getKeyboardShortcut (event);
+		}
+		if (event.result is null) return parentResult;
+		if (keybindingPtr !is null ) OS.g_free (keybindingPtr.ptr);
+		char[] name = event.result.dup ~ \0;
+        char* p = cast(char*) OS.g_malloc (name.length);
+		keybindingPtr =  p ? p[ 0 .. name.length ] : null;
+		return keybindingPtr.ptr;
+	}
+
+	package static extern(C) char* atkAction_get_name (void* obj, int index) {
+        auto atkObject = cast(AtkObject*)obj;
+		if (DEBUG) Stdout.formatln ("-->atkAction_get_name");
+		AccessibleObject object = getAccessibleObject (atkObject);
+		if (object is null) return null;
+		char* parentResult;
+		if (ATK.g_type_is_a (object.parentType, ATK_ACTION_TYPE)) {
+			auto actionIface = cast(AtkActionIface*)ATK.g_type_interface_peek_parent (ATK.ATK_ACTION_GET_IFACE (object.handle));
+			if (actionIface.get_name !is null) {
+				parentResult = actionIface.get_name( object.handle, index);
+			}
+		}
+		AccessibleControlListener[] listeners = object.getControlListeners ();
+		if (listeners.length is 0) return parentResult;
+
+		AccessibleControlEvent event = new AccessibleControlEvent (object);
+		event.childID = object.id;
+		if (parentResult !is null) {
+            char[] res = fromUtf8z( parentResult );
+            event.result = res.dup;
+		}
+		for (int i = 0; i < listeners.length; i++) {
+			listeners [i].getDefaultAction (event);
+		}
+		if (event.result is null) return parentResult;
+		if (actionNamePtr !is null) OS.g_free (actionNamePtr.ptr);
+
+        char[] name = event.result.dup ~ \0;
+        auto p = cast(char*)OS.g_malloc (name.length);
+        actionNamePtr =  p ? p[ 0 .. name.length ] : null;
+        return actionNamePtr.ptr;
+	}
+
+	package static extern(C) void atkComponent_get_extents (void* obj, int* x, int* y, int* width, int* height, int coord_type) {
+        auto atkObject = cast(AtkObject*)obj;
+		if (DEBUG) Stdout.formatln ("-->atkComponent_get_extents");
+		AccessibleObject object = getAccessibleObject (atkObject);
+		if (object is null) return 0;
+        *x = 0;
+        *y = 0;
+        *width = 0;
+        *height = 0;
+		if (ATK.g_type_is_a (object.parentType, ATK_COMPONENT_TYPE)) {
+			auto componentIface = cast(AtkComponentIface*) ATK.g_type_interface_peek_parent (ATK.ATK_COMPONENT_GET_IFACE (object.handle));
+			if (componentIface.get_extents !is null) {
+				componentIface.get_extents( object.handle, x, y, width, height, coord_type);
+			}
+		}
+		AccessibleControlListener[] listeners = object.getControlListeners ();
+		if (listeners.length is 0) return 0;
+
+		int parentX = *x, parentY = *y;
+		int parentWidth = *width, parentHeight = *height;
+		AccessibleControlEvent event = new AccessibleControlEvent (object);
+		event.childID = object.id;
+		event.x = parentX; event.y = parentY;
+		event.width = parentWidth; event.height = parentHeight;
+		if (coord_type is ATK.ATK_XY_WINDOW) {
+			/* translate control -> display, for filling in event to be dispatched */
+			auto gtkAccessible = ATK.GTK_ACCESSIBLE (object.handle);
+			auto topLevel = ATK.gtk_widget_get_toplevel (gtkAccessible.widget);
+			auto window = OS.GTK_WIDGET_WINDOW (topLevel);
+			int topWindowX, topWindowY;
+			OS.gdk_window_get_origin (window, &topWindowX, &topWindowY);
+			event.x += topWindowX;
+			event.y += topWindowY;
+		}
+		for (int i = 0; i < listeners.length; i++) {
+			listeners [i].getLocation (event);
+		}
+		if (coord_type is ATK.ATK_XY_WINDOW) {
+			/* translate display -> control, for answering to the OS */
+			auto gtkAccessible = ATK.GTK_ACCESSIBLE (object.handle);
+			auto topLevel = ATK.gtk_widget_get_toplevel (gtkAccessible.widget);
+			auto window = OS.GTK_WIDGET_WINDOW (topLevel);
+			int topWindowX, topWindowY;
+			OS.gdk_window_get_origin (window, &topWindowX, &topWindowY);
+			event.x -= topWindowX;
+			event.y -= topWindowY;
+		}
+		*x = event.x;
+		*y = event.y;
+		*width = event.width;
+		*height = event.height;
+		//return 0;
+	}
+
+	package static extern(C) void atkComponent_get_position (void* obj, int* x, int* y, int coord_type) {
+        auto atkObject = cast(AtkObject*)obj;
+		if (DEBUG) Stdout.formatln ("-->atkComponent_get_position, object: {} x:{} y:{} coord:{}", atkObject, x, y, coord_type);
+		AccessibleObject object = getAccessibleObject (atkObject);
+		if (object is null) return 0;
+		*x=0;
+		*y=0;
+		if (ATK.g_type_is_a (object.parentType, ATK_COMPONENT_TYPE)) {
+			auto componentIface = cast(AtkComponentIface*)ATK.g_type_interface_peek_parent (ATK.ATK_COMPONENT_GET_IFACE (object.handle));
+			if (componentIface.get_extents !is null) {
+				componentIface.get_position( object.handle, x, y, coord_type);
+			}
+		}
+		AccessibleControlListener[] listeners = object.getControlListeners ();
+		if (listeners.length is 0) return 0;
+
+		int parentX, parentY;
+		parentX = *x;
+		parentY = *y;
+		AccessibleControlEvent event = new AccessibleControlEvent (object);
+		event.childID = object.id;
+		event.x = parentX; event.y = parentY;
+		if (coord_type is ATK.ATK_XY_WINDOW) {
+			/* translate control -> display, for filling in event to be dispatched */
+			auto gtkAccessible = ATK.GTK_ACCESSIBLE (object.handle);
+			auto topLevel = ATK.gtk_widget_get_toplevel (gtkAccessible.widget);
+			auto window = OS.GTK_WIDGET_WINDOW (topLevel);
+			int topWindowX, topWindowY;
+			OS.gdk_window_get_origin (window, &topWindowX, &topWindowY);
+			event.x += topWindowX;
+			event.y += topWindowY;
+		}
+		for (int i = 0; i < listeners.length; i++) {
+			listeners [i].getLocation (event);
+		}
+		if (coord_type is ATK.ATK_XY_WINDOW) {
+			/* translate display -> control, for answering to the OS */
+			auto gtkAccessible = ATK.GTK_ACCESSIBLE (object.handle);
+			auto topLevel = ATK.gtk_widget_get_toplevel (gtkAccessible.widget);
+			auto window = OS.GTK_WIDGET_WINDOW (topLevel);
+            int topWindowX, topWindowY;
+			OS.gdk_window_get_origin (window, &topWindowX, &topWindowY);
+			event.x -= topWindowX;
+			event.y -= topWindowY;
+		}
+		*x=event.x;
+		*y=event.y;
+		//return 0;
+	}
+
+    //PORTING_FIXME: what about the coord_type? componentIface.get_size( object.handle, width, height, coord_type);
+    //package static extern(C) void atkComponent_get_size (void* obj, int* width, int* height, int coord_type) {
+    package static extern(C) void atkComponent_get_size (void* obj, int* width, int* height) {
+        auto atkObject = cast(AtkObject*)obj;
+		if (DEBUG) Stdout.formatln ("-->atkComponent_get_size");
+		AccessibleObject object = getAccessibleObject (atkObject);
+		if (object is null) return 0;
+		*width=0;
+		*height=0;
+		if (ATK.g_type_is_a (object.parentType, ATK_COMPONENT_TYPE)) {
+			auto componentIface = cast(AtkComponentIface*)ATK.g_type_interface_peek_parent (ATK.ATK_COMPONENT_GET_IFACE (object.handle));
+			if (componentIface.get_extents !is null) {
+                //PORTING_FIXME: what about the coord_type? componentIface.get_size( object.handle, width, height, coord_type);
+                componentIface.get_size( object.handle, width, height);
+			}
+		}
+		AccessibleControlListener[] listeners = object.getControlListeners ();
+		if (listeners.length is 0) return 0;
+
+		int parentWidth, parentHeight;
+		parentWidth= *width;
+		parentHeight= *height;
+		AccessibleControlEvent event = new AccessibleControlEvent (object);
+		event.childID = object.id;
+		event.width = parentWidth; event.height = parentHeight;
+		for (int i = 0; i < listeners.length; i++) {
+			listeners [i].getLocation (event);
+		}
+		*width=event.width;
+		*height=event.height;
+		//return 0;
+	}
+
+	package static extern(C) AtkObject* atkComponent_ref_accessible_at_point (void* obj, int x, int y, int coord_type) {
+        auto atkObject = cast(AtkObject*)obj;
+		if (DEBUG) Stdout.formatln ("-->atkComponent_ref_accessible_at_point");
+		AccessibleObject object = getAccessibleObject (atkObject);
+		if (object is null) return null;
+		AtkObject* parentResult;
+		if (ATK.g_type_is_a (object.parentType, ATK_COMPONENT_TYPE)) {
+			auto componentIface = cast(AtkComponentIface*)ATK.g_type_interface_peek_parent (ATK.ATK_COMPONENT_GET_IFACE (object.handle));
+			if (componentIface.ref_accessible_at_point !is null) {
+				parentResult = componentIface.ref_accessible_at_point( object.handle, x, y, coord_type);
+			}
+		}
+		AccessibleControlListener[] listeners = object.getControlListeners ();
+		if (listeners.length is 0) return parentResult;
+
+		AccessibleControlEvent event = new AccessibleControlEvent (object);
+		event.childID = object.id;
+		event.x = x; event.y = y;
+		if (coord_type is ATK.ATK_XY_WINDOW) {
+			/* translate control -> display, for filling in the event to be dispatched */
+			auto gtkAccessible = ATK.GTK_ACCESSIBLE (object.handle);
+			auto topLevel = ATK.gtk_widget_get_toplevel (gtkAccessible.widget);
+			auto window = OS.GTK_WIDGET_WINDOW (topLevel);
+			int topWindowX, topWindowY;
+			OS.gdk_window_get_origin (window, &topWindowX, &topWindowY);
+			event.x += topWindowX;
+			event.y += topWindowY;
+		}
+		for (int i = 0; i < listeners.length; i++) {
+			listeners [i].getChildAtPoint (event);
+		}
+		if (event.childID is object.id) event.childID = ACC.CHILDID_SELF;
+		AccessibleObject accObj = object.getChildByID (event.childID);
+		if (accObj !is null) {
+			if (parentResult !is null) OS.g_object_unref (parentResult);
+			OS.g_object_ref (accObj.handle);
+			return accObj.handle;
+		}
+		return parentResult;
+	}
+
+	package static extern(C) AtkHyperlink* atkHypertext_get_link (void* obj, int link_index) {
+        auto atkObject = cast(AtkObject*)obj;
+		if (DEBUG) Stdout.formatln ("-->atkHypertext_get_link");
+		return null;
+	}
+
+	package static extern(C) int atkHypertext_get_n_links (void* obj) {
+        auto atkObject = cast(AtkObject*)obj;
+		if (DEBUG) Stdout.formatln ("-->atkHypertext_get_n_links");
+		return 0;	/* read hyperlink's name */
+	}
+
+	package static extern(C) int atkHypertext_get_link_index (void* obj, int char_index) {
+        auto atkObject = cast(AtkObject*)obj;
+		if (DEBUG) Stdout.formatln ("-->atkHypertext_get_link_index");
+		return 0;
+	}
+
+	package static extern(C) char* atkObject_get_description (AtkObject* atkObject) {
+		if (DEBUG) Stdout.formatln ("-->atkObject_get_description");
+		AccessibleObject object = getAccessibleObject (atkObject);
+		if (object is null) return null;
+		char* parentResult;
+		auto objectClass = cast(AtkObjectClass*)ATK.g_type_class_peek (object.parentType);
+		if (objectClass.get_description !is null) {
+			parentResult = objectClass.get_description(object.handle);
+		}
+		AccessibleListener[] listeners = object.getAccessibleListeners ();
+		if (listeners.length is 0) return parentResult;
+
+		AccessibleEvent event = new AccessibleEvent (object);
+		event.childID = object.id;
+		if (parentResult !is null) {
+			event.result = fromUtf8z( parentResult ).dup;
+		}
+		for (int i = 0; i < listeners.length; i++) {
+			listeners [i].getDescription (event);
+		}
+		if (event.result is null) return parentResult;
+		if (descriptionPtr !is null) OS.g_free (descriptionPtr.ptr);
+
+        char[] name = event.result.dup ~ \0;
+        char* p = cast(char*)OS.g_malloc (name.length);
+        descriptionPtr =  p ? p[ 0 .. name.length ] : null;
+        return descriptionPtr.ptr;	}
+
+	package static extern(C) char* atkObject_get_name (AtkObject* atkObject) {
+		if (DEBUG) Stdout.formatln ("-->atkObject_get_name: {}", atkObject);
+		AccessibleObject object = getAccessibleObject (atkObject);
+		if (object is null) return null;
+		char* parentResult;
+		auto objectClass = cast(AtkObjectClass*)ATK.g_type_class_peek (object.parentType);
+		if (objectClass.get_name !is null) {
+			parentResult = objectClass.get_name( object.handle);
+		}
+		AccessibleListener[] listeners = object.getAccessibleListeners ();
+		if (listeners.length is 0) return parentResult;
+
+		AccessibleEvent event = new AccessibleEvent (object);
+		event.childID = object.id;
+		if (parentResult !is null) {
+			event.result = fromUtf8z( parentResult ).dup;
+		}
+		for (int i = 0; i < listeners.length; i++) {
+			listeners [i].getName (event);
+		}
+		if (event.result is null) return parentResult;
+		if (namePtr !is null) OS.g_free (namePtr.ptr);
+        char[] name = event.result.dup ~ \0;
+        char* p = cast(char*)OS.g_malloc (name.length);
+        namePtr =  p ? p[ 0 .. name.length ] : null;
+        return namePtr.ptr;
+	}
+
+	package static extern(C) int atkObject_get_n_children (AtkObject* atkObject) {
+		if (DEBUG) Stdout.formatln ("-->atkObject_get_n_children: {}", atkObject);
+		AccessibleObject object = getAccessibleObject (atkObject);
+		if (object is null) return 0;
+		int /*long*/ parentResult = 0;
+		auto objectClass = cast(AtkObjectClass*)ATK.g_type_class_peek (object.parentType);
+		if (objectClass.get_n_children !is null) {
+			parentResult = objectClass.get_n_children( object.handle);
+		}
+		AccessibleControlListener[] listeners = object.getControlListeners ();
+		if (listeners.length is 0) return parentResult;
+
+		AccessibleControlEvent event = new AccessibleControlEvent (object);
+		event.childID = object.id;
+		event.detail = cast(int)/*64*/parentResult;
+		for (int i = 0; i < listeners.length; i++) {
+			listeners [i].getChildCount (event);
+		}
+		return event.detail;
+	}
+
+	package static extern(C) int atkObject_get_index_in_parent (AtkObject* atkObject) {
+		if (DEBUG) Stdout.formatln ("-->atkObjectCB_get_index_in_parent.  ");
+		AccessibleObject object = getAccessibleObject (atkObject);
+		if (object is null) return 0;
+		if (object.index !is -1) return object.index;
+		auto objectClass = cast(AtkObjectClass*)ATK.g_type_class_peek (object.parentType);
+		if (objectClass.get_index_in_parent is null) return 0;
+		return objectClass.get_index_in_parent(object. handle);
+	}
+
+	package static extern(C) AtkObject* atkObject_get_parent (AtkObject* atkObject) {
+		if (DEBUG) Stdout.formatln ("-->atkObject_get_parent: {}", atkObject);
+		AccessibleObject object = getAccessibleObject (atkObject);
+		if (object is null) return null;
+		if (object.parent !is null) return object.parent.handle;
+		auto objectClass = cast(AtkObjectClass*)ATK.g_type_class_peek (object.parentType);
+		if (objectClass.get_parent is null) return null;
+		return objectClass.get_parent( object.handle);
+	}
+
+	package static extern(C) int atkObject_get_role (AtkObject* atkObject) {
+		if (DEBUG) Stdout.formatln ("-->atkObject_get_role: {}", atkObject);
+		AccessibleObject object = getAccessibleObject (atkObject);
+		if (object is null) return 0;
+		if (object.getAccessibleListeners ().length !is 0) {
+			AccessibleControlListener[] listeners = object.getControlListeners ();
+			AccessibleControlEvent event = new AccessibleControlEvent (object);
+			event.childID = object.id;
+			event.detail = -1;
+			for (int i = 0; i < listeners.length; i++) {
+				listeners [i].getRole (event);
+			}
+			if (event.detail !is -1) {
+				switch (event.detail) {
+					/* Convert from win32 role values to atk role values */
+					case ACC.ROLE_CHECKBUTTON: return ATK.ATK_ROLE_CHECK_BOX;
+					case ACC.ROLE_CLIENT_AREA: return ATK.ATK_ROLE_DRAWING_AREA;
+					case ACC.ROLE_COMBOBOX: return ATK.ATK_ROLE_COMBO_BOX;
+					case ACC.ROLE_DIALOG: return ATK.ATK_ROLE_DIALOG;
+					case ACC.ROLE_LABEL: return ATK.ATK_ROLE_LABEL;
+					case ACC.ROLE_LINK: return ATK.ATK_ROLE_TEXT;
+					case ACC.ROLE_LIST: return ATK.ATK_ROLE_LIST;
+					case ACC.ROLE_LISTITEM: return ATK.ATK_ROLE_LIST_ITEM;
+					case ACC.ROLE_MENU: return ATK.ATK_ROLE_MENU;
+					case ACC.ROLE_MENUBAR: return ATK.ATK_ROLE_MENU_BAR;
+					case ACC.ROLE_MENUITEM: return ATK.ATK_ROLE_MENU_ITEM;
+					case ACC.ROLE_PROGRESSBAR: return ATK.ATK_ROLE_PROGRESS_BAR;
+					case ACC.ROLE_PUSHBUTTON: return ATK.ATK_ROLE_PUSH_BUTTON;
+					case ACC.ROLE_SCROLLBAR: return ATK.ATK_ROLE_SCROLL_BAR;
+					case ACC.ROLE_SEPARATOR: return ATK.ATK_ROLE_SEPARATOR;
+					case ACC.ROLE_SLIDER: return ATK.ATK_ROLE_SLIDER;
+					case ACC.ROLE_TABLE: return ATK.ATK_ROLE_TABLE;
+					case ACC.ROLE_TABLECELL: return ATK.ATK_ROLE_TABLE_CELL;
+					case ACC.ROLE_TABLECOLUMNHEADER: return ATK.ATK_ROLE_TABLE_COLUMN_HEADER;
+					case ACC.ROLE_TABLEROWHEADER: return ATK.ATK_ROLE_TABLE_ROW_HEADER;
+					case ACC.ROLE_TABFOLDER: return ATK.ATK_ROLE_PAGE_TAB_LIST;
+					case ACC.ROLE_TABITEM: return ATK.ATK_ROLE_PAGE_TAB;
+					case ACC.ROLE_TEXT: return ATK.ATK_ROLE_TEXT;
+					case ACC.ROLE_TOOLBAR: return ATK.ATK_ROLE_TOOL_BAR;
+					case ACC.ROLE_TOOLTIP: return ATK.ATK_ROLE_TOOL_TIP;
+					case ACC.ROLE_TREE: return ATK.ATK_ROLE_TREE;
+					case ACC.ROLE_TREEITEM: return ATK.ATK_ROLE_LIST_ITEM;
+					case ACC.ROLE_RADIOBUTTON: return ATK.ATK_ROLE_RADIO_BUTTON;
+					case ACC.ROLE_WINDOW: return ATK.ATK_ROLE_WINDOW;
+				}
+			}
+		}
+		auto objectClass = cast(AtkObjectClass*)ATK.g_type_class_peek (object.parentType);
+		if (objectClass.get_role is null) return 0;
+		return objectClass.get_role( object.handle);
+	}
+
+	package static extern(C) AtkObject* atkObject_ref_child (AtkObject* atkObject, int /*long*/ index) {
+		if (DEBUG) Stdout.formatln ("-->atkObject_ref_child: {} of: {}", index, atkObject);
+		AccessibleObject object = getAccessibleObject (atkObject);
+		if (object is null) return null;
+		object.updateChildren ();
+		AccessibleObject accObject = object.getChildByIndex (cast(int)/*64*/index);
+		if (accObject !is null) {
+			OS.g_object_ref (accObject.handle);
+			return accObject.handle;
+		}
+		auto objectClass = cast(AtkObjectClass*)ATK.g_type_class_peek (object.parentType);
+		if (objectClass.ref_child is null) return null;
+		return objectClass.ref_child( object.handle, index);
+	}
+
+	package static extern(C) AtkStateSet * atkObject_ref_state_set (AtkObject* atkObject) {
+		if (DEBUG) Stdout.formatln ("-->atkObject_ref_state_set");
+		AccessibleObject object = getAccessibleObject (atkObject);
+		if (object is null) return null;
+		AtkStateSet* parentResult;
+		auto objectClass = cast(AtkObjectClass*)ATK.g_type_class_peek (object.parentType);
+		if (objectClass.ref_state_set !is null) {
+			parentResult = objectClass.ref_state_set( object.handle);
+		}
+		AccessibleControlListener[] listeners = object.getControlListeners ();
+		if (listeners.length is 0) return parentResult;
+
+		auto set = parentResult;
+		AccessibleControlEvent event = new AccessibleControlEvent (object);
+		event.childID = object.id;
+		event.detail = -1;
+		for (int i = 0; i < listeners.length; i++) {
+			listeners [i].getState (event);
+		}
+		if (event.detail !is -1) {
+			/*	Convert from win32 state values to atk state values */
+			int state = event.detail;
+			if ((state & ACC.STATE_BUSY) !is 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_BUSY);
+			if ((state & ACC.STATE_CHECKED) !is 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_CHECKED);
+			if ((state & ACC.STATE_EXPANDED) !is 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_EXPANDED);
+			if ((state & ACC.STATE_FOCUSABLE) !is 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_FOCUSABLE);
+			if ((state & ACC.STATE_FOCUSED) !is 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_FOCUSED);
+			if ((state & ACC.STATE_HOTTRACKED) !is 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_ARMED);
+			if ((state & ACC.STATE_INVISIBLE) is 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_VISIBLE);
+			if ((state & ACC.STATE_MULTISELECTABLE) !is 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_MULTISELECTABLE);
+			if ((state & ACC.STATE_OFFSCREEN) is 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_SHOWING);
+			if ((state & ACC.STATE_PRESSED) !is 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_PRESSED);
+			if ((state & ACC.STATE_READONLY) is 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_EDITABLE);
+			if ((state & ACC.STATE_SELECTABLE) !is 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_SELECTABLE);
+			if ((state & ACC.STATE_SELECTED) !is 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_SELECTED);
+			if ((state & ACC.STATE_SIZEABLE) !is 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_RESIZABLE);
+			/* Note: STATE_COLLAPSED, STATE_LINKED and STATE_NORMAL have no ATK equivalents */
+		}
+		return set;
+	}
+
+	package static extern(C) int atkSelection_is_child_selected (void* obj, int index) {
+        auto atkObject = cast(AtkObject*)obj;
+		if (DEBUG) Stdout.formatln ("-->atkSelection_is_child_selected");
+		AccessibleObject object = getAccessibleObject (atkObject);
+		if (object is null) return 0;
+		int /*long*/ parentResult = 0;
+		if (ATK.g_type_is_a (object.parentType, ATK_SELECTION_TYPE)) {
+			auto selectionIface = cast(AtkSelectionIface*)ATK.g_type_interface_peek_parent (ATK.ATK_SELECTION_GET_IFACE (object.handle));
+			if (selectionIface.is_child_selected !is null) {
+				parentResult = selectionIface.is_child_selected( object.handle, index);
+			}
+		}
+		AccessibleControlListener[] listeners = object.getControlListeners ();
+		if (listeners.length is 0) return parentResult;
+
+		AccessibleControlEvent event = new AccessibleControlEvent (object);
+		event.childID = object.id;
+		for (int i = 0; i < listeners.length; i++) {
+			listeners [i].getSelection (event);
+		}
+		AccessibleObject accessibleObject = object.getChildByID (event.childID);
+		if (accessibleObject !is null) {
+			return accessibleObject.index is index ? 1 : 0;
+		}
+		return parentResult;
+	}
+
+	package static extern(C) AtkObject* atkSelection_ref_selection (void* obj, int index) {
+        auto atkObject = cast(AtkObject*)obj;
+		if (DEBUG) Stdout.formatln ("-->atkSelection_ref_selection");
+		AccessibleObject object = getAccessibleObject (atkObject);
+		if (object is null) return null;
+		AtkObject* parentResult;
+		if (ATK.g_type_is_a (object.parentType, ATK_SELECTION_TYPE)) {
+			auto selectionIface = cast(AtkSelectionIface*)ATK.g_type_interface_peek_parent (ATK.ATK_SELECTION_GET_IFACE (object.handle));
+			if (selectionIface.ref_selection !is null) {
+				parentResult = selectionIface.ref_selection( object.handle, index);
+			}
+		}
+		AccessibleControlListener[] listeners = object.getControlListeners ();
+		if (listeners.length is 0) return parentResult;
+
+		AccessibleControlEvent event = new AccessibleControlEvent (object);
+		event.childID = object.id;
+		for (int i = 0; i < listeners.length; i++) {
+			listeners [i].getSelection (event);
+		}
+		AccessibleObject accObj = object.getChildByID (event.childID);
+		if (accObj !is null) {
+			if (parentResult !is null) OS.g_object_unref (parentResult);
+			OS.g_object_ref (accObj.handle);
+			return accObj.handle;
+		}
+		return parentResult;
+	}
+
+	package static extern(C) int atkText_get_caret_offset (void* obj) {
+        auto atkObject = cast(AtkObject*)obj;
+		if (DEBUG) Stdout.formatln ("-->atkText_get_caret_offset");
+		AccessibleObject object = getAccessibleObject (atkObject);
+		if (object is null) return 0;
+		int /*long*/ parentResult = 0;
+		if (ATK.g_type_is_a (object.parentType, ATK_TEXT_TYPE)) {
+			auto textIface = cast(AtkTextIface*)ATK.g_type_interface_peek_parent (ATK.ATK_TEXT_GET_IFACE (object.handle));
+			if (textIface.get_caret_offset !is null) {
+				parentResult = textIface.get_caret_offset( object.handle);
+			}
+		}
+		AccessibleTextListener[] listeners = object.getTextListeners ();
+		if (listeners.length is 0) return parentResult;
+
+		AccessibleTextEvent event = new AccessibleTextEvent (object);
+		event.childID = object.id;
+		event.offset = cast(int)/*64*/parentResult;
+		for (int i = 0; i < listeners.length; i++) {
+			listeners [i].getCaretOffset (event);
+		}
+		return event.offset;
+	}
+
+	package static extern(C) uint atkText_get_character_at_offset (void* obj, int offset) {
+        auto atkObject = cast(AtkObject*)obj;
+		if (DEBUG) Stdout.formatln ("-->atkText_get_character_at_offset");
+		AccessibleObject object = getAccessibleObject (atkObject);
+		if (object is null) return 0;
+		char[] text = object.getText ();
+		if (text !is null) return text[cast(int)/*64*/offset ]; // TODO
+		if (ATK.g_type_is_a (object.parentType, ATK_TEXT_TYPE)) {
+			auto textIface = cast(AtkTextIface*)ATK.g_type_class_peek (object.parentType);
+			if (textIface.get_character_at_offset !is null) {
+				return textIface.get_character_at_offset( object.handle, offset);
+			}
+		}
+		return 0;
+	}
+
+	package static extern(C) int atkText_get_character_count (void* obj) {
+        auto atkObject = cast(AtkObject*)obj;
+		if (DEBUG) Stdout.formatln ("-->atkText_get_character_count");
+		AccessibleObject object = getAccessibleObject (atkObject);
+		if (object is null) return 0;
+		char[] text = object.getText ();
+		if (text !is null) return text.length;
+		if (ATK.g_type_is_a (object.parentType, ATK_TEXT_TYPE)) {
+			auto textIface = cast(AtkTextIface*)ATK.g_type_class_peek (object.parentType);
+			if (textIface.get_character_count !is null) {
+				return textIface.get_character_count( object.handle);
+			}
+		}
+		return 0;
+	}
+
+	package static extern(C) int atkText_get_n_selections (void* obj) {
+        auto atkObject = cast(AtkObject*)obj;
+		if (DEBUG) Stdout.formatln("-->atkText_get_n_selections");
+		AccessibleObject object = getAccessibleObject (atkObject);
+		if (object is null) return 0;
+		int /*long*/ parentResult = 0;
+		if (ATK.g_type_is_a (object.parentType, ATK_TEXT_TYPE)) {
+			auto textIface = cast(AtkTextIface*)ATK.g_type_interface_peek_parent (ATK.ATK_TEXT_GET_IFACE (object.handle));
+			if (textIface.get_n_selections !is null) {
+				parentResult = textIface.get_n_selections( object.handle);
+			}
+		}
+		AccessibleTextListener[] listeners = object.getTextListeners ();
+		if (listeners.length is 0) return parentResult;
+
+		AccessibleTextEvent event = new AccessibleTextEvent (object);
+		event.childID = object.id;
+		for (int i = 0; i < listeners.length; i++) {
+			listeners [i].getSelectionRange (event);
+		}
+		return event.length is 0 ? parentResult : 1;
+	}
+
+	package static extern(C) char* atkText_get_selection (void* obj, int selection_num, int* start_offset, int* end_offset) {
+        auto atkObject = cast(AtkObject*)obj;
+		if (DEBUG) Stdout.formatln ("-->atkText_get_selection");
+		AccessibleObject object = getAccessibleObject (atkObject);
+		if (object is null) return null;
+		*start_offset=0;
+		*end_offset=0;
+		if (ATK.g_type_is_a (object.parentType, ATK_TEXT_TYPE)) {
+			auto textIface = cast(AtkTextIface*)ATK.g_type_interface_peek_parent (ATK.ATK_TEXT_GET_IFACE (object.handle));
+			if (textIface.get_selection !is null) {
+				textIface.get_selection( object.handle, selection_num, start_offset, end_offset );
+			}
+		}
+		AccessibleTextListener[] listeners = object.getTextListeners ();
+		if (listeners.length is 0) return null;
+
+		AccessibleTextEvent event = new AccessibleTextEvent (object);
+		event.childID = object.id;
+		int parentStart;
+		int parentEnd;
+		parentStart= *start_offset;
+		parentEnd= *end_offset;
+		event.offset = parentStart;
+		event.length = parentEnd - parentStart;
+		for (int i = 0; i < listeners.length; i++) {
+			listeners [i].getSelectionRange (event);
+		}
+		*start_offset = event.offset;
+		*end_offset = event.offset + event.length;
+		return null;
+	}
+
+	package static extern(C) char* atkText_get_text (void* obj, int start_offset, int end_offset) {
+        auto atkObject = cast(AtkObject*)obj;
+		if (DEBUG) Stdout.formatln ("-->atkText_get_text: {},{}", start_offset, end_offset);
+		AccessibleObject object = getAccessibleObject (atkObject);
+		if (object is null) return null;
+		char[] text = object.getText ();
+		if (text.length > 0) {
+			if (end_offset is -1) {
+				end_offset = text.length ;
+			} else {
+				end_offset = Math.min (end_offset, text.length );
+			}
+			start_offset = Math.min (start_offset, end_offset);
+			text = text[ start_offset .. end_offset ];
+			auto result = cast(char*)OS.g_malloc (text.length+1);
+            result[ 0 .. text.length ] = text;
+            result[ text.length ] = '\0';
+			return result;
+		}
+		return null;
+	}
+
+	package static extern(C) char* atkText_get_text_after_offset (void* obj, int offset_value, int boundary_type, int* start_offset, int* end_offset) {
+        auto atkObject = cast(AtkObject*)obj;
+		if (DEBUG) Stdout.formatln ("-->atkText_get_text_after_offset");
+		AccessibleObject object = getAccessibleObject (atkObject);
+		if (object is null) return null;
+		int offset = cast(int)/*64*/offset_value;
+		char[] text = object.getText ();
+		if (text.length > 0) {
+			int length = text.length ;
+			offset = Math.min (offset, length - 1);
+			int startBounds = offset;
+			int endBounds = offset;
+			switch (cast(int)/*64*/boundary_type) {
+				case ATK.ATK_TEXT_BOUNDARY_CHAR: {
+					if (length > offset) endBounds++;
+					break;
+				}
+				case ATK.ATK_TEXT_BOUNDARY_WORD_START: {
+					int wordStart1 = nextIndexOfChar (text, " !?.\n", offset - 1);
+					if (wordStart1 is -1) {
+						startBounds = endBounds = length;
+						break;
+					}
+					wordStart1 = nextIndexOfNotChar (text, " !?.\n", wordStart1);
+					if (wordStart1 is length) {
+						startBounds = endBounds = length;
+						break;
+					}
+					startBounds = wordStart1;
+					int wordStart2 = nextIndexOfChar (text, " !?.\n", wordStart1);
+					if (wordStart2 is -1) {
+						endBounds = length;
+						break;
+					}
+					endBounds = nextIndexOfNotChar (text, " !?.\n", wordStart2);
+					break;
+				}
+				case ATK.ATK_TEXT_BOUNDARY_WORD_END: {
+					int previousWordEnd = previousIndexOfNotChar (text, " \n", offset);
+					if (previousWordEnd is -1 || previousWordEnd !is offset - 1) {
+						offset = nextIndexOfNotChar (text, " \n", offset);
+					}
+					if (offset is -1) {
+						startBounds = endBounds = length;
+						break;
+					}
+					int wordEnd1 = nextIndexOfChar (text, " !?.\n", cast(int)/*64*/offset);
+					if (wordEnd1 is -1) {
+						startBounds = endBounds = length;
+						break;
+					}
+					wordEnd1 = nextIndexOfNotChar (text, "!?.", wordEnd1);
+					if (wordEnd1 is length) {
+						startBounds = endBounds = length;
+						break;
+					}
+					startBounds = wordEnd1;
+					int wordEnd2 = nextIndexOfNotChar (text, " \n", wordEnd1);
+					if (wordEnd2 is length) {
+						startBounds = endBounds = length;
+						break;
+					}
+					wordEnd2 = nextIndexOfChar (text, " !?.\n", wordEnd2);
+					if (wordEnd2 is -1) {
+						endBounds = length;
+						break;
+					}
+					endBounds = nextIndexOfNotChar (text, "!?.", wordEnd2);
+					break;
+				}
+				case ATK.ATK_TEXT_BOUNDARY_SENTENCE_START: {
+					int previousSentenceEnd = previousIndexOfChar (text, "!?.", offset);
+					int previousText = previousIndexOfNotChar (text, " !?.\n", offset);
+					int sentenceStart1 = 0;
+					if (previousSentenceEnd >= previousText) {
+						sentenceStart1 = nextIndexOfNotChar (text, " !?.\n", offset);
+					} else {
+						sentenceStart1 = nextIndexOfChar (text, "!?.", offset);
+						if (sentenceStart1 is -1) {
+							startBounds = endBounds = length;
+							break;
+						}
+						sentenceStart1 = nextIndexOfNotChar (text, " !?.\n", sentenceStart1);
+					}
+					if (sentenceStart1 is length) {
+						startBounds = endBounds = length;
+						break;
+					}
+					startBounds = sentenceStart1;
+					int sentenceStart2 = nextIndexOfChar (text, "!?.", sentenceStart1);
+					if (sentenceStart2 is -1) {
+						endBounds = length;
+						break;
+					}
+					endBounds = nextIndexOfNotChar (text, " !?.\n", sentenceStart2);
+					break;
+				}
+				case ATK.ATK_TEXT_BOUNDARY_SENTENCE_END: {
+					int sentenceEnd1 = nextIndexOfChar (text, "!?.", offset);
+					if (sentenceEnd1 is -1) {
+						startBounds = endBounds = length;
+						break;
+					}
+					sentenceEnd1 = nextIndexOfNotChar (text, "!?.", sentenceEnd1);
+					if (sentenceEnd1 is length) {
+						startBounds = endBounds = length;
+						break;
+					}
+					startBounds = sentenceEnd1;
+					int sentenceEnd2 = nextIndexOfNotChar (text, " \n", sentenceEnd1);
+					if (sentenceEnd2 is length) {
+						startBounds = endBounds = length;
+						break;
+					}
+					sentenceEnd2 = nextIndexOfChar (text, "!?.", sentenceEnd2);
+					if (sentenceEnd2 is -1) {
+						endBounds = length;
+						break;
+					}
+					endBounds = nextIndexOfNotChar (text, "!?.", sentenceEnd2);
+					break;
+				}
+				case ATK.ATK_TEXT_BOUNDARY_LINE_START: {
+					int lineStart1 = locate( text, '\n' );
+                    if( lineStart1 == text.length ) lineStart1 = -1;
+					if (lineStart1 is -1) {
+						startBounds = endBounds = length;
+						break;
+					}
+					lineStart1 = nextIndexOfNotChar (text, "\n", lineStart1);
+					if (lineStart1 is length) {
+						startBounds = endBounds = length;
+						break;
+					}
+					startBounds = lineStart1;
+					int lineStart2 = locate( text, '\n' );
+                    if( lineStart2 == text.length ) lineStart2 = -1;
+					if (lineStart2 is -1) {
+						endBounds = length;
+						break;
+					}
+					lineStart2 = nextIndexOfNotChar (text, "\n", lineStart2);
+					endBounds = lineStart2;
+					break;
+				}
+				case ATK.ATK_TEXT_BOUNDARY_LINE_END: {
+					int lineEnd1 = nextIndexOfChar (text, "\n", offset);
+					if (lineEnd1 is -1) {
+						startBounds = endBounds = length;
+						break;
+					}
+					startBounds = lineEnd1;
+					if (startBounds is length) {
+						endBounds = length;
+						break;
+					}
+					int lineEnd2 = nextIndexOfChar (text, "\n", lineEnd1 + 1);
+					if (lineEnd2 is -1) {
+						endBounds = length;
+						break;
+					}
+					endBounds = lineEnd2;
+					break;
+				}
+			}
+			*start_offset=startBounds;
+			*end_offset=endBounds;
+			text = text[startBounds .. endBounds ];
+			auto result = cast(char*)OS.g_malloc (text.length+1);
+            result[ 0 .. text.length ] = text;
+            result[ text.length ] = '\0';
+			return result;
+		}
+		return null;
+	}
+
+	package static extern(C) char* atkText_get_text_at_offset (void* obj, int offset_value, int boundary_type, int* start_offset, int* end_offset) {
+        auto atkObject = cast(AtkObject*)obj;
+		if (DEBUG) Stdout.formatln ("-->atkText_get_text_at_offset: {} start: {} end: {}", offset_value, start_offset, end_offset);
+		AccessibleObject object = getAccessibleObject (atkObject);
+		if (object is null) return null;
+		int offset = offset_value;
+		char[] text = object.getText ();
+		if (text.length > 0) {
+			int length = text.length;
+			offset = Math.min (offset, length - 1);
+			int startBounds = offset;
+			int endBounds = offset;
+			switch (boundary_type) {
+				case ATK.ATK_TEXT_BOUNDARY_CHAR: {
+					if (length > offset) endBounds++;
+					break;
+				}
+				case ATK.ATK_TEXT_BOUNDARY_WORD_START: {
+					int wordStart1 = previousIndexOfNotChar (text, " !?.\n", offset);
+					if (wordStart1 is -1) {
+						startBounds = endBounds = 0;
+						break;
+					}
+					wordStart1 = previousIndexOfChar (text, " !?.\n", wordStart1) + 1;
+					if (wordStart1 is -1) {
+						startBounds = 0;
+						break;
+					}
+					startBounds = wordStart1;
+					int wordStart2 = nextIndexOfChar (text, " !?.\n", wordStart1);
+					endBounds = nextIndexOfNotChar (text, " !?.\n", wordStart2);
+					break;
+				}
+				case ATK.ATK_TEXT_BOUNDARY_WORD_END: {
+					int wordEnd1 = previousIndexOfNotChar (text, "!?.", offset + 1);
+					wordEnd1 = previousIndexOfChar (text, " !?.\n", wordEnd1);
+					wordEnd1 = previousIndexOfNotChar (text, " \n", wordEnd1 + 1);
+					if (wordEnd1 is -1) {
+						startBounds = endBounds = 0;
+						break;
+					}
+					startBounds = wordEnd1 + 1;
+					int wordEnd2 = nextIndexOfNotChar (text, " \n", startBounds);
+					if (wordEnd2 is length) {
+						endBounds = startBounds;
+						break;
+					}
+					wordEnd2 = nextIndexOfChar (text, " !?.\n", wordEnd2);
+					if (wordEnd2 is -1) {
+						endBounds = startBounds;
+						break;
+					}
+					endBounds = nextIndexOfNotChar (text, "!?.", wordEnd2);
+					break;
+				}
+				case ATK.ATK_TEXT_BOUNDARY_SENTENCE_START: {
+					int sentenceStart1 = previousIndexOfNotChar (text, " !?.\n", offset + 1);
+					if (sentenceStart1 is -1) {
+						startBounds = endBounds = 0;
+						break;
+					}
+					sentenceStart1 = previousIndexOfChar (text, "!?.", sentenceStart1) + 1;
+					startBounds = nextIndexOfNotChar (text, " \n", sentenceStart1);
+					int sentenceStart2 = nextIndexOfChar (text, "!?.", startBounds);
+					endBounds = nextIndexOfNotChar (text, " !?.\n", sentenceStart2);
+					break;
+				}
+				case ATK.ATK_TEXT_BOUNDARY_SENTENCE_END: {
+					int sentenceEnd1 = previousIndexOfNotChar (text, "!?.", offset + 1);
+					sentenceEnd1 = previousIndexOfChar (text, "!?.", sentenceEnd1);
+					sentenceEnd1 = previousIndexOfNotChar (text, " \n", sentenceEnd1 + 1);
+					if (sentenceEnd1 is -1) {
+						startBounds = endBounds = 0;
+						break;
+					}
+					startBounds = sentenceEnd1 + 1;
+					int sentenceEnd2 = nextIndexOfNotChar (text, " \n", startBounds);
+					if (sentenceEnd2 is length) {
+						endBounds = startBounds;
+						break;
+					}
+					sentenceEnd2 = nextIndexOfChar (text, "!?.", sentenceEnd2);
+					if (sentenceEnd2 is -1) {
+						endBounds = startBounds;
+						break;
+					}
+					endBounds = nextIndexOfNotChar (text, "!?.", sentenceEnd2);
+					break;
+				}
+				case ATK.ATK_TEXT_BOUNDARY_LINE_START: {
+					startBounds = previousIndexOfChar (text, "\n", offset) + 1;
+					int lineEnd2 = nextIndexOfChar (text, "\n", startBounds);
+					if (lineEnd2 < length) lineEnd2++;
+					endBounds = lineEnd2;
+					break;
+				}
+				case ATK.ATK_TEXT_BOUNDARY_LINE_END: {
+					int lineEnd1 = previousIndexOfChar (text, "\n", offset);
+					if (lineEnd1 is -1) {
+						startBounds = endBounds = 0;
+						break;
+					}
+					startBounds = lineEnd1;
+					endBounds = nextIndexOfChar (text, "\n", lineEnd1 + 1);
+				}
+			}
+			*start_offset=startBounds;
+			*end_offset=endBounds;
+			text = text[startBounds .. endBounds];
+			auto result = cast(char*) OS.g_malloc (text.length+1);
+            result[ 0 .. text.length ] = text;
+            result[ text.length ] = '\0';
+			return result;
+		}
+		return null;
+	}
+
+	package static extern(C) char* atkText_get_text_before_offset (void* obj, int offset_value, int boundary_type, int* start_offset, int* end_offset) {
+        auto atkObject = cast(AtkObject*)obj;
+		if (DEBUG) Stdout.formatln ("-->atkText_get_text_before_offset");
+		AccessibleObject object = getAccessibleObject (atkObject);
+		if (object is null) return null;
+		int offset = offset_value;
+		char[] text = object.getText ();
+		if (text.length > 0) {
+			int length = text.length;
+			offset = Math.min (offset, length - 1);
+			int startBounds = offset;
+			int endBounds = offset;
+			switch (boundary_type) {
+				case ATK.ATK_TEXT_BOUNDARY_CHAR: {
+					if (length >= offset && offset > 0) startBounds--;
+					break;
+				}
+				case ATK.ATK_TEXT_BOUNDARY_WORD_START: {
+					int wordStart1 = previousIndexOfChar (text, " !?.\n", offset - 1);
+					if (wordStart1 is -1) {
+						startBounds = endBounds = 0;
+						break;
+					}
+					int wordStart2 = previousIndexOfNotChar (text, " !?.\n", wordStart1);
+					if (wordStart2 is -1) {
+						startBounds = endBounds = 0;
+						break;
+					}
+					endBounds = wordStart1 + 1;
+					startBounds = previousIndexOfChar (text, " !?.\n", wordStart2) + 1;
+					break;
+				}
+				case ATK.ATK_TEXT_BOUNDARY_WORD_END: {
+					int wordEnd1 =previousIndexOfChar (text, " !?.\n", offset);
+					if (wordEnd1 is -1) {
+						startBounds = endBounds = 0;
+						break;
+					}
+					wordEnd1 = previousIndexOfNotChar (text, " \n", wordEnd1 + 1);
+					if (wordEnd1 is -1) {
+						startBounds = endBounds = 0;
+						break;
+					}
+					endBounds = wordEnd1 + 1;
+					int wordEnd2 = previousIndexOfNotChar (text, " !?.\n", endBounds);
+					wordEnd2 = previousIndexOfChar (text, " !?.\n", wordEnd2);
+					if (wordEnd2 is -1) {
+						startBounds = 0;
+						break;
+					}
+					startBounds = previousIndexOfNotChar (text, " \n", wordEnd2 + 1) + 1;
+					break;
+				}
+				case ATK.ATK_TEXT_BOUNDARY_SENTENCE_START: {
+					int sentenceStart1 = previousIndexOfChar (text, "!?.", offset);
+					if (sentenceStart1 is -1) {
+						startBounds = endBounds = 0;
+						break;
+					}
+					int sentenceStart2 = previousIndexOfNotChar (text, "!?.", sentenceStart1);
+					if (sentenceStart2 is -1) {
+						startBounds = endBounds = 0;
+						break;
+					}
+					endBounds = sentenceStart1 + 1;
+					startBounds = previousIndexOfChar (text, "!?.", sentenceStart2) + 1;
+					break;
+				}
+				case ATK.ATK_TEXT_BOUNDARY_SENTENCE_END: {
+					int sentenceEnd1 = previousIndexOfChar (text, "!?.", offset);
+					if (sentenceEnd1 is -1) {
+						startBounds = endBounds = 0;
+						break;
+					}
+					sentenceEnd1 = previousIndexOfNotChar (text, " \n", sentenceEnd1 + 1);
+					if (sentenceEnd1 is -1) {
+						startBounds = endBounds = 0;
+						break;
+					}
+					endBounds = sentenceEnd1 + 1;
+					int sentenceEnd2 = previousIndexOfNotChar (text, "!?.", endBounds);
+					sentenceEnd2 = previousIndexOfChar (text, "!?.", sentenceEnd2);
+					if (sentenceEnd2 is -1) {
+						startBounds = 0;
+						break;
+					}
+					startBounds = previousIndexOfNotChar (text, " \n", sentenceEnd2 + 1) + 1;
+					break;
+				}
+				case ATK.ATK_TEXT_BOUNDARY_LINE_START: {
+					int lineStart1 = previousIndexOfChar (text, "\n", offset);
+					if (lineStart1 is -1) {
+						startBounds = endBounds = 0;
+						break;
+					}
+					endBounds = lineStart1 + 1;
+					startBounds = previousIndexOfChar (text, "\n", lineStart1) + 1;
+					break;
+				}
+				case ATK.ATK_TEXT_BOUNDARY_LINE_END: {
+					int lineEnd1 = previousIndexOfChar (text, "\n", offset);
+					if (lineEnd1 is -1) {
+						startBounds = endBounds = 0;
+						break;
+					}
+					endBounds = lineEnd1;
+					startBounds = previousIndexOfChar (text, "\n", lineEnd1);
+					if (startBounds is -1) startBounds = 0;
+					break;
+				}
+			}
+			*start_offset=startBounds;
+			*end_offset=endBounds;
+			text = text[startBounds .. endBounds];
+			auto result = cast(char*)OS.g_malloc (text.length+1);
+            result[ 0 .. text.length ] = text;
+            result[ text.length ] = '\0';
+			return result;
+		}
+		return null;
+	}
+
+	AccessibleListener[] getAccessibleListeners () {
+		if (accessible is null) return new AccessibleListener [0];
+		AccessibleListener[] result = accessible.getAccessibleListeners ();
+		return result !is null ? result : new AccessibleListener [0];
+	}
+
+	static AccessibleObject getAccessibleObject (AtkObject* atkObject) {
+		return AccessibleObjects[atkObject];
+	}
+
+	AccessibleObject getChildByHandle (AtkObject* handle) {
+		return children[handle];
+	}
+
+	AccessibleObject getChildByID (int childId) {
+		if (childId is ACC.CHILDID_SELF) return this;
+		foreach( object; children ){
+			if (object.id is childId) return object;
+		}
+		return null;
+	}
+
+	AccessibleObject getChildByIndex (int childIndex) {
+        foreach( object; children ){
+			if (object.index is childIndex) return object;
+		}
+		return null;
+	}
+
+	AccessibleControlListener[] getControlListeners () {
+		if (accessible is null) return new AccessibleControlListener [0];
+		AccessibleControlListener[] result = accessible.getControlListeners ();
+		return result !is null ? result : new AccessibleControlListener [0];
+	}
+
+	char[] getText () {
+		char* parentResult;
+		char[] parentText = "";	//$NON-NLS-1$
+		if (ATK.g_type_is_a (parentType, ATK_TEXT_TYPE)) {
+			auto textIface = cast(AtkTextIface*)ATK.g_type_interface_peek_parent (ATK.ATK_TEXT_GET_IFACE (handle));
+			int /*long*/ characterCount = 0;
+			if (textIface.get_character_count !is null) {
+				characterCount = textIface.get_character_count( handle);
+			}
+			if (characterCount > 0 && textIface.get_text !is null) {
+				parentResult = textIface.get_text( handle, 0, characterCount);
+				if (parentResult !is null) {
+					parentText = fromUtf8z( parentResult ).dup;
+				}
+			}
+		}
+		AccessibleControlListener[] controlListeners = getControlListeners ();
+		if (controlListeners.length is 0) return parentText;
+		AccessibleControlEvent event = new AccessibleControlEvent (this);
+		event.childID = id;
+		event.result = parentText;
+		for (int i = 0; i < controlListeners.length; i++) {
+			controlListeners [i].getValue (event);
+		}
+		return event.result;
+	}
+
+	AccessibleTextListener[] getTextListeners () {
+		if (accessible is null) return new AccessibleTextListener [0];
+		AccessibleTextListener[] result = accessible.getTextListeners ();
+		return result !is null ? result : new AccessibleTextListener [0];
+	}
+
+	private static extern(C) void gObjectClass_finalize (GObject* atkObject) {
+		auto superType = ATK.g_type_class_peek_parent (ATK.G_OBJECT_GET_CLASS (cast(GTypeInstance*)atkObject));
+		auto objectClassStruct = cast(GObjectClass*)ATK.G_OBJECT_CLASS (cast(GTypeClass*)superType);
+		objectClassStruct.finalize(atkObject);
+		AccessibleObject object = getAccessibleObject (cast(AtkObject*)atkObject);
+		if (object !is null) {
+			AccessibleObjects.remove (cast(AtkObject*)atkObject);
+			object.release ();
+		}
+	}
+
+	static int nextIndexOfChar (char[] string, char[] searchChars, int startIndex) {
+		int result = string.length;
+		for (int i = 0; i < searchChars.length; i++) {
+			char current = searchChars[i];
+			int index = locate( string, current, startIndex );
+			if (index !is string.length ) result = Math.min (result, index);
+		}
+		return result;
+	}
+
+	static int nextIndexOfNotChar (char[] string, char[] searchChars, int startIndex) {
+		int length = string.length;
+		int index = startIndex;
+		while (index < length) {
+			char current = string[index];
+			if ( !contains( searchChars, current)) break;
+			index++;
+		}
+		return index;
+	}
+
+	static int previousIndexOfChar (char[] string, char[] searchChars, int startIndex) {
+		int result = -1;
+		if (startIndex < 0) return result;
+		string = string[0 .. startIndex];
+		for (int i = 0; i < searchChars.length ; i++) {
+			char current = searchChars[i];
+			int index = locatePrior( string, current);
+			if (index !is string.length ) result = Math.max (result, index);
+		}
+		return result;
+	}
+
+	static int previousIndexOfNotChar (char[] string, char[] searchChars, int startIndex) {
+		if (startIndex < 0) return -1;
+		int index = startIndex - 1;
+		while (index >= 0) {
+			char current = string[index];
+			if ( !contains(searchChars, current)) break;
+			index--;
+		}
+		return index;
+	}
+
+	void release () {
+		if (DEBUG) Stdout.formatln("AccessibleObject.release: {}", handle);
+		accessible = null;
+        foreach( child; children ){
+			if (child.isLightweight) OS.g_object_unref (child.handle);
+		}
+		if (parent !is null) parent.removeChild (this, false);
+	}
+
+	void removeChild (AccessibleObject child, bool unref) {
+		children.remove (child.handle);
+		if (unref && child.isLightweight) OS.g_object_unref (child.handle);
+	}
+
+	void selectionChanged () {
+		OS.g_signal_emit_by_name0 (handle, ATK.selection_changed.ptr);
+	}
+
+	void setFocus (int childID) {
+		updateChildren ();
+		AccessibleObject accObject = getChildByID (childID);
+		if (accObject !is null) {
+			ATK.atk_focus_tracker_notify (accObject.handle);
+		}
+	}
+
+	void setParent (AccessibleObject parent) {
+		this.parent = parent;
+	}
+
+	void textCaretMoved(int index) {
+		OS.g_signal_emit_by_name1 (handle, ATK.text_caret_moved.ptr, index);
+	}
+
+	void textChanged(int type, int startIndex, int length) {
+		if (type is ACC.TEXT_DELETE) {
+			OS.g_signal_emit_by_name2 (handle, ATK.text_changed_delete.ptr, startIndex, length);
+		} else {
+			OS.g_signal_emit_by_name2 (handle, ATK.text_changed_insert.ptr, startIndex, length);
+		}
+	}
+
+	void textSelectionChanged() {
+		OS.g_signal_emit_by_name0 (handle, ATK.text_selection_changed.ptr);
+	}
+
+	void updateChildren () {
+		if (isLightweight) return;
+		AccessibleControlListener[] listeners = getControlListeners ();
+		if (listeners.length is 0) return;
+
+		AccessibleControlEvent event = new AccessibleControlEvent (this);
+		for (int i = 0; i < listeners.length; i++) {
+			listeners [i].getChildren (event);
+		}
+		if (event.children !is null && event.children.length > 0) {
+			AtkObject*[] idsToKeep = new AtkObject*[]( children.length );
+            idsToKeep.length = 0;
+			if ( null !is (cast(Integer)event.children[0] )) {
+				/*	an array of child id's (Integers) was answered */
+				auto parentType = AccessibleFactory.getDefaultParentType ();
+				for (int i = 0; i < event.children.length; i++) {
+					AccessibleObject object = getChildByIndex (i);
+					if (object is null) {
+						auto childType = AccessibleFactory.getChildType (accessible, i);
+						object = new AccessibleObject (childType, null, accessible, parentType, true);
+						AccessibleObjects[object.handle] = object;
+						addChild (object);
+						object.index = i;
+					}
+                    if( auto intChild = cast(Integer)event.children[i] ){
+                        object.id = intChild.intValue ();
+                    }
+                    else {
+						/* a non-ID value was given so don't set the ID */
+					}
+					idsToKeep ~= object.handle;
+				}
+			} else {
+				/* an array of Accessible children was answered */
+				int childIndex = 0;
+				for (int i = 0; i < event.children.length; i++) {
+					AccessibleObject object = null;
+                    if( auto accChild = cast(Accessible)event.children[i] ){
+						object = accChild.accessibleObject;
+					} else {
+						/* a non-Accessible value was given so nothing to do here */
+					}
+					if (object !is null) {
+						object.index = childIndex++;
+                        idsToKeep ~= object.handle;
+					}
+				}
+			}
+			/* remove old children that were not provided as children anymore */
+			foreach( id; children.keys ){
+				if ( !tango.core.Array.contains( idsToKeep, id )) {
+					AccessibleObject object = cast(AccessibleObject) children[id];
+					removeChild (object, true);
+				}
+			}
+		}
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwt/accessibility/AccessibleTextAdapter.d	Fri Jan 11 05:07:22 2008 +0100
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+module dwt.accessibility.AccessibleTextAdapter;
+
+import dwt.accessibility.AccessibleTextEvent;
+import dwt.accessibility.AccessibleTextListener;
+
+/**
+ * This adapter class provides default implementations for the
+ * methods described by the <code>AccessibleTextListener</code> interface.
+ * <p>
+ * Classes that wish to deal with <code>AccessibleTextEvent</code>s can
+ * extend this class and override only the methods that they are
+ * interested in.
+ * </p><p>
+ * Note: Accessibility clients use child identifiers to specify
+ * whether they want information about a control or one of its children.
+ * Child identifiers are increasing integers beginning with 0.
+ * The identifier CHILDID_SELF represents the control itself.
+ * When returning a child identifier to a client, you may use CHILDID_NONE
+ * to indicate that no child or control has the required information.
+ * </p><p>
+ * Note: This adapter is typically used by implementors of
+ * a custom control to provide very detailed information about
+ * the control instance to accessibility clients.
+ * </p>
+ *
+ * @see AccessibleTextListener
+ * @see AccessibleTextEvent
+ *
+ * @since 3.0
+ */
+public abstract class AccessibleTextAdapter : AccessibleTextListener {
+
+	/**
+	 * Sent when an accessibility client requests the current character offset
+	 * of the text caret.
+	 * The default behavior is to do nothing.
+	 * <p>
+	 * Return the caret offset in the <code>offset</code>
+	 * field of the event object.
+	 * </p>
+	 *
+	 * @param e an event object containing the following fields:<ul>
+	 *    <li>childID [IN] - an identifier specifying a child of the control</li>
+	 *    <li>offset [OUT] - the current offset of the text caret</li>
+	 * </ul>
+	 */
+	public void getCaretOffset (AccessibleTextEvent e) {
+	}
+
+	/**
+	 * Sent when an accessibility client requests the range of the current
+	 * text selection.
+	 * The default behavior is to do nothing.
+	 * <p>
+	 * Return the selection start offset and non-negative length in the
+	 * <code>offset</code> and <code>length</code> fields of the event object.
+	 * </p>
+	 *
+	 * @param e an event object containing the following fields:<ul>
+	 *    <li>childID [IN] - an identifier specifying a child of the control</li>
+	 *    <li>offset [OUT] - the offset of the current text selection</li>
+	 *    <li>length [OUT] - the length of the current text selection</li>
+	 * </ul>
+	 */
+	public void getSelectionRange (AccessibleTextEvent e) {
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwt/accessibility/AccessibleTextEvent.d	Fri Jan 11 05:07:22 2008 +0100
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+module dwt.accessibility.AccessibleTextEvent;
+
+
+import dwt.internal.SWTEventObject;
+import tango.text.convert.Format;
+
+/**
+ * Instances of this class are sent as a result of
+ * accessibility clients sending messages to controls
+ * asking for detailed information about the implementation
+ * of the control instance. Typically, only implementors
+ * of custom controls need to listen for this event.
+ * <p>
+ * Note: The meaning of each field depends on the
+ * message that was sent.
+ * </p>
+ *
+ * @see AccessibleTextListener
+ * @see AccessibleTextAdapter
+ *
+ * @since 3.0
+ */
+public class AccessibleTextEvent : SWTEventObject {
+	public int childID;				// IN
+	public int offset, length;		// OUT
+
+	//static final long serialVersionUID = 3977019530868308275L;
+
+/**
+ * Constructs a new instance of this class.
+ *
+ * @param source the object that fired the event
+ */
+public this (Object source) {
+	super (source);
+}
+
+/**
+ * Returns a string containing a concise, human-readable
+ * description of the receiver.
+ *
+ * @return a string representation of the event
+ */
+public char[] toString () {
+	return Format( "AccessibleTextEvent {{childID={} offset={} length={}}",
+        childID,
+		offset,
+		length);
+}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwt/accessibility/AccessibleTextListener.d	Fri Jan 11 05:07:22 2008 +0100
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+module dwt.accessibility.AccessibleTextListener;
+
+import dwt.accessibility.AccessibleTextEvent;
+
+import dwt.internal.SWTEventListener;
+
+/**
+ * Classes that implement this interface provide methods
+ * that deal with the events that are generated when an
+ * accessibility client sends a message to a control.
+ * <p>
+ * After creating an instance of a class that implements
+ * this interface it can be added to a control using the
+ * <code>addAccessibleTextListener</code> method and removed
+ * using the <code>removeAccessibleTextListener</code> method.
+ * When a client requests information the appropriate method
+ * will be invoked.
+ * </p><p>
+ * Note: Accessibility clients use child identifiers to specify
+ * whether they want information about a control or one of its children.
+ * Child identifiers are increasing integers beginning with 0.
+ * The identifier CHILDID_SELF represents the control itself.
+ * </p><p>
+ * Note: This interface is typically used by implementors of
+ * a custom control to provide very detailed information about
+ * the control instance to accessibility clients.
+ * </p>
+ *
+ * @see AccessibleTextAdapter
+ * @see AccessibleTextEvent
+ *
+ * @since 3.0
+ */
+public interface AccessibleTextListener : SWTEventListener {
+
+	/**
+	 * Sent when an accessibility client requests the current character offset
+	 * of the text caret.
+	 * <p>
+	 * Return the caret offset in the <code>offset</code>
+	 * field of the event object.
+	 * </p>
+	 *
+	 * @param e an event object containing the following fields:<ul>
+	 *    <li>childID [IN] - an identifier specifying a child of the control</li>
+	 *    <li>offset [OUT] - the current offset of the text caret</li>
+	 * </ul>
+	 */
+	public void getCaretOffset (AccessibleTextEvent e);
+
+	/**
+	 * Sent when an accessibility client requests the range of the current
+	 * text selection.
+	 * <p>
+	 * Return the selection start offset and non-negative length in the
+	 * <code>offset</code> and <code>length</code> fields of the event object.
+	 * </p>
+	 *
+	 * @param e an event object containing the following fields:<ul>
+	 *    <li>childID [IN] - an identifier specifying a child of the control</li>
+	 *    <li>offset [OUT] - the offset of the current text selection</li>
+	 *    <li>length [OUT] - the length of the current text selection</li>
+	 * </ul>
+	 */
+	public void getSelectionRange (AccessibleTextEvent e);
+}
--- a/dwt/internal/accessibility/gtk/ATK.d	Thu Jan 10 08:21:49 2008 +0100
+++ b/dwt/internal/accessibility/gtk/ATK.d	Fri Jan 11 05:07:22 2008 +0100
@@ -18,9 +18,34 @@
 import dwt.internal.Library;
 import dwt.internal.gtk.OS;
 import dwt.internal.c.atk;
+import dwt.internal.c.gtk;
 
 import tango.core.Traits;
 
+alias dwt.internal.c.atk.AtkObjectFactory AtkObjectFactory;
+alias dwt.internal.c.atk.AtkObjectClass AtkObjectClass;
+alias dwt.internal.c.atk.AtkActionIface AtkActionIface;
+alias dwt.internal.c.atk.AtkComponentIface AtkComponentIface;
+alias dwt.internal.c.atk.AtkHypertextIface AtkHypertextIface;
+alias dwt.internal.c.atk.AtkSelectionIface AtkSelectionIface;
+alias dwt.internal.c.atk.AtkTextIface AtkTextIface;
+alias dwt.internal.c.atk.AtkObject AtkObject;
+alias dwt.internal.c.atk.AtkStateSet AtkStateSet;
+alias dwt.internal.c.atk.AtkObjectFactoryClass AtkObjectFactoryClass;
+alias dwt.internal.c.atk.AtkHyperlink AtkHyperlink;
+
+alias dwt.internal.c.gtk.GtkAccessible GtkAccessible;
+
+private AtkActionIface* ATK_ACTION_GET_IFACE( AtkObject* );
+private AtkComponentIface* ATK_COMPONENT_GET_IFACE( AtkObject* );
+private AtkObjectFactoryClass* ATK_OBJECT_FACTORY_CLASS( void* );
+private AtkSelectionIface* ATK_SELECTION_GET_IFACE( AtkObject* );
+private AtkTextIface* ATK_TEXT_GET_IFACE(AtkObject*);
+private GtkAccessible* GTK_ACCESSIBLE(AtkObject*);
+
+
+
+
 template NameOfFunc(alias f) {
     // Note: highly dependent on the .stringof formatting
     // the value begins with "& " which is why the first two chars are cut off
@@ -112,12 +137,12 @@
 	public static const char[] text_caret_moved = "text_caret_moved";
 	public static const char[] text_selection_changed = "text_selection_changed";
 
-    //mixin ForwardGtkAtkCFunc!(.ATK_ACTION_GET_IFACE );
-    //mixin ForwardGtkAtkCFunc!(.ATK_COMPONENT_GET_IFACE);
-    //mixin ForwardGtkAtkCFunc!(.ATK_OBJECT_FACTORY_CLASS );
-    //mixin ForwardGtkAtkCFunc!(.ATK_SELECTION_GET_IFACE );
-    //mixin ForwardGtkAtkCFunc!(.ATK_TEXT_GET_IFACE );
-    //mixin ForwardGtkAtkCFunc!(.GTK_ACCESSIBLE );
+    mixin ForwardGtkAtkCFunc!(.ATK_ACTION_GET_IFACE );
+    mixin ForwardGtkAtkCFunc!(.ATK_COMPONENT_GET_IFACE);
+    mixin ForwardGtkAtkCFunc!(.ATK_OBJECT_FACTORY_CLASS );
+    mixin ForwardGtkAtkCFunc!(.ATK_SELECTION_GET_IFACE );
+    mixin ForwardGtkAtkCFunc!(.ATK_TEXT_GET_IFACE );
+    mixin ForwardGtkAtkCFunc!(.GTK_ACCESSIBLE );
     mixin ForwardGtkAtkCFunc!(.atk_focus_tracker_notify );
     mixin ForwardGtkAtkCFunc!(.atk_get_default_registry );
     mixin ForwardGtkAtkCFunc!(.atk_object_factory_create_accessible );
@@ -133,3 +158,5 @@
     mixin ForwardGtkAtkCFunc!(.atk_state_set_new );
 
 }
+
+
--- a/dwt/internal/c/atk.d	Thu Jan 10 08:21:49 2008 +0100
+++ b/dwt/internal/c/atk.d	Fri Jan 11 05:07:22 2008 +0100
@@ -4,7 +4,7 @@
 ******************************************************************************/
 module dwt.internal.c.atk;
 
-public import dwt.internal.c.glib;
+public import dwt.internal.c.glib_object;
 
 extern(C):
 align(4):
--- a/dwt/internal/c/gdk.d	Thu Jan 10 08:21:49 2008 +0100
+++ b/dwt/internal/c/gdk.d	Fri Jan 11 05:07:22 2008 +0100
@@ -5,7 +5,7 @@
 module dwt.internal.c.gdk;
 public import dwt.internal.c.pango;
 public import dwt.internal.c.cairo;
-public import dwt.internal.c.glib;
+public import dwt.internal.c.glib_object;
 
 extern(C):
 align(4):
--- a/dwt/internal/c/gdkx.d	Thu Jan 10 08:21:49 2008 +0100
+++ b/dwt/internal/c/gdkx.d	Fri Jan 11 05:07:22 2008 +0100
@@ -5,7 +5,7 @@
 module dwt.internal.c.gdkx;
 public import dwt.internal.c.pango;
 public import dwt.internal.c.cairo;
-public import dwt.internal.c.glib;
+public import dwt.internal.c.glib_object;
 public import dwt.internal.c.gdk;
 public import dwt.internal.c.Xlib;
 public import dwt.internal.c.Xutil;
--- a/dwt/internal/c/gtk.d	Thu Jan 10 08:21:49 2008 +0100
+++ b/dwt/internal/c/gtk.d	Fri Jan 11 05:07:22 2008 +0100
@@ -8,7 +8,7 @@
 public import dwt.internal.c.cairo;
 public import dwt.internal.c.pango;
 public import dwt.internal.c.gdk;
-public import dwt.internal.c.glib;
+public import dwt.internal.c.glib_object;
 
 extern(C):
 align(4):
--- a/dwt/internal/c/gtk_unix_print_2_0.d	Thu Jan 10 08:21:49 2008 +0100
+++ b/dwt/internal/c/gtk_unix_print_2_0.d	Fri Jan 11 05:07:22 2008 +0100
@@ -9,7 +9,7 @@
 public import dwt.internal.c.pango;
 public import dwt.internal.c.gdk;
 public import dwt.internal.c.gtk;
-public import dwt.internal.c.glib;
+public import dwt.internal.c.glib_object;
 
 alias void GtkPrintUnixDialogPrivate;
 alias _GtkPrintUnixDialogClass GtkPrintUnixDialogClass;
--- a/dwt/internal/c/pango.d	Thu Jan 10 08:21:49 2008 +0100
+++ b/dwt/internal/c/pango.d	Fri Jan 11 05:07:22 2008 +0100
@@ -4,7 +4,7 @@
 ******************************************************************************/
 module dwt.internal.c.pango;
 
-public import dwt.internal.c.glib;
+public import dwt.internal.c.glib_object;
 
 extern(C):
 align(4):
--- a/dwt/internal/c/pangocairo.d	Thu Jan 10 08:21:49 2008 +0100
+++ b/dwt/internal/c/pangocairo.d	Fri Jan 11 05:07:22 2008 +0100
@@ -6,7 +6,7 @@
 
 public import dwt.internal.c.cairo;
 public import dwt.internal.c.pango;
-public import dwt.internal.c.glib;
+public import dwt.internal.c.glib_object;
 
 extern(C):
 align(4):
--- a/dwt/internal/gtk/OS.d	Thu Jan 10 08:21:49 2008 +0100
+++ b/dwt/internal/gtk/OS.d	Fri Jan 11 05:07:22 2008 +0100
@@ -26,7 +26,6 @@
         dwt.internal.c.gdk,
         dwt.internal.c.gdkx,
         dwt.internal.c.atk,
-        dwt.internal.c.glib,
         dwt.internal.c.cairo,
         dwt.internal.c.pango,
         dwt.internal.c.pangocairo,
@@ -45,6 +44,10 @@
 public alias dwt.internal.c.glib_object.GClosureNotify GClosureNotify;
 public alias dwt.internal.c.glib_object.GPollFunc GPollFunc;
 public alias dwt.internal.c.glib_object.GTypeInstance GTypeInstance;
+public alias dwt.internal.c.glib_object.GObjectClass GObjectClass;
+public alias dwt.internal.c.glib_object.GTypeClass GTypeClass;
+public alias dwt.internal.c.glib_object.GInterfaceInfo GInterfaceInfo;
+public alias dwt.internal.c.glib_object.GTypeQuery GTypeQuery;
 
 public alias dwt.internal.c.gdk.GdkColor GdkColor;
 public alias dwt.internal.c.gdk.GdkRegion GdkRegion;
@@ -146,6 +149,22 @@
     g_object_get( obj, firstPropertyName, res, null );
 }
 
+private void g_signal_emit_by_name0( void* instance, char* detailed_signal ){
+    g_signal_emit_by_name( instance, detailed_signal );
+}
+
+private void g_signal_emit_by_name1( void* instance, char* detailed_signal, int value ){
+    g_signal_emit_by_name( instance, detailed_signal, value );
+}
+
+private void g_signal_emit_by_name2( void* instance, char* detailed_signal, int value1, int value2 ){
+    g_signal_emit_by_name( instance, detailed_signal, value1, value2 );
+}
+
+private void g_signal_emit_by_name3( void* instance, char* detailed_signal, int value1, int value2, int value3 ){
+    g_signal_emit_by_name( instance, detailed_signal, value1, value2, value3 );
+}
+
 // for linux always true, the other possibility would be GDK_WINDOWING_WIN32
 private bool GDK_WINDOWING_X11(){
     return true;
@@ -886,10 +905,10 @@
     mixin ForwardGtkOsCFunc!(.g_signal_connect_closure);
     mixin ForwardGtkOsCFunc!(.g_signal_connect_closure_by_id);
 //    mixin ForwardGtkOsCFunc!(.g_signal_connect_after);
-    mixin ForwardGtkOsCFunc!(.g_signal_emit_by_name);
-    mixin ForwardGtkOsCFunc!(.g_signal_emit_by_name);
-    mixin ForwardGtkOsCFunc!(.g_signal_emit_by_name);
-    mixin ForwardGtkOsCFunc!(.g_signal_emit_by_name);
+    mixin ForwardGtkOsCFunc!(.g_signal_emit_by_name0);
+    mixin ForwardGtkOsCFunc!(.g_signal_emit_by_name1);
+    mixin ForwardGtkOsCFunc!(.g_signal_emit_by_name2);
+    mixin ForwardGtkOsCFunc!(.g_signal_emit_by_name3);
     mixin ForwardGtkOsCFunc!(.g_signal_handler_disconnect);
     mixin ForwardGtkOsCFunc!(.g_signal_handlers_block_matched);
     mixin ForwardGtkOsCFunc!(.g_signal_handlers_disconnect_matched);
@@ -2235,13 +2254,12 @@
         return (cast(GObjectClass*) g_type_check_class_cast ( arg0, cast(GType) (20 << 2) ) ) ;
     }
 
-    // Compile prob: GTypeClass has no member g_class
-   /+ static GObjectClass* G_OBJECT_GET_CLASS( GTypeClass* arg0 )
+    static GObjectClass* G_OBJECT_GET_CLASS( GTypeInstance* arg0 )
     {
         lock.lock();
         scope(exit) lock.unlock();
         return (cast(GObjectClass*) arg0.g_class) ;
-    }+/
+    }
 
     static gchar* G_OBJECT_TYPE_NAME( GTypeInstance* arg0 )
     {
--- a/dwt/widgets/Display.d	Thu Jan 10 08:21:49 2008 +0100
+++ b/dwt/widgets/Display.d	Fri Jan 11 05:07:22 2008 +0100
@@ -125,11 +125,6 @@
  */
 public class Display : Device {
 
-    package struct CallbackData {
-        Display display;
-        void* data;
-    }
-
 	/* Events Dispatching and Callback */
 	int gdkEventCount;
 	GdkEvent* [] gdkEvents;
@@ -3952,3 +3947,9 @@
 }
 
 }
+
+package struct CallbackData {
+    Display display;
+    void* data;
+}
+
--- a/dwt/widgets/Shell.d	Thu Jan 10 08:21:49 2008 +0100
+++ b/dwt/widgets/Shell.d	Fri Jan 11 05:07:22 2008 +0100
@@ -143,7 +143,7 @@
 	int minWidth, minHeight;
 	Control lastActive;
 	Region region;
-    Display.CallbackData filterProcCallbackData;
+    CallbackData filterProcCallbackData;
 
 	static final int MAXIMUM_TRIM = 128;
 
--- a/todo.txt	Thu Jan 10 08:21:49 2008 +0100
+++ b/todo.txt	Fri Jan 11 05:07:22 2008 +0100
@@ -1,7 +1,24 @@
+Rule for porting
+
+    package/module and modulename
+    class declarator extends/implements to : and comma list
+    ctors: Classnames to 'this'
+    Replace automatic
+        s/\<boolean\>/bool/g
+        s/==/is/g
+        s/!=/!is/g
+        s/\<equals\>/==\/*eq*\//g   // the replacements need post edit
+    Replace with prompt
+        s/\<String\>/char[]/g       // replace only types, not comments or parts for identifiers
+        s/is 0/is null/g            // replace only that one, that are reference types
+
+
 Next Steps:
     * accessibility package (independant)
     * Shell
 
+Button, EventTable, Menu, ScrollBar, Synchronizer, Tray
+
 Questions:
     Whats needed at minimum to make a test with empty window?
     How about memory management?