# HG changeset patch # User Frank Benoit # Date 1200024442 -3600 # Node ID 787b5413b0ce492f11e63c19a82db741d8d1070c # Parent c83c51423d031b6849e646d6af39622b352c5175 accessibility package diff -r c83c51423d03 -r 787b5413b0ce dsss.conf --- 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 diff -r c83c51423d03 -r 787b5413b0ce dwt/accessibility/ACC.d --- /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; +} diff -r c83c51423d03 -r 787b5413b0ce dwt/accessibility/Accessible.d --- /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 getAccessible, 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 AccessibleListener 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 + * @exception SWTException + * + * @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 AccessibleControlListener + * interface. + * + * @param listener the listener that should be notified when the receiver + * is asked for custom control specific information + * + * @exception IllegalArgumentException + * @exception SWTException + * + * @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 AccessibleTextListener + * interface. + * + * @param listener the listener that should be notified when the receiver + * is asked for custom text control specific information + * + * @exception IllegalArgumentException + * @exception SWTException + * + * @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. + *

+ * IMPORTANT: This method is not part of the public + * API for Accessible. 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. + *

+ * + * @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 + * @exception SWTException + * + * @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 + * @exception SWTException + * + * @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 + * @exception SWTException + * + * @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 + * + * @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 + */ + 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 + * + * @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 ACC.NOTIFY_TEXT_INSERT + * or ACC.NOTIFY_TEXT_DELETE + * @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 + * + * @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 + * + * @since 3.0 + */ + public void textSelectionChanged () { + checkWidget (); + if (accessibleObject !is null) { + accessibleObject.textSelectionChanged (); + } + } +} diff -r c83c51423d03 -r 787b5413b0ce dwt/accessibility/AccessibleAdapter.d --- /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 AccessibleListener interface. + *

+ * Classes that wish to deal with AccessibleEvents can + * extend this class and override only the methods that they are + * interested in. + *

+ * 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. + *

+ * + * @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. + *

+ * Return the name of the control or specified child in the + * result 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. + *

+ * + * @param e an event object containing the following fields: + */ + 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. + *

+ * 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. + *

+ * Return the help string of the control or specified child in + * the result 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. + *

+ * + * @param e an event object containing the following fields: + */ + 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. + *

+ * 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. + *

+ * Return the keyboard shortcut string of the control or specified child + * in the result 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. + *

+ * + * @param e an event object containing the following fields: + */ + 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. + *

+ * 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. + *

+ * Return the description of the control or specified child in + * the result 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. + *

+ * + * @param e an event object containing the following fields: + */ + public void getDescription(AccessibleEvent e) { + } +} diff -r c83c51423d03 -r 787b5413b0ce dwt/accessibility/AccessibleControlAdapter.d --- /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 AccessibleControlListener interface. + *

+ * Classes that wish to deal with AccessibleControlEvents can + * extend this class and override only the methods that they are + * interested in. + *

+ * 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. + *

+ * Note: This adapter is typically used by implementors of + * a custom control to provide very detailed information about + * the control instance to accessibility clients. + *

+ * + * @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. + *

+ * Return the identifier of the child at display point (x, y) + * in the childID 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. + *

+ * + * @param e an event object containing the following fields: + */ + 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. + *

+ * Return a rectangle describing the location of the specified + * control or child in the x, y, width, and height + * fields of the event object. + *

+ * + * @param e an event object containing the following fields: + */ + 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. + *

+ * Return an Accessible for the specified control or + * child in the accessible field of the event object. + * Return null if the specified child does not have its own + * Accessible. + *

+ * + * @param e an event object containing the following fields: + */ + 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. + *

+ * Return the number of child items in the detail + * field of the event object. + *

+ * + * @param e an event object containing the following fields: + */ + 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. + *

+ * 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". + *

+ * Return a string describing the default action of the specified + * control or child in the result field of the event object. + * Returning null tells the client to use the platform default action string. + *

+ * + * @param e an event object containing the following fields: + */ + 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. + *

+ * Return the identifier of the child that has focus in the + * childID 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. + *

+ * + * @param e an event object containing the following fields: + */ + 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. + *

+ * Return a role constant (constant defined in ACC beginning with ROLE_) + * that describes the role of the specified control or child in the + * detail field of the event object. + *

+ * + * @param e an event object containing the following fields: + */ + 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. + *

+ * Return the identifier of the selected child in the + * childID 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 children field. + * Return CHILDID_NONE if neither the control nor any of its children are selected. + *

+ * + * @param e an event object containing the following fields: + */ + 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. + *

