changeset 37:c86fc3d50cfa

Decorations
author Frank Benoit <benoit@tionex.de>
date Thu, 10 Jan 2008 05:17:47 +0100
parents f0cac58ac62b
children 6e625fa1612d
files dwt/internal/gtk/OS.d dwt/widgets/Button.d dwt/widgets/Canvas.d dwt/widgets/Caret.d dwt/widgets/Composite.d dwt/widgets/Control.d dwt/widgets/Decorations.d dwt/widgets/Menu.d dwt/widgets/Widget.d todo.txt
diffstat 10 files changed, 1285 insertions(+), 162 deletions(-) [+]
line wrap: on
line diff
--- a/dwt/internal/gtk/OS.d	Thu Jan 10 05:01:46 2008 +0100
+++ b/dwt/internal/gtk/OS.d	Thu Jan 10 05:17:47 2008 +0100
@@ -114,6 +114,7 @@
 public alias dwt.internal.c.gtk.GtkCellRendererClass GtkCellRendererClass;
 public alias dwt.internal.c.gtk.GtkAllocation GtkAllocation;
 public alias dwt.internal.c.gtk.GtkSocket GtkSocket;
+public alias dwt.internal.c.gtk.GtkAccelGroup GtkAccelGroup;
 
 public alias dwt.internal.c.Xlib.XErrorEvent XErrorEvent;
 public alias dwt.internal.c.Xlib.XExposeEvent XExposeEvent;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwt/widgets/Button.d	Thu Jan 10 05:17:47 2008 +0100