+ * 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 + * detail field of the event object. + *

+ * + * @param e an event object containing the following fields: + */ + 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. + *

+ * 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. + *

+ * Return a string describing the value of the specified control + * or child in the result field of the event object. + * Returning null tells the client to use the platform value string. + *

+ * + * @param e an event object containing the following fields: + */ + public void getValue(AccessibleControlEvent e) { + } + + /** + * Sent when an accessibility client requests the children of the control. + * The default behavior is to do nothing. + *

+ * Return the children as an array of childIDs in the children + * field of the event object. + *

+ * + * @param e an event object containing the following fields: + */ + public void getChildren(AccessibleControlEvent e) { + } +} diff -r c83c51423d03 -r 787b5413b0ce dwt/accessibility/AccessibleControlEvent.d --- /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. + *

+ * Note: The meaning of each field depends on the + * message that was sent. + *

+ * + * @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); +} +} diff -r c83c51423d03 -r 787b5413b0ce dwt/accessibility/AccessibleControlListener.d --- /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. + *

+ * After creating an instance of a class that implements + * this interface it can be added to a control using the + * addAccessibleControlListener method and removed + * using the removeAccessibleControlListener method. + * When a client requests information the appropriate method + * will be invoked. + *

+ * 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. + *

+ * Note: This interface is typically used by implementors of + * a custom control to provide very detailed information about + * the control instance to accessibility clients. + *

+ * + * @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. + *

+ * Return the identifier of the child at display point (x, y) + * in the childID 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. + *

+ * + * @param e an event object containing the following fields: + */ + 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. + *

+ * Return a rectangle describing the location of the specified + * control or child in the x, y, width, and height + * fields of the event object. + *

+ * + * @param e an event object containing the following fields: + */ + public void getLocation(AccessibleControlEvent e); + + /** + * Sent when an accessibility client requests the accessible object + * for a child of the control. + *

+ * Return an Accessible for the specified control or + * child in the accessible field of the event object. + * Return null if the specified child does not have its own + * Accessible. + *

+ * + * @param e an event object containing the following fields: + */ + public void getChild(AccessibleControlEvent e); + + /** + * Sent when an accessibility client requests the number of + * children in the control. + *

+ * Return the number of child items in the detail + * field of the event object. + *

+ * + * @param e an event object containing the following fields: + */ + 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. + *

+ * 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". + *

+ * Return a string describing the default action of the specified + * control or child in the result field of the event object. + * Returning null tells the client to use the platform default action string. + *

+ * + * @param e an event object containing the following fields: + */ + public void getDefaultAction(AccessibleControlEvent e); + + /** + * Sent when an accessibility client requests the identity of + * the child or control that has keyboard focus. + *

+ * Return the identifier of the child that has focus in the + * childID 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. + *

+ * + * @param e an event object containing the following fields: + */ + 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. + *

+ * Return a role constant (constant defined in ACC beginning with ROLE_) + * that describes the role of the specified control or child in the + * detail field of the event object. + *

+ * + * @param e an event object containing the following fields: + */ + public void getRole(AccessibleControlEvent e); + + /** + * Sent when an accessibility client requests the identity of + * the child or control that is currently selected. + *

+ * Return the identifier of the selected child in the + * childID 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 children field. + * Return CHILDID_NONE if neither the control nor any of its children are selected. + *

+ * + * @param e an event object containing the following fields: + */ + 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. + *

+ * 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 + * detail field of the event object. + *

+ * + * @param e an event object containing the following fields: + */ + 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. + *

+ * 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. + *

+ * Return a string describing the value of the specified control + * or child in the result field of the event object. + * Returning null tells the client to use the platform value string. + *

+ * + * @param e an event object containing the following fields: + */ + public void getValue(AccessibleControlEvent e); + + /** + * Sent when an accessibility client requests the children of the control. + *

+ * Return the children as an array of childIDs in the children + * field of the event object. + *

+ * + * @param e an event object containing the following fields: + */ + public void getChildren(AccessibleControlEvent e); +} diff -r c83c51423d03 -r 787b5413b0ce dwt/accessibility/AccessibleEvent.d --- /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. + *

+ * Note: The meaning of the result field depends + * on the message that was sent. + *

+ * + * @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 ); +} +} diff -r c83c51423d03 -r 787b5413b0ce dwt/accessibility/AccessibleFactory.d --- /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); + } + } +} diff -r c83c51423d03 -r 787b5413b0ce dwt/accessibility/AccessibleListener.d --- /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. + *

+ * After creating an instance of a class that implements + * this interface it can be added to a control using the + * addAccessibleListener method and removed + * using the removeAccessibleListener method. + * When a client requests information, the appropriate method + * will be invoked. + *

+ * 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. + *

+ * + * @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. + *

+ * Return the name of the control or specified child in the + * result 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. + *

+ * + * @param e an event object containing the following fields: + */ + 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 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. + *

+ * Return the help string of the control or specified child in + * the result 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. + *

+ * + * @param e an event object containing the following fields: + */ + 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. + *

+ * 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. + *

+ * Return the keyboard shortcut string of the control or specified child + * in the result 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. + *

+ * + * @param e an event object containing the following fields: + */ + 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. + *

+ * 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. + *

+ * Return the description of the control or specified child in + * the result 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. + *

+ * + * @param e an event object containing the following fields: + */ + public void getDescription(AccessibleEvent e); +} diff -r c83c51423d03 -r 787b5413b0ce dwt/accessibility/AccessibleObject.d --- /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); + } + } + } + } +} diff -r c83c51423d03 -r 787b5413b0ce dwt/accessibility/AccessibleTextAdapter.d --- /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 AccessibleTextListener interface. + *

+ * Classes that wish to deal with AccessibleTextEvents can + * extend this class and override only the methods that they are + * interested in. + *

+ * 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. + *

+ * Note: This adapter is typically used by implementors of + * a custom control to provide very detailed information about + * the control instance to accessibility clients. + *

+ * + * @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. + *

+ * Return the caret offset in the offset + * field of the event object. + *

+ * + * @param e an event object containing the following fields: + */ + 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. + *

+ * Return the selection start offset and non-negative length in the + * offset and length fields of the event object. + *

+ * + * @param e an event object containing the following fields: + */ + public void getSelectionRange (AccessibleTextEvent e) { + } +} diff -r c83c51423d03 -r 787b5413b0ce dwt/accessibility/AccessibleTextEvent.d --- /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. + *

+ * Note: The meaning of each field depends on the + * message that was sent. + *

+ * + * @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); +} +} diff -r c83c51423d03 -r 787b5413b0ce dwt/accessibility/AccessibleTextListener.d --- /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. + *

+ * After creating an instance of a class that implements + * this interface it can be added to a control using the + * addAccessibleTextListener method and removed + * using the removeAccessibleTextListener method. + * When a client requests information the appropriate method + * will be invoked. + *

+ * 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. + *

+ * Note: This interface is typically used by implementors of + * a custom control to provide very detailed information about + * the control instance to accessibility clients. + *

+ * + * @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. + *

+ * Return the caret offset in the offset + * field of the event object. + *

+ * + * @param e an event object containing the following fields: + */ + public void getCaretOffset (AccessibleTextEvent e); + + /** + * Sent when an accessibility client requests the range of the current + * text selection. + *

+ * Return the selection start offset and non-negative length in the + * offset and length fields of the event object. + *

+ * + * @param e an event object containing the following fields: + */ + public void getSelectionRange (AccessibleTextEvent e); +} diff -r c83c51423d03 -r 787b5413b0ce dwt/internal/accessibility/gtk/ATK.d --- 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 ); } + + diff -r c83c51423d03 -r 787b5413b0ce dwt/internal/c/atk.d --- 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): diff -r c83c51423d03 -r 787b5413b0ce dwt/internal/c/gdk.d --- 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): diff -r c83c51423d03 -r 787b5413b0ce dwt/internal/c/gdkx.d --- 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; diff -r c83c51423d03 -r 787b5413b0ce dwt/internal/c/gtk.d --- 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): diff -r c83c51423d03 -r 787b5413b0ce dwt/internal/c/gtk_unix_print_2_0.d --- 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; diff -r c83c51423d03 -r 787b5413b0ce dwt/internal/c/pango.d --- 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): diff -r c83c51423d03 -r 787b5413b0ce dwt/internal/c/pangocairo.d --- 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): diff -r c83c51423d03 -r 787b5413b0ce dwt/internal/gtk/OS.d --- 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 ) { diff -r c83c51423d03 -r 787b5413b0ce dwt/widgets/Display.d --- 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; +} + diff -r c83c51423d03 -r 787b5413b0ce dwt/widgets/Shell.d --- 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; diff -r c83c51423d03 -r 787b5413b0ce todo.txt --- 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/\/bool/g + s/==/is/g + s/!=/!is/g + s/\/==\/*eq*\//g // the replacements need post edit + Replace with prompt + s/\/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?