@@ -0,0 +1,771 @@
+/*******************************************************************************
+ * 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.widgets.Button;
+
+import dwt.widgets.Control;
+
+class Button : Control {
+}
+
+/+
+import dwt.internal.*;
+import dwt.internal.gtk.*;
+import dwt.*;
+import dwt.graphics.*;
+import dwt.events.*;
+
+/**
+ * Instances of this class represent a selectable user interface object that
+ * issues notification when pressed and released.
+ * <dl>
+ * <dt><b>Styles:</b></dt>
+ * <dd>ARROW, CHECK, PUSH, RADIO, TOGGLE, FLAT</dd>
+ * <dd>UP, DOWN, LEFT, RIGHT, CENTER</dd>
+ * <dt><b>Events:</b></dt>
+ * <dd>Selection</dd>
+ * </dl>
+ * <p>
+ * Note: Only one of the styles ARROW, CHECK, PUSH, RADIO, and TOGGLE
+ * may be specified.
+ * </p><p>
+ * Note: Only one of the styles LEFT, RIGHT, and CENTER may be specified.
+ * </p><p>
+ * Note: Only one of the styles UP, DOWN, LEFT, and RIGHT may be specified
+ * when the ARROW style is specified.
+ * </p><p>
+ * IMPORTANT: This class is intended to be subclassed <em>only</em>
+ * within the SWT implementation.
+ * </p>
+ */
+public class Button extends Control {
+	int /*long*/ boxHandle, labelHandle, imageHandle, arrowHandle, groupHandle;
+	boolean selected;
+	ImageList imageList;
+	Image image;
+	String text;
+
+/**
+ * Constructs a new instance of this class given its parent
+ * and a style value describing its behavior and appearance.
+ * <p>
+ * The style value is either one of the style constants defined in
+ * class <code>SWT</code> which is applicable to instances of this
+ * class, or must be built by <em>bitwise OR</em>'ing together
+ * (that is, using the <code>int</code> "|" operator) two or more
+ * of those <code>SWT</code> style constants. The class description
+ * lists the style constants that are applicable to the class.
+ * Style bits are also inherited from superclasses.
+ * </p>
+ *
+ * @param parent a composite control which will be the parent of the new instance (cannot be null)
+ * @param style the style of control to construct
+ *
+ * @exception IllegalArgumentException <ul>
+ *    <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ *    <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ *
+ * @see SWT#ARROW
+ * @see SWT#CHECK
+ * @see SWT#PUSH
+ * @see SWT#RADIO
+ * @see SWT#TOGGLE
+ * @see SWT#FLAT
+ * @see SWT#LEFT
+ * @see SWT#RIGHT
+ * @see SWT#CENTER
+ * @see Widget#checkSubclass
+ * @see Widget#getStyle
+ */
+public Button (Composite parent, int style) {
+	super (parent, checkStyle (style));
+}
+
+static int checkStyle (int style) {
+	style = checkBits (style, SWT.PUSH, SWT.ARROW, SWT.CHECK, SWT.RADIO, SWT.TOGGLE, 0);
+	if ((style & (SWT.PUSH | SWT.TOGGLE)) != 0) {
+		return checkBits (style, SWT.CENTER, SWT.LEFT, SWT.RIGHT, 0, 0, 0);
+	}
+	if ((style & (SWT.CHECK | SWT.RADIO)) != 0) {
+		return checkBits (style, SWT.LEFT, SWT.RIGHT, SWT.CENTER, 0, 0, 0);
+	}
+	if ((style & SWT.ARROW) != 0) {
+		style |= SWT.NO_FOCUS;
+		return checkBits (style, SWT.UP, SWT.DOWN, SWT.LEFT, SWT.RIGHT, 0, 0);
+	}
+	return style;
+}
+
+/**
+ * Adds the listener to the collection of listeners who will
+ * be notified when the control is selected by the user, by sending
+ * it one of the messages defined in the <code>SelectionListener</code>
+ * interface.
+ * <p>
+ * <code>widgetSelected</code> is called when the control is selected by the user.
+ * <code>widgetDefaultSelected</code> is not called.
+ * </p>
+ *
+ * @param listener the listener which should be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see SelectionListener
+ * @see #removeSelectionListener
+ * @see SelectionEvent
+ */
+public void addSelectionListener (SelectionListener listener) {
+	checkWidget ();
+	if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+	TypedListener typedListener = new TypedListener (listener);
+	addListener (SWT.Selection,typedListener);
+	addListener (SWT.DefaultSelection,typedListener);
+}
+
+public Point computeSize (int wHint, int hHint, boolean changed) {
+	checkWidget ();
+	if (wHint != SWT.DEFAULT && wHint < 0) wHint = 0;
+	if (hHint != SWT.DEFAULT && hHint < 0) hHint = 0;
+	/*
+	* Feature in GTK, GtkCheckButton and GtkRadioButton allocate
+	* only the minimum size necessary for its child. This causes the child
+	* alignment to fail. The fix is to set the child size to the size
+	* of the button.
+	*/
+	forceResize ();
+	int [] reqWidth = null, reqHeight = null;
+	if ((style & (SWT.CHECK | SWT.RADIO)) != 0) {
+		reqWidth = new int [1];
+		reqHeight = new int [1];
+		OS.gtk_widget_get_size_request (boxHandle, reqWidth, reqHeight);
+		OS.gtk_widget_set_size_request (boxHandle, -1, -1);
+	}
+	Point size = computeNativeSize (handle, wHint, hHint, changed);
+	if ((style & (SWT.CHECK | SWT.RADIO)) != 0) {
+		OS.gtk_widget_set_size_request (boxHandle, reqWidth [0], reqHeight [0]);
+	}
+	if (wHint != SWT.DEFAULT || hHint != SWT.DEFAULT) {
+		if ((OS.GTK_WIDGET_FLAGS (handle) & OS.GTK_CAN_DEFAULT) != 0) {
+			int /*long*/ [] buffer = new int /*long*/ [1];
+			GtkBorder border = new GtkBorder ();
+			OS.gtk_widget_style_get (handle, OS.default_border, buffer, 0);
+			if (buffer[0] != 0) {
+				OS.memmove (border, buffer[0], GtkBorder.sizeof);
+			} else {
+				/* Use the GTK+ default value of 1 for each. */
+				border.left = border.right = border.top = border.bottom = 1;
+			}
+			if (wHint != SWT.DEFAULT) size.x += border.left + border.right;
+			if (hHint != SWT.DEFAULT) size.y += border.top + border.bottom;
+		}
+	}
+	return size;
+}
+
+void createHandle (int index) {
+	state |= HANDLE;
+	if ((style & SWT.PUSH) == 0) state |= THEME_BACKGROUND;
+	int bits = SWT.ARROW | SWT.TOGGLE | SWT.CHECK | SWT.RADIO | SWT.PUSH;
+	fixedHandle = OS.g_object_new (display.gtk_fixed_get_type (), 0);
+	if (fixedHandle == 0) error (SWT.ERROR_NO_HANDLES);
+	OS.gtk_fixed_set_has_window (fixedHandle, true);
+	switch (style & bits) {
+		case SWT.ARROW:
+			int arrow_type = OS.GTK_ARROW_UP;
+			if ((style & SWT.UP) != 0) arrow_type = OS.GTK_ARROW_UP;
+			if ((style & SWT.DOWN) != 0) arrow_type = OS.GTK_ARROW_DOWN;
+            if ((style & SWT.LEFT) != 0) arrow_type = OS.GTK_ARROW_LEFT;
+            if ((style & SWT.RIGHT) != 0) arrow_type = OS.GTK_ARROW_RIGHT;
+			handle = OS.gtk_button_new ();
+			if (handle == 0) error (SWT.ERROR_NO_HANDLES);
+			arrowHandle = OS.gtk_arrow_new (arrow_type, OS.GTK_SHADOW_OUT);
+			if (arrowHandle == 0) error (SWT.ERROR_NO_HANDLES);
+			break;
+		case SWT.TOGGLE:
+			handle = OS.gtk_toggle_button_new ();
+			if (handle == 0) error (SWT.ERROR_NO_HANDLES);
+			break;
+		case SWT.CHECK:
+			handle = OS.gtk_check_button_new ();
+			if (handle == 0) error (SWT.ERROR_NO_HANDLES);
+			break;
+		case SWT.RADIO:
+			/*
+			* Feature in GTK.  In GTK, radio button must always be part of
+			* a radio button group.  In a GTK radio group, one button is always
+			* selected.  This means that it is not possible to have a single
+			* radio button that is unselected.  This is necessary to allow
+			* applications to implement their own radio behavior or use radio
+			* buttons outside of radio groups.  The fix is to create a hidden
+			* radio button for each radio button we create and add them
+			* to the same group.  This allows the visible button to be
+			* unselected.
+			*/
+			groupHandle = OS.gtk_radio_button_new (0);
+			if (groupHandle == 0) error (SWT.ERROR_NO_HANDLES);
+			OS.g_object_ref (groupHandle);
+			OS.gtk_object_sink (groupHandle);
+			handle = OS.gtk_radio_button_new (OS.gtk_radio_button_get_group (groupHandle));
+			if (handle == 0) error (SWT.ERROR_NO_HANDLES);
+			break;
+		case SWT.PUSH:
+		default:
+			handle = OS.gtk_button_new ();
+			if (handle == 0) error (SWT.ERROR_NO_HANDLES);
+			OS.GTK_WIDGET_SET_FLAGS(handle, OS.GTK_CAN_DEFAULT);
+			break;
+	}
+	if ((style & SWT.ARROW) != 0) {
+		OS.gtk_container_add (handle, arrowHandle);
+	} else {
+		boxHandle = OS.gtk_hbox_new (false, 4);
+		if (boxHandle == 0) error (SWT.ERROR_NO_HANDLES);
+		labelHandle = OS.gtk_label_new_with_mnemonic (null);
+		if (labelHandle == 0) error (SWT.ERROR_NO_HANDLES);
+		imageHandle = OS.gtk_image_new ();
+		if (imageHandle == 0) error (SWT.ERROR_NO_HANDLES);
+		OS.gtk_container_add (handle, boxHandle);
+		OS.gtk_container_add (boxHandle, imageHandle);
+		OS.gtk_container_add (boxHandle, labelHandle);
+	}
+	OS.gtk_container_add (fixedHandle, handle);
+
+	if ((style & SWT.ARROW) != 0) return;
+	_setAlignment (style & (SWT.LEFT | SWT.CENTER | SWT.RIGHT));
+}
+
+void createWidget (int index) {
+	super.createWidget (index);
+	text = "";
+}
+
+void deregister () {
+	super.deregister ();
+	if (boxHandle != 0) display.removeWidget (boxHandle);
+	if (labelHandle != 0) display.removeWidget (labelHandle);
+	if (imageHandle != 0) display.removeWidget (imageHandle);
+	if (arrowHandle != 0) display.removeWidget (arrowHandle);
+}
+
+int /*long*/ fontHandle () {
+	if (labelHandle != 0) return labelHandle;
+	return super.fontHandle ();
+}
+
+/**
+ * Returns a value which describes the position of the
+ * text or image in the receiver. The value will be one of
+ * <code>LEFT</code>, <code>RIGHT</code> or <code>CENTER</code>
+ * unless the receiver is an <code>ARROW</code> button, in
+ * which case, the alignment will indicate the direction of
+ * the arrow (one of <code>LEFT</code>, <code>RIGHT</code>,
+ * <code>UP</code> or <code>DOWN</code>).
+ *
+ * @return the alignment
+ *
+ * @exception SWTException <ul>
+ *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getAlignment () {
+	checkWidget ();
+	if ((style & SWT.ARROW) != 0) {
+		if ((style & SWT.UP) != 0) return SWT.UP;
+		if ((style & SWT.DOWN) != 0) return SWT.DOWN;
+		if ((style & SWT.LEFT) != 0) return SWT.LEFT;
+		if ((style & SWT.RIGHT) != 0) return SWT.RIGHT;
+		return SWT.UP;
+	}
+	if ((style & SWT.LEFT) != 0) return SWT.LEFT;
+	if ((style & SWT.CENTER) != 0) return SWT.CENTER;
+	if ((style & SWT.RIGHT) != 0) return SWT.RIGHT;
+	return SWT.LEFT;
+}
+
+/**
+ * Returns the receiver's image if it has one, or null
+ * if it does not.
+ *
+ * @return the receiver's image
+ *
+ * @exception SWTException <ul>
+ *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public Image getImage () {
+	checkWidget ();
+	return image;
+}
+
+String getNameText () {
+	return getText ();
+}
+
+/**
+ * Returns <code>true</code> if the receiver is selected,
+ * and false otherwise.
+ * <p>
+ * When the receiver is of type <code>CHECK</code> or <code>RADIO</code>,
+ * it is selected when it is checked. When it is of type <code>TOGGLE</code>,
+ * it is selected when it is pushed in. If the receiver is of any other type,
+ * this method returns false.
+ *
+ * @return the selection state
+ *
+ * @exception SWTException <ul>
+ *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public boolean getSelection () {
+	checkWidget ();
+	if ((style & (SWT.CHECK | SWT.RADIO | SWT.TOGGLE)) == 0) return false;
+	return OS.gtk_toggle_button_get_active (handle);
+}
+
+/**
+ * Returns the receiver's text, which will be an empty
+ * string if it has never been set or if the receiver is
+ * an <code>ARROW</code> button.
+ *
+ * @return the receiver's text
+ *
+ * @exception SWTException <ul>
+ *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public String getText () {
+	checkWidget();
+	if ((style & SWT.ARROW) != 0) return "";
+	return text;
+}
+
+int /*long*/ gtk_button_press_event (int /*long*/ widget, int /*long*/ event) {
+	int /*long*/ result = super.gtk_button_press_event (widget, event);
+	if (result != 0) return result;
+	if ((style & SWT.RADIO) != 0) selected  = getSelection ();
+	return result;
+}
+
+int /*long*/ gtk_clicked (int /*long*/ widget) {
+	if ((style & SWT.RADIO) != 0) {
+		if ((parent.getStyle () & SWT.NO_RADIO_GROUP) != 0) {
+			setSelection (!selected);
+		} else {
+			selectRadio ();
+		}
+	}
+	postEvent (SWT.Selection);
+	return 0;
+}
+
+int /*long*/ gtk_focus_in_event (int /*long*/ widget, int /*long*/ event) {
+	int /*long*/ result = super.gtk_focus_in_event (widget, event);
+	// widget could be disposed at this point
+	if (handle == 0) return 0;
+	if ((style & SWT.PUSH) != 0 && OS.GTK_WIDGET_HAS_DEFAULT (handle)) {
+		Decorations menuShell = menuShell ();
+		menuShell.defaultButton = this;
+	}
+	return result;
+}
+
+int /*long*/ gtk_focus_out_event (int /*long*/ widget, int /*long*/ event) {
+	int /*long*/ result = super.gtk_focus_out_event (widget, event);
+	// widget could be disposed at this point
+	if (handle == 0) return 0;
+	if ((style & SWT.PUSH) != 0 && !OS.GTK_WIDGET_HAS_DEFAULT (handle)) {
+		Decorations menuShell = menuShell ();
+		if (menuShell.defaultButton == this) {
+			menuShell.defaultButton = null;
+		}
+	}
+	return result;
+}
+
+int /*long*/ gtk_key_press_event (int /*long*/ widget, int /*long*/ event) {
+	int /*long*/ result = super.gtk_key_press_event (widget, event);
+	if (result != 0) return result;
+	if ((style & SWT.RADIO) != 0) selected  = getSelection ();
+	return result;
+}
+
+void hookEvents () {
+	super.hookEvents();
+	OS.g_signal_connect_closure (handle, OS.clicked, display.closures [CLICKED], false);
+	if (labelHandle != 0) {
+		OS.g_signal_connect_closure_by_id (labelHandle, display.signalIds [MNEMONIC_ACTIVATE], 0, display.closures [MNEMONIC_ACTIVATE], false);
+	}
+}
+
+boolean isDescribedByLabel () {
+	return false;
+}
+
+boolean mnemonicHit (char key) {
+	if (labelHandle == 0) return false;
+	boolean result = super.mnemonicHit (labelHandle, key);
+	if (result) setFocus ();
+	return result;
+}
+
+boolean mnemonicMatch (char key) {
+	if (labelHandle == 0) return false;
+	return mnemonicMatch (labelHandle, key);
+}
+
+void register () {
+	super.register ();
+	if (boxHandle != 0) display.addWidget (boxHandle, this);
+	if (labelHandle != 0) display.addWidget (labelHandle, this);
+	if (imageHandle != 0) display.addWidget (imageHandle, this);
+	if (arrowHandle != 0) display.addWidget (arrowHandle, this);
+}
+
+void releaseHandle () {
+	super.releaseHandle ();
+	boxHandle = imageHandle = labelHandle = arrowHandle = 0;
+}
+
+void releaseWidget () {
+	super.releaseWidget ();
+	if (groupHandle != 0) OS.g_object_unref (groupHandle);
+	groupHandle = 0;
+	if (imageList != null) imageList.dispose ();
+	imageList = null;
+	image = null;
+	text = null;
+}
+
+/**
+ * Removes the listener from the collection of listeners who will
+ * be notified when the control is selected by the user.
+ *
+ * @param listener the listener which should no longer be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see SelectionListener
+ * @see #addSelectionListener
+ */
+public void removeSelectionListener (SelectionListener listener) {
+	checkWidget();
+	if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
+	if (eventTable == null) return;
+	eventTable.unhook (SWT.Selection, listener);
+	eventTable.unhook (SWT.DefaultSelection,listener);
+}
+
+void resizeHandle (int width, int height) {
+	super.resizeHandle (width, height);
+	/*
+	* Feature in GTK, GtkCheckButton and GtkRadioButton allocate
+	* only the minimum size necessary for its child. This causes the child
+	* alignment to fail. The fix is to set the child size to the size
+	* of the button.
+	*/
+	if ((style & (SWT.CHECK | SWT.RADIO)) != 0) {
+		OS.gtk_widget_set_size_request (boxHandle, width, -1);
+	}
+}
+
+void selectRadio () {
+	/*
+	* This code is intentionally commented.  When two groups
+	* of radio buttons with the same parent are separated by
+	* another control, the correct behavior should be that
+	* the two groups act independently.  This is consistent
+	* with radio tool and menu items.  The commented code
+	* implements this behavior.
+	*/
+//	int index = 0;
+//	Control [] children = parent._getChildren ();
+//	while (index < children.length && children [index] != this) index++;
+//	int i = index - 1;
+//	while (i >= 0 && children [i].setRadioSelection (false)) --i;
+//	int j = index + 1;
+//	while (j < children.length && children [j].setRadioSelection (false)) j++;
+//	setSelection (true);
+	Control [] children = parent._getChildren ();
+	for (int i=0; i<children.length; i++) {
+		Control child = children [i];
+		if (this != child) child.setRadioSelection (false);
+	}
+	setSelection (true);
+}
+
+/**
+ * Controls how text, images and arrows will be displayed
+ * in the receiver. The argument should be one of
+ * <code>LEFT</code>, <code>RIGHT</code> or <code>CENTER</code>
+ * unless the receiver is an <code>ARROW</code> button, in
+ * which case, the argument indicates the direction of
+ * the arrow (one of <code>LEFT</code>, <code>RIGHT</code>,
+ * <code>UP</code> or <code>DOWN</code>).
+ *
+ * @param alignment the new alignment
+ *
+ * @exception SWTException <ul>
+ *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setAlignment (int alignment) {
+	checkWidget ();
+	_setAlignment (alignment);
+}
+
+void _setAlignment (int alignment) {
+	if ((style & SWT.ARROW) != 0) {
+		if ((style & (SWT.UP | SWT.DOWN | SWT.LEFT | SWT.RIGHT)) == 0) return;
+		style &= ~(SWT.UP | SWT.DOWN | SWT.LEFT | SWT.RIGHT);
+		style |= alignment & (SWT.UP | SWT.DOWN | SWT.LEFT | SWT.RIGHT);
+		int arrow_type = OS.GTK_ARROW_UP;
+		boolean isRTL = (style & SWT.RIGHT_TO_LEFT) != 0;
+		switch (alignment) {
+			case SWT.UP: arrow_type = OS.GTK_ARROW_UP; break;
+			case SWT.DOWN: arrow_type = OS.GTK_ARROW_DOWN; break;
+			case SWT.LEFT: arrow_type = isRTL ? OS.GTK_ARROW_RIGHT : OS.GTK_ARROW_LEFT; break;
+			case SWT.RIGHT: arrow_type = isRTL ? OS.GTK_ARROW_LEFT : OS.GTK_ARROW_RIGHT; break;
+		}
+		OS.gtk_arrow_set (arrowHandle, arrow_type, OS.GTK_SHADOW_OUT);
+		return;
+	}
+	if ((alignment & (SWT.LEFT | SWT.RIGHT | SWT.CENTER)) == 0) return;
+	style &= ~(SWT.LEFT | SWT.RIGHT | SWT.CENTER);
+	style |= alignment & (SWT.LEFT | SWT.RIGHT | SWT.CENTER);
+	/* Alignment not honoured when image and text are visible */
+	boolean bothVisible = OS.GTK_WIDGET_VISIBLE (labelHandle) && OS.GTK_WIDGET_VISIBLE (imageHandle);
+	if (bothVisible) {
+		if ((style & (SWT.RADIO | SWT.CHECK)) != 0) alignment = SWT.LEFT;
+		if ((style & (SWT.PUSH | SWT.TOGGLE)) != 0) alignment = SWT.CENTER;
+	}
+	if ((alignment & SWT.LEFT) != 0) {
+		if (bothVisible) {
+			OS.gtk_box_set_child_packing (boxHandle, labelHandle, false, false, 0, OS.GTK_PACK_START);
+			OS.gtk_box_set_child_packing (boxHandle, imageHandle, false, false, 0, OS.GTK_PACK_START);
+		}
+		OS.gtk_misc_set_alignment (labelHandle, 0.0f, 0.5f);
+		OS.gtk_label_set_justify (labelHandle, OS.GTK_JUSTIFY_LEFT);
+		OS.gtk_misc_set_alignment (imageHandle, 0.0f, 0.5f);
+		return;
+	}
+	if ((alignment & SWT.CENTER) != 0) {
+		if (bothVisible) {
+			OS.gtk_box_set_child_packing (boxHandle, labelHandle, true, true, 0, OS.GTK_PACK_END);
+			OS.gtk_box_set_child_packing (boxHandle, imageHandle, true, true, 0, OS.GTK_PACK_START);
+			OS.gtk_misc_set_alignment (labelHandle, 0f, 0.5f);
+			OS.gtk_misc_set_alignment (imageHandle, 1f, 0.5f);
+		} else {
+			OS.gtk_misc_set_alignment (labelHandle, 0.5f, 0.5f);
+			OS.gtk_label_set_justify (labelHandle, OS.GTK_JUSTIFY_CENTER);
+			OS.gtk_misc_set_alignment (imageHandle, 0.5f, 0.5f);
+		}
+		return;
+	}
+	if ((alignment & SWT.RIGHT) != 0) {
+		if (bothVisible) {
+			OS.gtk_box_set_child_packing (boxHandle, labelHandle, false, false, 0, OS.GTK_PACK_END);
+			OS.gtk_box_set_child_packing (boxHandle, imageHandle, false, false, 0, OS.GTK_PACK_END);
+		}
+		OS.gtk_misc_set_alignment (labelHandle, 1.0f, 0.5f);
+		OS.gtk_label_set_justify (labelHandle, OS.GTK_JUSTIFY_RIGHT);
+		OS.gtk_misc_set_alignment (imageHandle, 1.0f, 0.5f);
+		return;
+	}
+}
+
+void setBackgroundColor (GdkColor color) {
+	super.setBackgroundColor (color);
+	setBackgroundColor(fixedHandle, color);
+	if (labelHandle != 0) setBackgroundColor(labelHandle, color);
+	if (imageHandle != 0) setBackgroundColor(imageHandle, color);
+}
+
+void setFontDescription (int /*long*/ font) {
+	super.setFontDescription (font);
+	if (labelHandle != 0) OS.gtk_widget_modify_font (labelHandle, font);
+	if (imageHandle != 0) OS.gtk_widget_modify_font (imageHandle, font);
+}
+
+boolean setRadioSelection (boolean value) {
+	if ((style & SWT.RADIO) == 0) return false;
+	if (getSelection () != value) {
+		setSelection (value);
+		postEvent (SWT.Selection);
+	}
+	return true;
+}
+
+void setForegroundColor (GdkColor color) {
+	super.setForegroundColor (color);
+	setForegroundColor (fixedHandle, color);
+	if (labelHandle != 0) setForegroundColor (labelHandle, color);
+	if (imageHandle != 0) setForegroundColor (imageHandle, color);
+}
+
+/**
+ * Sets the receiver's image to the argument, which may be
+ * <code>null</code> indicating that no image should be displayed.
+ * <p>
+ * Note that a Button can display an image and text simultaneously
+ * on Windows (starting with XP), GTK+ and OSX.  On other platforms,
+ * a Button that has an image and text set into it will display the
+ * image or text that was set most recently.
+ * </p>
+ * @param image the image to display on the receiver (may be <code>null</code>)
+ *
+ * @exception IllegalArgumentException <ul>
+ *    <li>ERROR_INVALID_ARGUMENT - if the image has been disposed</li>
+ * </ul>
+ * @exception SWTException <ul>
+ *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setImage (Image image) {
+	checkWidget ();
+	if ((style & SWT.ARROW) != 0) return;
+	if (imageList != null) imageList.dispose ();
+	imageList = null;
+	if (image != null) {
+		if (image.isDisposed()) error (SWT.ERROR_INVALID_ARGUMENT);
+		imageList = new ImageList ();
+		int imageIndex = imageList.add (image);
+		int /*long*/ pixbuf = imageList.getPixbuf (imageIndex);
+		OS.gtk_image_set_from_pixbuf (imageHandle, pixbuf);
+		if (text.length () == 0) OS.gtk_widget_hide (labelHandle);
+		OS.gtk_widget_show (imageHandle);
+	} else {
+		OS.gtk_image_set_from_pixbuf (imageHandle, 0);
+		OS.gtk_widget_show (labelHandle);
+		OS.gtk_widget_hide (imageHandle);
+	}
+	this.image = image;
+	_setAlignment (style);
+}
+
+void setOrientation () {
+	super.setOrientation ();
+	if ((style & SWT.RIGHT_TO_LEFT) != 0) {
+		if (labelHandle != 0) OS.gtk_widget_set_direction (labelHandle, OS.GTK_TEXT_DIR_RTL);
+		if (imageHandle != 0) OS.gtk_widget_set_direction (imageHandle, OS.GTK_TEXT_DIR_RTL);
+		if (arrowHandle != 0) {
+			switch (style & (SWT.LEFT | SWT.RIGHT)) {
+				case SWT.LEFT: OS.gtk_arrow_set (arrowHandle, OS.GTK_ARROW_RIGHT, OS.GTK_SHADOW_OUT); break;
+				case SWT.RIGHT: OS.gtk_arrow_set (arrowHandle, OS.GTK_ARROW_LEFT, OS.GTK_SHADOW_OUT); break;
+			}
+		}
+	}
+}
+
+/**
+ * Sets the selection state of the receiver, if it is of type <code>CHECK</code>,
+ * <code>RADIO</code>, or <code>TOGGLE</code>.
+ *
+ * <p>
+ * When the receiver is of type <code>CHECK</code> or <code>RADIO</code>,
+ * it is selected when it is checked. When it is of type <code>TOGGLE</code>,
+ * it is selected when it is pushed in.
+ *
+ * @param selected the new selection state
+ *
+ * @exception SWTException <ul>
+ *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setSelection (boolean selected) {
+	checkWidget();
+	if ((style & (SWT.CHECK | SWT.RADIO | SWT.TOGGLE)) == 0) return;
+	OS.g_signal_handlers_block_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, CLICKED);
+	OS.gtk_toggle_button_set_active (handle, selected);
+	if ((style & SWT.RADIO) != 0) OS.gtk_toggle_button_set_active (groupHandle, !selected);
+	OS.g_signal_handlers_unblock_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, CLICKED);
+}
+
+/**
+ * Sets the receiver's text.
+ * <p>
+ * This method sets the button label.  The label may include
+ * the mnemonic character but must not contain line delimiters.
+ * </p>
+ * <p>
+ * Mnemonics are indicated by an '&amp;' that causes the next
+ * character to be the mnemonic.  When the user presses a
+ * key sequence that matches the mnemonic, a selection
+ * event occurs. On most platforms, the mnemonic appears
+ * underlined but may be emphasized in a platform specific
+ * manner.  The mnemonic indicator character '&amp;' can be
+ * escaped by doubling it in the string, causing a single
+ * '&amp;' to be displayed.
+ * </p><p>
+ * Note that a Button can display an image and text simultaneously
+ * on Windows (starting with XP), GTK+ and OSX.  On other platforms,
+ * a Button that has an image and text set into it will display the
+ * image or text that was set most recently.
+ * </p>
+ * @param string the new text
+ *
+ * @exception IllegalArgumentException <ul>
+ *    <li>ERROR_NULL_ARGUMENT - if the text is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setText (String string) {
+	checkWidget ();
+	if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
+	if ((style & SWT.ARROW) != 0) return;
+	text = string;
+	char [] chars = fixMnemonic (string);
+	byte [] buffer = Converter.wcsToMbcs (null, chars, true);
+	OS.gtk_label_set_text_with_mnemonic (labelHandle, buffer);
+	if (image == null) OS.gtk_widget_hide (imageHandle);
+	OS.gtk_widget_show (labelHandle);
+	_setAlignment (style);
+}
+
+void showWidget () {
+	super.showWidget ();
+	if (boxHandle != 0) OS.gtk_widget_show (boxHandle);
+	if (labelHandle != 0) OS.gtk_widget_show (labelHandle);
+	if (arrowHandle != 0) OS.gtk_widget_show (arrowHandle);
+}
+
+int traversalCode (int key, GdkEventKey event) {
+	int code = super.traversalCode (key, event);
+	if ((style & SWT.RADIO) != 0) code |= SWT.TRAVERSE_ARROW_NEXT | SWT.TRAVERSE_ARROW_PREVIOUS;
+	return code;
+}
+
+}
++/
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwt/widgets/Canvas.d	Thu Jan 10 05:17:47 2008 +0100
@@ -0,0 +1,338 @@
+/*******************************************************************************
+ * 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.widgets.Canvas;
+
+
+import dwt.graphics.Point;
+import dwt.internal.gtk.OS;
+import dwt.SWT;
+import dwt.widgets.Composite;
+import dwt.widgets.Caret;
+import dwt.widgets.Control;
+import dwt.graphics.GC;
+import dwt.graphics.Rectangle;
+import dwt.graphics.Font;
+
+/**
+ * Instances of this class provide a surface for drawing
+ * arbitrary graphics.
+ * <dl>
+ * <dt><b>Styles:</b></dt>
+ * <dd>(none)</dd>
+ * <dt><b>Events:</b></dt>
+ * <dd>(none)</dd>
+ * </dl>
+ * <p>
+ * This class may be subclassed by custom control implementors
+ * who are building controls that are <em>not</em> constructed
+ * from aggregates of other controls. That is, they are either
+ * painted using SWT graphics calls or are handled by native
+ * methods.
+ * </p>
+ *
+ * @see Composite
+ */
+public class Canvas : Composite {
+	Caret caret;
+
+this () {}
+
+/**
+ * Constructs a new instance of this class given its parent
+ * and a style value describing its behavior and appearance.
+ * <p>
+ * The style value is either one of the style constants defined in
+ * class <code>SWT</code> which is applicable to instances of this
+ * class, or must be built by <em>bitwise OR</em>'ing together
+ * (that is, using the <code>int</code> "|" operator) two or more
+ * of those <code>SWT</code> style constants. The class description
+ * lists the style constants that are applicable to the class.
+ * Style bits are also inherited from superclasses.
+ * </p>
+ *
+ * @param parent a composite control which will be the parent of the new instance (cannot be null)
+ * @param style the style of control to construct
+ *
+ * @exception IllegalArgumentException <ul>
+ *    <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * </ul>
+ *
+ * @see SWT
+ * @see Widget#checkSubclass
+ * @see Widget#getStyle
+ */
+public this (Composite parent, int style) {
+	super (parent, style);
+}
+
+/**
+ * Fills the interior of the rectangle specified by the arguments,
+ * with the receiver's background.
+ *
+ * @param gc the gc where the rectangle is to be filled
+ * @param x the x coordinate of the rectangle to be filled
+ * @param y the y coordinate of the rectangle to be filled
+ * @param width the width of the rectangle to be filled
+ * @param height the height of the rectangle to be filled
+ *
+ * @exception IllegalArgumentException <ul>
+ *    <li>ERROR_NULL_ARGUMENT - if the gc is null</li>
+ *    <li>ERROR_INVALID_ARGUMENT - if the gc has been disposed</li>
+ * </ul>
+ * @exception SWTException <ul>
+ *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.2
+ */
+public void drawBackground (GC gc, int x, int y, int width, int height) {
+	checkWidget ();
+	if (gc is null) error (SWT.ERROR_NULL_ARGUMENT);
+	if (gc.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT);
+	super.drawBackground (gc, x, y, width, height);
+}
+
+/**
+ * Returns the caret.
+ * <p>
+ * The caret for the control is automatically hidden
+ * and shown when the control is painted or resized,
+ * when focus is gained or lost and when an the control
+ * is scrolled.  To avoid drawing on top of the caret,
+ * the programmer must hide and show the caret when
+ * drawing in the window any other time.
+ * </p>
+ *
+ * @return the caret
+ *
+ * @exception SWTException <ul>
+ *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public Caret getCaret () {
+	checkWidget();
+	return caret;
+}
+
+Point getIMCaretPos () {
+	if (caret is null) return super.getIMCaretPos ();
+	return new Point (caret.x, caret.y);
+}
+
+override int /*long*/ gtk_expose_event (GtkWidget* widget, GdkEventExpose* event) {
+	if ((state & OBSCURED) !is 0) return 0;
+	bool isFocus = caret !is null && caret.isFocusCaret ();
+	if (isFocus) caret.killFocus ();
+	auto result = super.gtk_expose_event (widget, event);
+	if (isFocus) caret.setFocus ();
+	return result;
+}
+
+override int /*long*/ gtk_focus_in_event (GtkWidget* widget, GdkEventFocus* event) {
+	auto result = super.gtk_focus_in_event (widget, event);
+	if (caret !is null) caret.setFocus ();
+	return result;
+}
+
+override int /*long*/ gtk_focus_out_event (GtkWidget* widget, GdkEventFocus* event) {
+	auto result = super.gtk_focus_out_event (widget, event);
+	if (caret !is null) caret.killFocus ();
+	return result;
+}
+
+void redrawWidget (int x, int y, int width, int height, bool redrawAll, bool all, bool trim) {
+	bool isFocus = caret !is null && caret.isFocusCaret ();
+	if (isFocus) caret.killFocus ();
+	super.redrawWidget (x, y, width, height, redrawAll, all, trim);
+	if (isFocus) caret.setFocus ();
+}
+
+void releaseChildren (bool destroy) {
+	if (caret !is null) {
+		caret.release (false);
+		caret = null;
+	}
+	super.releaseChildren (destroy);
+}
+
+/**
+ * Scrolls a rectangular area of the receiver by first copying
+ * the source area to the destination and then causing the area
+ * of the source which is not covered by the destination to
+ * be repainted. Children that intersect the rectangle are
+ * optionally moved during the operation. In addition, outstanding
+ * paint events are flushed before the source area is copied to
+ * ensure that the contents of the canvas are drawn correctly.
+ *
+ * @param destX the x coordinate of the destination
+ * @param destY the y coordinate of the destination
+ * @param x the x coordinate of the source
+ * @param y the y coordinate of the source
+ * @param width the width of the area
+ * @param height the height of the area
+ * @param all <code>true</code>if children should be scrolled, and <code>false</code> otherwise
+ *
+ * @exception SWTException <ul>
+ *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void scroll (int destX, int destY, int x, int y, int width, int height, bool all) {
+	checkWidget();
+	if (width <= 0 || height <= 0) return;
+	int deltaX = destX - x, deltaY = destY - y;
+	if (deltaX is 0 && deltaY is 0) return;
+	if (!isVisible ()) return;
+	bool isFocus = caret !is null && caret.isFocusCaret ();
+	if (isFocus) caret.killFocus ();
+	auto window = paintWindow ();
+	auto visibleRegion = OS.gdk_drawable_get_visible_region (window);
+	GdkRectangle* srcRect = new GdkRectangle ();
+	srcRect.x = x;
+	srcRect.y = y;
+	srcRect.width = width;
+	srcRect.height = height;
+	auto copyRegion = OS.gdk_region_rectangle (srcRect);
+	OS.gdk_region_intersect(copyRegion, visibleRegion);
+	auto invalidateRegion = OS.gdk_region_rectangle (srcRect);
+	OS.gdk_region_subtract (invalidateRegion, visibleRegion);
+	OS.gdk_region_offset (invalidateRegion, deltaX, deltaY);
+	GdkRectangle* copyRect = new GdkRectangle();
+	OS.gdk_region_get_clipbox (copyRegion, copyRect);
+	if (copyRect.width !is 0 && copyRect.height !is 0) {
+		update ();
+	}
+	Control control = findBackgroundControl ();
+	if (control is null) control = this;
+	if (control.backgroundImage !is null) {
+		redrawWidget (x, y, width, height, false, false, false);
+		redrawWidget (destX, destY, width, height, false, false, false);
+	} else {
+//		GC gc = new GC (this);
+//		gc.copyArea (x, y, width, height, destX, destY);
+//		gc.dispose ();
+		auto gdkGC = OS.gdk_gc_new (window);
+		OS.gdk_gc_set_exposures (gdkGC, true);
+		OS.gdk_draw_drawable (window, gdkGC, window, copyRect.x, copyRect.y, copyRect.x + deltaX, copyRect.y + deltaY, copyRect.width, copyRect.height);
+		OS.g_object_unref (gdkGC);
+		bool disjoint = (destX + width < x) || (x + width < destX) || (destY + height < y) || (y + height < destY);
+		if (disjoint) {
+			GdkRectangle* rect = new GdkRectangle ();
+			rect.x = x;
+			rect.y = y;
+			rect.width = width;
+			rect.height = height;
+			OS.gdk_region_union_with_rect (invalidateRegion, rect);
+		} else {
+			GdkRectangle* rect = new GdkRectangle ();
+			if (deltaX !is 0) {
+				int newX = destX - deltaX;
+				if (deltaX < 0) newX = destX + width;
+				rect.x = newX;
+				rect.y = y;
+				rect.width = Math.abs(deltaX);
+				rect.height = height;
+				OS.gdk_region_union_with_rect (invalidateRegion, rect);
+			}
+			if (deltaY !is 0) {
+				int newY = destY - deltaY;
+				if (deltaY < 0) newY = destY + height;
+				rect.x = x;
+				rect.y = newY;
+				rect.width = width;
+				rect.height = Math.abs(deltaY);
+				OS.gdk_region_union_with_rect (invalidateRegion, rect);
+			}
+		}
+		OS.gdk_window_invalidate_region(window, invalidateRegion, all);
+		OS.gdk_region_destroy (visibleRegion);
+		OS.gdk_region_destroy (copyRegion);
+		OS.gdk_region_destroy (invalidateRegion);
+	}
+	if (all) {
+		Control [] children = _getChildren ();
+		for (int i=0; i<children.length; i++) {
+			Control child = children [i];
+			Rectangle rect = child.getBounds ();
+			if (Math.min(x + width, rect.x + rect.width) >= Math.max (x, rect.x) &&
+				Math.min(y + height, rect.y + rect.height) >= Math.max (y, rect.y)) {
+					child.setLocation (rect.x + deltaX, rect.y + deltaY);
+			}
+		}
+	}
+	if (isFocus) caret.setFocus ();
+}
+
+int setBounds (int x, int y, int width, int height, bool move, bool resize) {
+	bool isFocus = caret !is null && caret.isFocusCaret ();
+	if (isFocus) caret.killFocus ();
+	int result = super.setBounds (x, y, width, height, move, resize);
+	if (isFocus) caret.setFocus ();
+	return result;
+}
+
+/**
+ * Sets the receiver's caret.
+ * <p>
+ * The caret for the control is automatically hidden
+ * and shown when the control is painted or resized,
+ * when focus is gained or lost and when an the control
+ * is scrolled.  To avoid drawing on top of the caret,
+ * the programmer must hide and show the caret when
+ * drawing in the window any other time.
+ * </p>
+ * @param caret the new caret for the receiver, may be null
+ *
+ * @exception IllegalArgumentException <ul>
+ *    <li>ERROR_INVALID_ARGUMENT - if the caret has been disposed</li>
+ * </ul>
+ * @exception SWTException <ul>
+ *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setCaret (Caret caret) {
+	checkWidget();
+	Caret newCaret = caret;
+	Caret oldCaret = this.caret;
+	this.caret = newCaret;
+	if (hasFocus ()) {
+		if (oldCaret !is null) oldCaret.killFocus ();
+		if (newCaret !is null) {
+			if (newCaret.isDisposed()) error(SWT.ERROR_INVALID_ARGUMENT);
+			newCaret.setFocus ();
+		}
+	}
+}
+
+public void setFont (Font font) {
+	checkWidget();
+	if (caret !is null) caret.setFont (font);
+	super.setFont (font);
+}
+
+void updateCaret () {
+	auto imHandle = imHandle ();
+	if (imHandle is null) return;
+	GdkRectangle* rect = new GdkRectangle ();
+	rect.x = caret.x;
+	rect.y = caret.y;
+	rect.width = caret.width;
+	rect.height = caret.height;
+	OS.gtk_im_context_set_cursor_location (imHandle, rect);
+}
+
+}
--- a/dwt/widgets/Caret.d	Thu Jan 10 05:01:46 2008 +0100
+++ b/dwt/widgets/Caret.d	Thu Jan 10 05:17:47 2008 +0100
@@ -9,10 +9,18 @@
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
 module dwt.widgets.Caret;
-
+import dwt.graphics.Font;
 class Caret{
     int blinkRate;
     bool blinkCaret();
+    int x, y, width, height;
+
+    bool isFocusCaret () ;
+    void killFocus () ;
+    void setFocus ();
+    void release(bool);
+    bool isDisposed();
+    public void setFont (Font font) ;
 }
 /+++
 
--- a/dwt/widgets/Composite.d	Thu Jan 10 05:01:46 2008 +0100
+++ b/dwt/widgets/Composite.d	Thu Jan 10 05:17:47 2008 +0100
@@ -705,17 +705,17 @@
 	return result;
 }
 
-override int /*long*/ gtk_focus (GtkWidget* widget, int /*long*/ directionType) {
+override int /*long*/ gtk_focus (GtkWidget* widget, GdkEventFocus* directionType) {
 	if (widget is socketHandle) return 0;
 	return super.gtk_focus (widget, directionType);
 }
 
-override int /*long*/ gtk_focus_in_event (GtkWidget* widget, int /*long*/ event) {
+override int /*long*/ gtk_focus_in_event (GtkWidget* widget, GdkEventFocus* event) {
 	int /*long*/ result = super.gtk_focus_in_event (widget, event);
 	return (state & CANVAS) !is 0 ? 1 : result;
 }
 
-override int /*long*/ gtk_focus_out_event (GtkWidget* widget, int /*long*/ event) {
+override int /*long*/ gtk_focus_out_event (GtkWidget* widget, GdkEventFocus* event) {
 	auto result = super.gtk_focus_out_event (widget, event);
 	return (state & CANVAS) !is 0 ? 1 : result;
 }
--- a/dwt/widgets/Control.d	Thu Jan 10 05:01:46 2008 +0100
+++ b/dwt/widgets/Control.d	Thu Jan 10 05:17:47 2008 +0100
@@ -2350,7 +2350,7 @@
 	return (state & HIDDEN) is 0;
 }
 
-int /*long*/ gtk_button_press_event (GtkWidget* widget, GdkEventButton* event) {
+override int /*long*/ gtk_button_press_event (GtkWidget* widget, GdkEventButton* event) {
 	GdkEventButton* gdkEvent = new GdkEventButton ();
 	memmove (gdkEvent, event, GdkEventButton.sizeof);
 	if (gdkEvent.type is OS.GDK_3BUTTON_PRESS) return 0;
@@ -2414,7 +2414,7 @@
 	return result;
 }
 
-int /*long*/ gtk_button_release_event (GtkWidget* widget, GdkEventButton* event) {
+override int /*long*/ gtk_button_release_event (GtkWidget* widget, GdkEventButton* event) {
 	GdkEventButton* gdkEvent = new GdkEventButton ();
 	memmove (gdkEvent, event, GdkEventButton.sizeof);
 	/*
@@ -2433,14 +2433,14 @@
 	return sendMouseEvent (SWT.MouseUp, button, display.clickCount, 0, false, gdkEvent.time, gdkEvent.x_root, gdkEvent.y_root, false, gdkEvent.state) ? 0 : 1;
 }
 
-int /*long*/ gtk_commit (GtkIMContext* imcontext, char* text) {
+override int /*long*/ gtk_commit (GtkIMContext* imcontext, char* text) {
 	char [] chars = fromUtf8z( text );
     if (chars.length is 0) return 0;
 	sendIMKeyEvent (SWT.KeyDown, null, chars);
 	return 0;
 }
 
-int /*long*/ gtk_enter_notify_event (GtkWidget*  widget, GdkEventCrossing* event) {
+override int /*long*/ gtk_enter_notify_event (GtkWidget*  widget, GdkEventCrossing* event) {
 	if (display.currentControl is this) return 0;
 	GdkEventCrossing* gdkEvent = new GdkEventCrossing ();
 	memmove (gdkEvent, event, GdkEventCrossing.sizeof);
@@ -2457,7 +2457,7 @@
 	return 0;
 }
 
-int /*long*/ gtk_event_after (GtkWidget*  widget, GdkEvent* gdkEvent) {
+override int /*long*/ gtk_event_after (GtkWidget*  widget, GdkEvent* gdkEvent) {
 	GdkEvent* event = new GdkEvent ();
 	memmove (event, gdkEvent, GdkEvent.sizeof);
 	switch (cast(int)event.type) {
@@ -2513,7 +2513,7 @@
 	return 0;
 }
 
-int /*long*/ gtk_expose_event (GtkWidget*  widget, GdkEventExpose* eventPtr) {
+override int /*long*/ gtk_expose_event (GtkWidget*  widget, GdkEventExpose* eventPtr) {
 	if ((state & OBSCURED) !is 0) return 0;
 	if (!hooks (SWT.Paint) && !filters (SWT.Paint)) return 0;
 	GdkEventExpose* gdkEvent = new GdkEventExpose ();
@@ -2534,12 +2534,12 @@
 	return 0;
 }
 
-int /*long*/ gtk_focus (GtkWidget* widget, int /*long*/ directionType) {
+override int /*long*/ gtk_focus (GtkWidget* widget, GdkEventFocus* directionType) {
 	/* Stop GTK traversal for every widget */
 	return 1;
 }
 
-int /*long*/ gtk_focus_in_event (GtkWidget*  widget, int /*long*/ event) {
+override int /*long*/ gtk_focus_in_event (GtkWidget*  widget, GdkEventFocus* event) {
 	// widget could be disposed at this point
 	if (handle !is null) {
 		Control oldControl = display.imControl;
@@ -2557,7 +2557,7 @@
 	return 0;
 }
 
-int /*long*/ gtk_focus_out_event (GtkWidget* widget, int /*long*/ event) {
+override int /*long*/ gtk_focus_out_event (GtkWidget* widget, GdkEventFocus* event) {
 	// widget could be disposed at this point
 	if (handle !is null) {
 		if (hooks (SWT.KeyDown) || hooks (SWT.KeyUp)) {
@@ -2570,7 +2570,7 @@
 	return 0;
 }
 
-int /*long*/ gtk_key_press_event (GtkWidget*  widget, GdkEventKey* event) {
+override int /*long*/ gtk_key_press_event (GtkWidget*  widget, GdkEventKey* event) {
 	if (!hasFocus ()) return 0;
 	GdkEventKey* gdkEvent = new GdkEventKey ();
 	memmove (gdkEvent, event, GdkEventKey.sizeof);
@@ -2589,7 +2589,7 @@
 	return super.gtk_key_press_event (widget, event);
 }
 
-int /*long*/ gtk_key_release_event (GtkWidget*  widget, GdkEventKey* event) {
+override int /*long*/ gtk_key_release_event (GtkWidget*  widget, GdkEventKey* event) {
 	if (!hasFocus ()) return 0;
 	auto imHandle = imHandle ();
 	if (imHandle !is null) {
@@ -2598,7 +2598,7 @@
 	return super.gtk_key_release_event (widget, event);
 }
 
-int /*long*/ gtk_leave_notify_event (GtkWidget* widget, GdkEventCrossing* event) {
+override int /*long*/ gtk_leave_notify_event (GtkWidget* widget, GdkEventCrossing* event) {
 	if (display.currentControl !is this) return 0;
 	display.removeMouseHoverTimeout (handle);
 	int result = 0;
@@ -2613,7 +2613,7 @@
 	return result;
 }
 
-int /*long*/ gtk_mnemonic_activate (GtkWidget* widget, int /*long*/ arg1) {
+override int /*long*/ gtk_mnemonic_activate (GtkWidget* widget, int /*long*/ arg1) {
 	int result = 0;
 	auto eventPtr = OS.gtk_get_current_event ();
 	if (eventPtr !is null) {
@@ -2634,7 +2634,7 @@
 	return result;
 }
 
-int /*long*/ gtk_motion_notify_event (GtkWidget* widget, GdkEventMotion* event) {
+override int /*long*/ gtk_motion_notify_event (GtkWidget* widget, GdkEventMotion* event) {
 	GdkEventMotion* gdkEvent = new GdkEventMotion ();
 	memmove (gdkEvent, event, GdkEventMotion.sizeof);
 	if (this is display.currentControl && (hooks (SWT.MouseHover) || filters (SWT.MouseHover))) {
@@ -2655,19 +2655,19 @@
 	return result;
 }
 
-int /*long*/ gtk_popup_menu (GtkWidget* widget) {
+override int /*long*/ gtk_popup_menu (GtkWidget* widget) {
 	if (!hasFocus()) return 0;
 	int x, y ;
 	OS.gdk_window_get_pointer (null, &x, &y, null);
 	return showMenu (x, y) ? 1 : 0;
 }
 
-int /*long*/ gtk_preedit_changed (int /*long*/ imcontext) {
+override int /*long*/ gtk_preedit_changed (GtkIMContext* imcontext) {
 	display.showIMWindow (this);
 	return 0;
 }
 
-int /*long*/ gtk_realize (GtkWidget* widget) {
+override int /*long*/ gtk_realize (GtkWidget* widget) {
 	auto imHandle = imHandle ();
 	if (imHandle !is null) {
 		auto window = OS.GTK_WIDGET_WINDOW (paintHandle ());
@@ -2680,7 +2680,7 @@
 	return 0;
 }
 
-int /*long*/ gtk_scroll_event (GtkWidget* widget, GdkEventScroll* eventPtr) {
+override int /*long*/ gtk_scroll_event (GtkWidget* widget, GdkEventScroll* eventPtr) {
 	GdkEventScroll* gdkEvent = new GdkEventScroll ();
 	memmove (gdkEvent, eventPtr, GdkEventScroll.sizeof);
 	switch (cast(int)gdkEvent.direction) {
@@ -2696,25 +2696,25 @@
 	return 0;
 }
 
-int /*long*/ gtk_show_help (GtkWidget* widget, int /*long*/ helpType) {
+override int /*long*/ gtk_show_help (GtkWidget* widget, int /*long*/ helpType) {
 	if (!hasFocus ()) return 0;
 	return sendHelpEvent (helpType) ? 1 : 0;
 }
 
-int /*long*/ gtk_style_set (GtkWidget* widget, int /*long*/ previousStyle) {
+override int /*long*/ gtk_style_set (GtkWidget* widget, int /*long*/ previousStyle) {
 	if (backgroundImage !is null) {
 		setBackgroundPixmap (backgroundImage.pixmap);
 	}
 	return 0;
 }
 
-int /*long*/ gtk_unrealize (GtkWidget* widget) {
+override int /*long*/ gtk_unrealize (GtkWidget* widget) {
 	auto imHandle = imHandle ();
 	if (imHandle !is null) OS.gtk_im_context_set_client_window (imHandle, null);
 	return 0;
 }
 
-int /*long*/ gtk_visibility_notify_event (GtkWidget* widget, GdkEventVisibility* event) {
+override int /*long*/ gtk_visibility_notify_event (GtkWidget* widget, GdkEventVisibility* event) {
 	GdkEventVisibility* gdkEvent = new GdkEventVisibility ();
 	memmove (gdkEvent, event, GdkEventVisibility.sizeof);
 	auto paintWindow = paintWindow();
@@ -2737,7 +2737,7 @@
 	return 0;
 }
 
-void gtk_widget_size_request (GtkWidget* widget, GtkRequisition* requisition) {
+/*no override*/ void gtk_widget_size_request (GtkWidget* widget, GtkRequisition* requisition) {
 	OS.gtk_widget_size_request (widget, requisition);
 }
 
--- a/dwt/widgets/Decorations.d	Thu Jan 10 05:01:46 2008 +0100
+++ b/dwt/widgets/Decorations.d	Thu Jan 10 05:17:47 2008 +0100
@@ -14,14 +14,16 @@
 import dwt.widgets.Menu;
 import dwt.widgets.Composite;
 
-class Decorations : Composite {
-    void fixDecorations (Decorations newDecorations, Control control, Menu [] menus);
-    void fixAccelGroup () ;
-}
-/+
-import dwt.*;
-import dwt.internal.gtk.*;
-import dwt.graphics.*;
+import dwt.SWT;
+import dwt.internal.gtk.OS;
+//import dwt.graphics.;
+import dwt.widgets.Canvas;
+import dwt.graphics.Image;
+import dwt.graphics.ImageData;
+import dwt.widgets.Control;
+import dwt.widgets.Display;
+import dwt.widgets.Widget;
+import dwt.widgets.Button;
 
 /**
  * Instances of this class provide the appearance and
@@ -100,18 +102,19 @@
  * @see Shell
  * @see SWT
  */
-public class Decorations extends Canvas {
-	String text;
+public class Decorations : Canvas {
+	char[] text;
 	Image image;
-	Image [] images = new Image [0];
-	boolean minimized, maximized;
+	Image [] images;
+	bool minimized, maximized;
 	Menu menuBar;
 	Menu [] menus;
 	Control savedFocus;
 	Button defaultButton, saveDefault;
-	int /*long*/ accelGroup, vboxHandle;
+	GtkAccelGroup* accelGroup;
+    int vboxHandle;
 
-Decorations () {
+this () {
 	/* Do nothing */
 }
 
@@ -153,15 +156,15 @@
  * @see Widget#checkSubclass
  * @see Widget#getStyle
  */
-public Decorations (Composite parent, int style) {
+public this (Composite parent, int style) {
 	super (parent, checkStyle (style));
 }
 
 static int checkStyle (int style) {
-	if ((style & SWT.NO_TRIM) != 0) {
+	if ((style & SWT.NO_TRIM) !is 0) {
 		style &= ~(SWT.CLOSE | SWT.TITLE | SWT.MIN | SWT.MAX | SWT.RESIZE | SWT.BORDER);
 	}
-	if ((style & (SWT.MENU | SWT.MIN | SWT.MAX | SWT.CLOSE)) != 0) {
+	if ((style & (SWT.MENU | SWT.MIN | SWT.MAX | SWT.CLOSE)) !is 0) {
 		style |= SWT.TITLE;
 	}
 	return style;
@@ -172,35 +175,35 @@
 }
 
 void _setImages (Image [] images) {
-	if (images != null && images.length > 1) {
+	if (images !is null && images.length > 1) {
 		Image [] bestImages = new Image [images.length];
 		System.arraycopy (images, 0, bestImages, 0, images.length);
 		sort (bestImages);
 		images = bestImages;
 	}
-	int /*long*/ pixbufs = 0;
-	if (images != null) {
+	GList* pixbufs;
+	if (images !is null) {
 		for (int i = 0; i < images.length; i++) {
 			Image image = images [i];
-			int /*long*/ pixbuf = Display.createPixbuf (image);
+			auto pixbuf = Display.createPixbuf (image);
 			pixbufs = OS.g_list_append (pixbufs, pixbuf);
 		}
 	}
-	OS.gtk_window_set_icon_list (topHandle (), pixbufs);
-	int /*long*/ [] data = new int /*long*/ [1];
-	int /*long*/ temp = pixbufs;
-	while (temp != 0) {
-		OS.memmove (data, temp, OS.PTR_SIZEOF);
-		OS.g_object_unref (data [0]);
-		temp = OS.g_list_next (temp);
+	OS.gtk_window_set_icon_list (cast(GtkWindow*)topHandle (), pixbufs);
+	GList* data;
+	auto temp = pixbufs;
+	while (temp !is null) {
+		data = temp;
+		OS.g_object_unref (data);
+		temp = cast(GList*)OS.g_list_next (temp);
 	}
-	if (pixbufs != 0) OS.g_list_free (pixbufs);
+	if (pixbufs !is null) OS.g_list_free (pixbufs);
 }
 
 void addMenu (Menu menu) {
-	if (menus == null) menus = new Menu [4];
+	if (menus is null) menus = new Menu [4];
 	for (int i=0; i<menus.length; i++) {
-		if (menus [i] == null) {
+		if (menus [i] is null) {
 			menus [i] = menu;
 			return;
 		}
@@ -212,15 +215,15 @@
 }
 
 int compare (ImageData data1, ImageData data2) {
-	if (data1.width == data2.width && data1.height == data2.height) {
+	if (data1.width is data2.width && data1.height is data2.height) {
 		int transparent1 = data1.getTransparencyType ();
 		int transparent2 = data2.getTransparencyType ();
-		if (transparent1 == SWT.TRANSPARENCY_ALPHA) return -1;
-		if (transparent2 == SWT.TRANSPARENCY_ALPHA) return 1;
-		if (transparent1 == SWT.TRANSPARENCY_MASK) return -1;
-		if (transparent2 == SWT.TRANSPARENCY_MASK) return 1;
-		if (transparent1 == SWT.TRANSPARENCY_PIXEL) return -1;
-		if (transparent2 == SWT.TRANSPARENCY_PIXEL) return 1;
+		if (transparent1 is SWT.TRANSPARENCY_ALPHA) return -1;
+		if (transparent2 is SWT.TRANSPARENCY_ALPHA) return 1;
+		if (transparent1 is SWT.TRANSPARENCY_MASK) return -1;
+		if (transparent2 is SWT.TRANSPARENCY_MASK) return 1;
+		if (transparent1 is SWT.TRANSPARENCY_PIXEL) return -1;
+		if (transparent2 is SWT.TRANSPARENCY_PIXEL) return 1;
 		return 0;
 	}
 	return data1.width > data2.width || data1.height > data2.height ? -1 : 1;
@@ -235,12 +238,12 @@
 }
 
 void createAccelGroup () {
-	if (accelGroup != 0) return;
+	if (accelGroup !is null) return;
 	accelGroup = OS.gtk_accel_group_new ();
-	if (accelGroup == 0) SWT.error (SWT.ERROR_NO_HANDLES);
+	if (accelGroup is null) SWT.error (SWT.ERROR_NO_HANDLES);
 	//FIXME - what should we do for Decorations
-	int /*long*/ shellHandle = topHandle ();
-	OS.gtk_window_add_accel_group (shellHandle, accelGroup);
+	auto shellHandle = topHandle ();
+	OS.gtk_window_add_accel_group (cast(GtkWindow*)shellHandle, accelGroup);
 }
 
 void createWidget (int index) {
@@ -249,32 +252,32 @@
 }
 
 void destroyAccelGroup () {
-	if (accelGroup == 0) return;
-	int /*long*/ shellHandle = topHandle ();
-	OS.gtk_window_remove_accel_group (shellHandle, accelGroup);
+	if (accelGroup is null) return;
+	auto shellHandle = topHandle ();
+	OS.gtk_window_remove_accel_group (cast(GtkWindow*)shellHandle, accelGroup);
 	//TEMPORARY CODE
 //	OS.g_object_unref (accelGroup);
-	accelGroup = 0;
+	accelGroup = null;
 }
 
 void fixAccelGroup () {
-	if (menuBar == null) return;
+	if (menuBar is null) return;
 	destroyAccelGroup ();
 	createAccelGroup ();
 	menuBar.addAccelerators (accelGroup);
 }
 
 void fixDecorations (Decorations newDecorations, Control control, Menu [] menus) {
-	if (this == newDecorations) return;
-	if (control == savedFocus) savedFocus = null;
-	if (control == defaultButton) defaultButton = null;
-	if (control == saveDefault) saveDefault = null;
-	if (menus == null) return;
+	if (this is newDecorations) return;
+	if (control is savedFocus) savedFocus = null;
+	if (control is defaultButton) defaultButton = null;
+	if (control is saveDefault) saveDefault = null;
+	if (menus is null) return;
 	Menu menu = control.menu;
-	if (menu != null) {
+	if (menu !is null) {
 		int index = 0;
 		while (index <menus.length) {
-			if (menus [index] == menu) {
+			if (menus [index] is menu) {
 				control.setMenu (null);
 				return;
 			}
@@ -299,7 +302,7 @@
  */
 public Button getDefaultButton () {
 	checkWidget();
-	return defaultButton != null ? defaultButton : saveDefault;
+	return defaultButton !is null ? defaultButton : saveDefault;
 }
 
 /**
@@ -357,7 +360,7 @@
  */
 public Image [] getImages () {
 	checkWidget ();
-	if (images == null) return new Image [0];
+	if (images is null) return new Image [0];
 	Image [] result = new Image [images.length];
 	System.arraycopy (images, 0, result, 0, images.length);
 	return result;
@@ -377,7 +380,7 @@
  *
  * @see #setMaximized
  */
-public boolean getMaximized () {
+public bool getMaximized () {
 	checkWidget();
 	return maximized;
 }
@@ -412,12 +415,12 @@
  *
  * @see #setMinimized
  */
-public boolean getMinimized () {
+public bool getMinimized () {
 	checkWidget();
 	return minimized;
 }
 
-String getNameText () {
+char[] getNameText () {
 	return getText ();
 }
 
@@ -434,21 +437,21 @@
  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
  * </ul>
  */
-public String getText () {
+public char[] getText () {
 	checkWidget();
 	return text;
 }
 
-public boolean isReparentable () {
+public bool isReparentable () {
 	checkWidget ();
 	return false;
 }
 
-boolean isTabGroup () {
+bool isTabGroup () {
 	return true;
 }
 
-boolean isTabItem () {
+bool isTabItem () {
 	return false;
 }
 
@@ -457,25 +460,25 @@
 }
 
 void removeMenu (Menu menu) {
-	if (menus == null) return;
+	if (menus is null) return;
 	for (int i=0; i<menus.length; i++) {
-		if (menus [i] == menu) {
+		if (menus [i] is menu) {
 			menus [i] = null;
 			return;
 		}
 	}
 }
 
-void releaseChildren (boolean destroy) {
-	if (menuBar != null) {
+void releaseChildren (bool destroy) {
+	if (menuBar !is null) {
 		menuBar.release (false);
 		menuBar = null;
 	}
 	super.releaseChildren (destroy);
-	if (menus != null) {
+	if (menus !is null) {
 		for (int i=0; i<menus.length; i++) {
 			Menu menu = menus [i];
-			if (menu != null && !menu.isDisposed ()) {
+			if (menu !is null && !menu.isDisposed ()) {
 				menu.dispose ();
 			}
 		}
@@ -496,9 +499,9 @@
 	defaultButton = saveDefault = null;
 }
 
-boolean restoreFocus () {
-	if (savedFocus != null && savedFocus.isDisposed ()) savedFocus = null;
-	boolean restored = savedFocus != null && savedFocus.setFocus ();
+bool restoreFocus () {
+	if (savedFocus !is null && savedFocus.isDisposed ()) savedFocus = null;
+	bool restored = savedFocus !is null && savedFocus.setFocus ();
 	savedFocus = null;
 	/*
 	* This code is intentionally commented.  When no widget
@@ -506,7 +509,7 @@
 	* default button.  Motif doesn't do this.
 	*/
 //	if (restored) return true;
-//	if (defaultButton != null && !defaultButton.isDisposed ()) {
+//	if (defaultButton !is null && !defaultButton.isDisposed ()) {
 //		if (defaultButton.setFocus ()) return true;
 //	}
 //	return false;
@@ -540,14 +543,14 @@
  */
 public void setDefaultButton (Button button) {
 	checkWidget();
-	int /*long*/ buttonHandle = 0;
-	if (button != null) {
+	GtkWidget* buttonHandle;
+	if (button !is null) {
 		if (button.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT);
-		if (button.menuShell () != this) error (SWT.ERROR_INVALID_PARENT);
+		if (button.menuShell () !is this) error (SWT.ERROR_INVALID_PARENT);
 		buttonHandle = button.handle;
 	}
 	saveDefault = defaultButton = button;
-	OS.gtk_window_set_default (topHandle (), buttonHandle);
+	OS.gtk_window_set_default (cast(GtkWindow*)topHandle (), buttonHandle);
 }
 
 /**
@@ -570,7 +573,7 @@
 public void setImage (Image image) {
 	checkWidget ();
 	this.image = image;
-	_setImages (image != null ? new Image [] {image} : null);
+	_setImages (image !is null ? [image] : null);
 }
 
 /**
@@ -599,9 +602,9 @@
  */
 public void setImages (Image [] images) {
 	checkWidget ();
-	if (images == null) error (SWT.ERROR_INVALID_ARGUMENT);
+	if (images is null) error (SWT.ERROR_INVALID_ARGUMENT);
 	for (int i = 0; i < images.length; i++) {
-		if (images [i] == null || images [i].isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT);
+		if (images [i] is null || images [i].isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT);
 	}
 	this.images = images;
 	_setImages (images);
@@ -630,7 +633,7 @@
  *
  * @see #setMinimized
  */
-public void setMaximized (boolean maximized) {
+public void setMaximized (bool maximized) {
 	checkWidget();
 	this.maximized = maximized;
 }
@@ -652,10 +655,10 @@
  */
 public void setMenuBar (Menu menu) {
 	checkWidget();
-	if (menuBar == menu) return;
-	if (menu != null) {
-		if ((menu.style & SWT.BAR) == 0) error (SWT.ERROR_MENU_NOT_BAR);
-		if (menu.parent != this) error (SWT.ERROR_INVALID_PARENT);
+	if (menuBar is menu) return;
+	if (menu !is null) {
+		if ((menu.style & SWT.BAR) is 0) error (SWT.ERROR_MENU_NOT_BAR);
+		if (menu.parent !is this) error (SWT.ERROR_INVALID_PARENT);
 	}
 	menuBar = menu;
 }
@@ -683,13 +686,13 @@
  *
  * @see #setMaximized
  */
-public void setMinimized (boolean minimized) {
+public void setMinimized (bool minimized) {
 	checkWidget();
 	this.minimized = minimized;
 }
 
 void setSavedFocus (Control control) {
-	if (this == control) return;
+	if (this is control) return;
 	savedFocus = control;
 }
 
@@ -708,9 +711,9 @@
  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
  * </ul>
  */
-public void setText (String string) {
+public void setText (char[] string) {
 	checkWidget();
-	if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
+	if (string is null) error (SWT.ERROR_NULL_ARGUMENT);
 	text = string;
 }
 
@@ -738,13 +741,13 @@
 	}
 }
 
-boolean traverseItem (boolean next) {
+bool traverseItem (bool next) {
 	return false;
 }
 
-boolean traverseReturn () {
-	Button button = defaultButton != null ? defaultButton: saveDefault;
-	if (button == null || button.isDisposed ()) return false;
+bool traverseReturn () {
+	Button button = defaultButton !is null ? defaultButton: saveDefault;
+	if (button is null || button.isDisposed ()) return false;
 	/*
 	* Bug in GTK.  When a default button that is disabled is
 	* activated using the Enter key, GTK GP's.  The fix is to
@@ -752,9 +755,8 @@
 	* key.
 	*/
 	if (!button.isVisible () || !button.isEnabled ()) return true;
-	int /*long*/ shellHandle = _getShell ().topHandle ();
-	return OS.gtk_window_activate_default (shellHandle);
+	auto shellHandle = _getShell ().topHandle ();
+	return cast(bool)OS.gtk_window_activate_default (cast(GtkWindow*)shellHandle);
 }
 
 }
-+/
\ No newline at end of file
--- a/dwt/widgets/Menu.d	Thu Jan 10 05:01:46 2008 +0100
+++ b/dwt/widgets/Menu.d	Thu Jan 10 05:17:47 2008 +0100
@@ -11,13 +11,16 @@
 module dwt.widgets.Menu;
 
 import dwt.widgets.Control;
-import dwt.internal.c.gtk;
+import dwt.widgets.Decorations;
+import dwt.internal.gtk.OS;
 
 class Menu : Control {
-bool isDisposed();
-void  dispose();
-void _setVisible (bool visible);
-void createIMMenu (GtkIMContext* imHandle) ;
+    bool isDisposed();
+    void  dispose();
+    void _setVisible (bool visible);
+    void createIMMenu (GtkIMContext* imHandle) ;
+    void addAccelerators(GtkAccelGroup*);
+    void fixMenus (Decorations newParent) ;
 }
 
 /+++
--- a/dwt/widgets/Widget.d	Thu Jan 10 05:01:46 2008 +0100
+++ b/dwt/widgets/Widget.d	Thu Jan 10 05:17:47 2008 +0100
@@ -575,11 +575,11 @@
 	return 0;
 }
 
-int /*long*/ gtk_button_press_event (GtkWidget* widget, int /*long*/ event) {
+int /*long*/ gtk_button_press_event (GtkWidget* widget, GdkEventButton* event) {
 	return 0;
 }
 
-int /*long*/ gtk_button_release_event (GtkWidget* widget, int /*long*/ event) {
+int /*long*/ gtk_button_release_event (GtkWidget* widget, GdkEventButton* event) {
 	return 0;
 }
 
@@ -595,7 +595,7 @@
 	return 0;
 }
 
-int /*long*/ gtk_commit (int /*long*/ imcontext, int /*long*/ text) {
+int /*long*/ gtk_commit (GtkIMContext* imcontext, char* text) {
 	return 0;
 }
 
@@ -619,15 +619,15 @@
 	return 0;
 }
 
-int /*long*/ gtk_enter_notify_event (GtkWidget* widget, int /*long*/ event) {
+int /*long*/ gtk_enter_notify_event (GtkWidget* widget, GdkEventCrossing* event) {
 	return 0;
 }
 
-int /*long*/ gtk_event (GtkWidget* widget, int /*long*/ event) {
+int /*long*/ gtk_event (GtkWidget* widget, GdkEvent* event) {
 	return 0;
 }
 
-int /*long*/ gtk_event_after (GtkWidget* widget, int /*long*/ event) {
+int /*long*/ gtk_event_after (GtkWidget* widget, GdkEvent* event) {
 	return 0;
 }
 
@@ -635,19 +635,19 @@
 	return 0;
 }
 
-int /*long*/ gtk_expose_event (GtkWidget* widget, int /*long*/ event) {
+int /*long*/ gtk_expose_event (GtkWidget* widget, GdkEventExpose* event) {
 	return 0;
 }
 
-int /*long*/ gtk_focus (GtkWidget* widget, int /*long*/ event) {
+int /*long*/ gtk_focus (GtkWidget* widget, GdkEventFocus* event) {
 	return 0;
 }
 
-int /*long*/ gtk_focus_in_event (GtkWidget* widget, int /*long*/ event) {
+int /*long*/ gtk_focus_in_event (GtkWidget* widget, GdkEventFocus* event) {
 	return 0;
 }
 
-int /*long*/ gtk_focus_out_event (GtkWidget* widget, int /*long*/ event) {
+int /*long*/ gtk_focus_out_event (GtkWidget* widget, GdkEventFocus* event) {
 	return 0;
 }
 
@@ -675,7 +675,7 @@
 	return sendKeyEvent (SWT.KeyUp, event) ? 0 : 1;
 }
 
-int /*long*/ gtk_leave_notify_event (GtkWidget* widget, int /*long*/ event) {
+int /*long*/ gtk_leave_notify_event (GtkWidget* widget, GdkEventCrossing* event) {
 	return 0;
 }
 
@@ -695,7 +695,7 @@
 	return 0;
 }
 
-int /*long*/ gtk_motion_notify_event (GtkWidget* widget, int /*long*/ event) {
+int /*long*/ gtk_motion_notify_event (GtkWidget* widget, GdkEventMotion* event) {
 	return 0;
 }
 
@@ -711,7 +711,7 @@
 	return 0;
 }
 
-int /*long*/ gtk_preedit_changed (GtkWidget* imcontext) {
+int /*long*/ gtk_preedit_changed (GtkIMContext* imcontext) {
 	return 0;
 }
 
@@ -727,7 +727,7 @@
 	return 0;
 }
 
-int /*long*/ gtk_scroll_event (GtkWidget* widget, int /*long*/ event) {
+int /*long*/ gtk_scroll_event (GtkWidget* widget, GdkEventScroll*  event) {
 	return 0;
 }
 
@@ -791,7 +791,7 @@
 	return 0;
 }
 
-int /*long*/ gtk_visibility_notify_event (GtkWidget* widget, int /*long*/ event) {
+int /*long*/ gtk_visibility_notify_event (GtkWidget* widget, GdkEventVisibility* event) {
 	return 0;
 }
 
@@ -1457,7 +1457,7 @@
 		case MONTH_CHANGED: return gtk_month_changed (handle);
 		case OUTPUT: return gtk_output (handle);
 		case POPUP_MENU: return gtk_popup_menu (handle);
-		case PREEDIT_CHANGED: return gtk_preedit_changed (handle);
+		case PREEDIT_CHANGED: return gtk_preedit_changed (cast(GtkIMContext*)handle);
 		case REALIZE: return gtk_realize (handle);
 		case SELECT: return gtk_select (cast(int)handle);
 		case SHOW: return gtk_show (handle);
@@ -1483,33 +1483,33 @@
 		case MOTION_NOTIFY_EVENT_INVERSE: {
 			return 1;
 		}
-		case BUTTON_PRESS_EVENT: return gtk_button_press_event (handle, arg0);
-		case BUTTON_RELEASE_EVENT: return gtk_button_release_event (handle, arg0);
-		case COMMIT: return gtk_commit (cast(int)handle, arg0);
+		case BUTTON_PRESS_EVENT: return gtk_button_press_event (handle, cast(GdkEventButton*)arg0);
+		case BUTTON_RELEASE_EVENT: return gtk_button_release_event (handle, cast(GdkEventButton*)arg0);
+		case COMMIT: return gtk_commit (cast(GtkIMContext*)handle, cast(char*)arg0);
 		case CONFIGURE_EVENT: return gtk_configure_event (handle, arg0);
 		case DELETE_EVENT: return gtk_delete_event (handle, arg0);
-		case ENTER_NOTIFY_EVENT: return gtk_enter_notify_event (handle, arg0);
-		case EVENT: return gtk_event (handle, arg0);
-		case EVENT_AFTER: return gtk_event_after (handle, arg0);
-		case EXPOSE_EVENT: return gtk_expose_event (handle, arg0);
-		case FOCUS: return gtk_focus (handle, arg0);
-		case FOCUS_IN_EVENT: return gtk_focus_in_event (handle, arg0);
-		case FOCUS_OUT_EVENT: return gtk_focus_out_event (handle, arg0);
+		case ENTER_NOTIFY_EVENT: return gtk_enter_notify_event (handle, cast(GdkEventCrossing*)arg0);
+		case EVENT: return gtk_event (handle, cast(GdkEvent*)arg0);
+		case EVENT_AFTER: return gtk_event_after (handle, cast(GdkEvent*)arg0);
+		case EXPOSE_EVENT: return gtk_expose_event (handle, cast(GdkEventExpose*)arg0);
+		case FOCUS: return gtk_focus (handle, cast(GdkEventFocus*)arg0);
+		case FOCUS_IN_EVENT: return gtk_focus_in_event (handle, cast(GdkEventFocus*)arg0);
+		case FOCUS_OUT_EVENT: return gtk_focus_out_event (handle, cast(GdkEventFocus*)arg0);
 		case KEY_PRESS_EVENT: return gtk_key_press_event (handle, cast(GdkEventKey*)arg0);
 		case KEY_RELEASE_EVENT: return gtk_key_release_event (handle, cast(GdkEventKey*)arg0);
 		case INPUT: return gtk_input (handle, arg0);
-		case LEAVE_NOTIFY_EVENT: return gtk_leave_notify_event (handle, arg0);
+		case LEAVE_NOTIFY_EVENT: return gtk_leave_notify_event (handle, cast(GdkEventCrossing*)arg0);
 		case MAP_EVENT: return gtk_map_event (handle, arg0);
 		case MNEMONIC_ACTIVATE: return gtk_mnemonic_activate (handle, arg0);
-		case MOTION_NOTIFY_EVENT: return gtk_motion_notify_event (handle, arg0);
+		case MOTION_NOTIFY_EVENT: return gtk_motion_notify_event (handle, cast(GdkEventMotion*)arg0);
 		case MOVE_FOCUS: return gtk_move_focus (handle, arg0);
-		case SCROLL_EVENT:	return gtk_scroll_event (handle, arg0);
+		case SCROLL_EVENT:	return gtk_scroll_event (handle, cast(GdkEventScroll*)arg0);
 		case SHOW_HELP: return gtk_show_help (handle, arg0);
 		case SIZE_ALLOCATE: return gtk_size_allocate (handle, arg0);
 		case STYLE_SET: return gtk_style_set (handle, arg0);
 		case TOGGLED: return gtk_toggled (cast(int)handle, arg0);
 		case UNMAP_EVENT: return gtk_unmap_event (handle, arg0);
-		case VISIBILITY_NOTIFY_EVENT: return gtk_visibility_notify_event (handle, arg0);
+		case VISIBILITY_NOTIFY_EVENT: return gtk_visibility_notify_event (handle, cast(GdkEventVisibility*)arg0);
 		case WINDOW_STATE_EVENT: return gtk_window_state_event (handle, arg0);
 		default: return 0;
 	}
--- a/todo.txt	Thu Jan 10 05:01:46 2008 +0100
+++ b/todo.txt	Thu Jan 10 05:17:47 2008 +0100
@@ -1,6 +1,6 @@
 Next Steps:
     * accessibility package (independant)
-    * Composite -> Canvas -> Decorations -> Shell
+    * Shell
 
 Questions:
     Whats needed at minimum to make a test with empty window?
@@ -57,16 +57,16 @@
 graphics/Transform                     // OK
 
 widgets/Button
-widgets/Canvas
+widgets/Canvas                         // OK
 widgets/Caret                          //
 widgets/ColorDialog
 widgets/Combo
-widgets/Composite
+widgets/Composite                      // OK
 widgets/Control                        // OK
 widgets/CoolBar
 widgets/CoolItem
 widgets/DateTime
-widgets/Decorations
+widgets/Decorations                    // OK
 widgets/Dialog
 widgets/DirectoryDialog
 widgets/Display                        // OK