/*
 * Java-Gnome Bindings Library
 *
 * Copyright 1998-2006 the Java-Gnome Team, all rights reserved.
 *
 * The Java-Gnome bindings library is free software distributed under
 * the terms of the GNU Library General Public License version 2.
 */

package org.gnu.gtk;

import java.lang.reflect.Method;
import java.util.Vector;

import org.gnu.atk.AtkObject;
import org.gnu.gdk.*;
import org.gnu.gdk.Window;
import org.gnu.glib.Boxed;
import org.gnu.glib.EventMap;
import org.gnu.glib.EventType;
import org.gnu.glib.GObject;
import org.gnu.glib.Type;
import org.gnu.gtk.event.*;
import org.gnu.glib.Handle;
import org.gnu.glib.Struct;
import org.gnu.pango.Context;
import org.gnu.pango.FontDescription;

/**
 * GtkWidget is the base class of all widgets.
 *
 * @deprecated This class is part of the java-gnome 2.x family of libraries,
 *             which, due to their inefficiency and complexity, are no longer
 *             being maintained and have been abandoned by the java-gnome
 *             project. You can likely find what you are looking for in the
 *             new java-gnome 4.0 bindings. See
 *             <code>org.gnome.gtk.Widget</code>,
 *             though be aware that the API may be considerably different.
 */
public class Widget extends GtkObject {

    // Cached class array used in makeWidget.
    private static Class[] handleClass = new Class[] { Handle.class };

    /**
     * The list of objects interested in focus events.
     */
    private Vector focusListeners = null;

    /**
     * The list of objects interested in configure events.
     */
    private Vector configureListeners = null;

    /**
     * Ths list of objects interested in key events.
     */
    private Vector keyListeners = null;

    /**
     * The list of objects interested in life cycle events.
     */
    private Vector lifeCycleListeners = null;

    /**
     * The list of objects interested in mouse events.
     */
    private Vector mouseListeners = null;

    /**
     * The list of objects interested in drag target events.
     */
    private Vector dragTargetListeners = null;

    /**
     * The list of objects interested in drag origin events.
     */
    private Vector dragOriginListeners = null;

    /**
     * The list of objects interested in expose events.
     */
    private Vector exposeListeners = null;

    /**
     * The list of objects interested in expose events.
     */
    private Vector mouseMotionListeners = null;

    /**
     * Create a new Widget with a handle to a native resource returned from a
     * call to the native libraries.
     * 
     * @param handle
     *            The handle that represents a pointer to a native resource.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public Widget(Handle handle) {
        super(handle);
    }

    /**
     * Creates a new Widget with a handle to a native resource returned from a
     * call to the native libraries. Should only be used internally by
     * Java-Gnome.
     * 
     * @param handle
     *            The handle that represents a pointer to a native resource.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public static Widget getWidget(Handle handle) {
        if (handle == null)
            return null;

        Widget obj = (Widget) getGObjectFromHandle(handle);
        if (obj == null)
            obj = new Widget(handle);

        return obj;
    }

    /**
     * Cause this Widget to be visible.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void show() {
        checkState();
        Widget.gtk_widget_show(getHandle());
    }

    /**
     * Cause this Widget and all of its' children to be visible.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void showAll() {
        checkState();
        Widget.gtk_widget_show_all(getHandle());
    }

    /**
     * Cause this Widget to not be visible.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void hide() {
        checkState();
        Widget.gtk_widget_hide(getHandle());
    }

    /**
     * Cause this Widget and all of its' children to not be visible.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void hideAll() {
        checkState();
        Widget.gtk_widget_hide_all(getHandle());
    }

    /**
     * Creates a native window resource associated with this widget. Normally a
     * widget realization happens implicitly; if you show a widget and all of
     * its' parent containers then the widget will be realized automatically.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void realize() {
        checkState();
        Widget.gtk_widget_realize(getHandle());
    }

    /**
     * Causes the entire widget to be redrawn.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void draw() {
        checkState();
        Widget.gtk_widget_queue_draw(getHandle());
    }

    /**
     * Causes the specified area to be redrawn.
     * 
     * @param area
     *            The area to be redrawn.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void drawArea(Rectangle area) {
        checkState();
        drawArea(area.getX(), area.getY(), area.getWidth(), area.getHeight());
    }

    /**
     * Causes the specified area to be redrawn
     * 
     * @param x
     *            The x coordinate for the area to be redrawn.
     * @param y
     *            The y coordinate for the area to be redrawn.
     * @param width
     *            The width of the area to be redrawn.
     * @param height
     *            The height of the area to be redrawn.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void drawArea(int x, int y, int width, int height) {
        checkState();
        Widget.gtk_widget_queue_draw_area(getHandle(), x, y, width, height);
    }

    /**
     * For widgets that can be activated (buttons, menu items, etc.) this method
     * activiates them. Activation is what happens when you press Enter on a
     * widget during keyboard navigation.
     * 
     * @return False if this widget is not activatable.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public boolean activate() {
        checkState();
        return Widget.gtk_widget_activate(getHandle());
    }

    /**
     * Moves a widget from one Container to another.
     * 
     * @param newParent
     *            The widget that will be the new parent.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void reparent(Widget newParent) {
        checkState();
        Widget.gtk_widget_reparent(getHandle(), newParent.getHandle());
    }

    /**
     * Returns the parent container for this widget
     * 
     * @return The parent container for this widget.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public Widget getParent() {
        checkState();
        Handle hndl = gtk_widget_get_parent(getHandle());
        return Widget.getWidget(hndl);
    }

    /**
     * Returns the widget's parent window.
     * 
     * @return Returns the widget's parent window.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public Window getParentWindow() {
        checkState();
        Handle hndl = gtk_widget_get_parent_window(getHandle());
        return Window.getWindowFromHandle(hndl);
    }

    /**
     * Return the widget's Gdk window, <i>if it has one</i>. This is the window
     * to draw upon when writing custom widgets. It's available after the widget
     * has been mapped. Thus if you listen to LifeCycleEvents, you can fetch the
     * Window instance using this method after an LifeCycleEvent of type MAP has
     * occurred.
     * 
     * @return the widget's Gdk Window, or null if a) it hasn't been mapped yet
     *         or b) it is of a type that doesn't have a Gdk Window.
     * @see #getParentWindow() if you want to be sure of getting to a Gdk
     *      Window.
     * @see DrawingArea for more about custom Widgets.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public Window getWindow() {
        checkState();
        Handle hndl = Widget.gtk_widget_get_window(getHandle());
        return Window.getWindowFromHandle(hndl);
    }

    /**
     * Sets the event mask for a widget. The event mask determines which events
     * a widget will receive. Keep in mind that different widgets have different
     * default event masks, and by changing the event mask you may disrupt a
     * widget's functionality, so be careful. This function must be called while
     * a widget is unrealized. Consider addEvents() for widgets that are already
     * realized, or if you want to preserve the existing event mask. This
     * function can't be used with NO_WINDOW widgets; to get events on those
     * widgets, place them inside an EventBox and receive events on the event
     * box.
     * 
     * @param events
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void setEvents(EventMask events) {
        checkState();
        gtk_widget_set_events(getHandle(), events.getValue());
    }

    /**
     * Adds the events in the bitfield events to the event mask for widget. See
     * setEvents() for details.
     * 
     * @param events
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void addEvents(EventMask events) {
        checkState();
        gtk_widget_add_events(getHandle(), events.getValue());
    }

    /**
     * Sets the extension events mask to mode.
     * 
     * @param mode
     *            extension events to receive.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void setExtensionEvents(ExtensionMode mode) {
        checkState();
        gtk_widget_set_extension_events(getHandle(), mode.getValue());
    }

    /**
     * Retrieves the extension events the widget will receive.
     * 
     * @return extension events for this widget.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public ExtensionMode getExtensionEvents() {
        checkState();
        return ExtensionMode
                .intern(gtk_widget_get_extension_events(getHandle()));
    }

    /**
     * Computes the intersection of the widget's area and <code>area</code>.
     * 
     * @param area
     *            The area to use to compute the intersection.
     * @return The intersection. If the areas don't intersect this method
     *         returns null.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public Rectangle intersect(Rectangle area) {
        checkState();
        Handle handle = gtk_widget_intersect(getHandle(), area.getHandle());
        return Rectangle.getRectangle(handle);
    }

    /**
     * Determines if the widget has focus within its' TOPLEVEL.
     * 
     * @return true if the widget has focus.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public boolean hasFocus() {
        checkState();
        return Widget.gtk_widget_is_focus(getHandle());
    }

    /**
     * Causes the widget to gain focus within its' TOPLEVEL.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void grabFocus() {
        checkState();
        Widget.gtk_widget_grab_focus(getHandle());
    }

    /**
     * Find out the current value of the "can-focus" property
     * 
     * @since 2.8.5
     * @see #setCanFocus(boolean)
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public boolean getCanFocus() {
        checkState();
        return getBooleanProperty("can-focus");
    }

    /**
     * Tell this Widget whether or not it is allowed to accept focus. Telling a
     * widget that it is not to accept focus generally means that it will be
     * skipped over when TABing around a Window. This can, however, have some
     * unexpected side effects: if a Label, for example, is told that it can't
     * have focus but it also told that its text is
     * {@link Label#setSelectable(boolean) selectable}, then you won't be able
     * to Copy and Paste any text you select from it.
     * 
     * @param canFocus
     * @since 2.8.5
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void setCanFocus(boolean canFocus) {
        checkState();
        setBooleanProperty("can-focus", canFocus);
    }

    /**
     * Causes the widget to become the default widget. The default widget is
     * activated when the user presses Enter in the window. Default widgets must
     * be activatable.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void grabDefault() {
        checkState();
        Widget.gtk_widget_grab_default(getHandle());
    }

    /**
     * Sets the name for this widget. Widgets can be named which allows you to
     * refer to them from a gtkrc file. You can apply a style to widgets with a
     * particular name in the gtkrc file. Names are also useful in accessibility
     * contexts (ie, using ATK) to dig into a runnnig Window and extract a
     * specific Widget (the concept is analoguous to id attributes in XML)
     * 
     * @param name
     *            The name for the widget.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void setName(String name) {
        checkState();
        Widget.gtk_widget_set_name(getHandle(), name);
    }

    /**
     * Returns the name for the widget.
     * 
     * @return The name for the widget.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public String getName() {
        checkState();
        return Widget.gtk_widget_get_name(getHandle());
    }

    /**
     * Sets the sensitivity of a widget. A widget is sensitive if the user can
     * interact with it. Insensitive widgets are "grayed out" and the user can't
     * interact with them. Insensitive widgets are known as "inactive",
     * "disabled", or "ghosted" in some other toolkits.
     * 
     * @param sensitive
     *            true to make the widget sensitive.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void setSensitive(boolean sensitive) {
        checkState();
        Widget.gtk_widget_set_sensitive(getHandle(), sensitive);
    }

    /**
     * Gets the sensitivity of the widget. A widget is sensitive if the user can
     * interact with it. Insensitive widgets are "grayed out" and the user can't
     * interact with them. Insensitive widgets are known as "inactive",
     * "disabled", or "ghosted" in some other toolkits.
     * 
     * @return true if the widget is sensitive, false otherwise.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public boolean getSensitive() {
        checkState();
        return gtk_widget_get_sensitive(getHandle());
    }

    /**
     * Returns the topmost widget in the container hierarchy.
     * 
     * @return The topmost widget.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public Widget getToplevel() {
        checkState();
        Handle hndl = gtk_widget_get_toplevel(getHandle());
        return Widget.getWidget(hndl);
    }

    /**
     * Returns the Colormap that will be used to render this widget.
     * 
     * @return The colormap used for this widget.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public Colormap getColormap() {
        checkState();
        Handle colorHandle = Widget.gtk_widget_get_colormap(getHandle());
        return Colormap.getColormapFromHandle(colorHandle);
    }

    /**
     * Set the Colormap that will be used to render this widget.
     * 
     * @param colormap
     *            The colormap to be used.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void setColormap(Colormap colormap) {
        checkState();
        Widget.gtk_widget_set_colormap(getHandle(), colormap.getHandle());
    }

    /**
     * Returns the location of the mouse pointer in widget coordinates. This
     * method will return null if the mouse is not currently in the widget.
     * 
     * @return The location of the mouse or null
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public Point getPointer() {
        checkState();
        int[] x = new int[1];
        int[] y = new int[1];
        Widget.gtk_widget_get_pointer(getHandle(), x, y);
        if (null == x)
            return null;
        if (null == y)
            return null;
        return new Point(x[0], y[0]);
    }

    /**
     * Determines whether this widget is somewhere inside of ancestor.
     * 
     * @param ancestor
     *            The possible parent widget
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public boolean isAncestor(Widget ancestor) {
        checkState();
        return Widget.gtk_widget_is_ancestor(getHandle(), ancestor.getHandle());
    }

    /**
     * Pushes a Colormap onto the stack of colormaps. The topmost Colormap on
     * the stack will be used to create all Widgets.
     * 
     * @param colormap
     *            The Colormap to push onto the stack.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void pushColormap(Colormap colormap) {
        checkState();
        Widget.gtk_widget_push_colormap(colormap.getHandle());
    }

    /**
     * Pops the top colormap off of the stack of colormaps. The topmost Colormap
     * on the stack will be used to create all Widgets.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void popColormap() {
        checkState();
        Widget.gtk_widget_pop_colormap();
    }

    /**
     * Sets the shape of this widgets OS window. This allows for transparent
     * windows.
     * 
     * @param shapeMask
     *            Shape to be added or null to remove an existing shape.
     * @param x
     *            X Position of the shape mask with respect to the window.
     * @param y
     *            Y Position of the shape mask with respect to the window.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void shapeCombineMask(Bitmap shapeMask, int x, int y) {
        checkState();
        Handle shapeMaskHandle = (shapeMask == null ? null : shapeMask
                .getHandle());
        Widget
                .gtk_widget_shape_combine_mask(getHandle(), shapeMaskHandle, x,
                        y);
    }

    /**
     * Sets the foreground color for a widget in a particular state. All other
     * style values are left untouched.
     * 
     * @param state
     *            The widget state to modify.
     * @param color
     *            The color to set the foreground or <code>null</code> to 
     *            to undo the effect of a previous call.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void setForegroundColor(StateType state, Color color) {
        checkState();
        Widget.gtk_widget_modify_fg(getHandle(), state.getValue(), getHandle(color));
    }

    /**
     * Sets the background color for a widget in a particular state. All other
     * style values are left untouched.
     * 
     * <p>
     * Note that some widgets draw on their parent container's window and thus
     * may not draw any background themselves. This is the case for e.g.
     * {@link Label}. To modify the background of such widgets, you have to set
     * the background color on their parent; if you want to set the background
     * of a rectangular area around a label, try placing the label in an
     * {@link EventBox} widget and setting the background color on that
     * </p>
     * 
     * @param state
     *            The widget state to modify.
     * @param color
     *            The color to set the background or <code>null</code> to 
     *            to undo the effect of a previous call.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void setBackgroundColor(StateType state, Color color) {
        checkState();
        Widget.gtk_widget_modify_bg(getHandle(), state.getValue(), getHandle(color));
    }

    /**
     * Sets the text color for a widget in a particular state. All other style
     * values are left untouched. The text color is the foreground color along
     * with the base color for widgets such as Entry, TextView, etc.
     * 
     * <p>
     * Note that some widgets draw on their parent container's window and thus
     * may not draw any background themselves. This is the case for e.g.
     * {@link Label}. To modify the background of such widgets, you have to set
     * the background color on their parent; if you want to set the background
     * of a rectangular area around a label, try placing the label in an
     * {@link EventBox} widget and setting the background color on that
     * </p>
     * 
     * @param state
     *            The widget state to modify.
     * @param color
     *            The color to set the text or <code>null</code> to 
     *            to undo the effect of a previous call.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void setTextColor(StateType state, Color color) {
        checkState();
        Widget.gtk_widget_modify_text(getHandle(), state.getValue(), getHandle(color));
    }

    /**
     * Sets the base color used for a widget in a particular state. The base
     * color is the background color used along with the text color for widgets
     * such as Entry, TextView, etc.
     * 
     * @param state
     *            The widget state to modify.
     * @param color
     *            The color to set or <code>null</code> to 
     *            to undo the effect of a previous call.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void setBaseColor(StateType state, Color color) {
        checkState();
        Widget.gtk_widget_modify_base(getHandle(), state.getValue(), getHandle(color));
    }

    /**
     * Sets the font to use for the widget.
     * 
     * @param fontDesc
     *            The font description to use or <code>null</code> to 
     *            to undo the effect of a previous call.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void setFont(FontDescription fontDesc) {
        checkState();
        Widget.gtk_widget_modify_font(getHandle(), getHandle(fontDesc));
    }

    /**
     * Modifies style values on the Widget. Modifications made using this
     * technique take precedence over style values set via an RC file.
     * 
     * @param style
     *            The style to apply to the Widget or <code>null</code> to 
     *            to undo the effect of a previous call.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void modifyStyle(RcStyle style) {
        checkState();
        Widget.gtk_widget_modify_style(getHandle(), getHandle(style));
    }

    /**
     * Retruns the Widget's {@link RcStyle}.
     * 
     * @return The current RcStyle for the Widget.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public RcStyle getModifierStyle() {
        checkState();
        Handle hndl = Widget.gtk_widget_get_modifier_style(getHandle());
        return RcStyle.getRcStyle(hndl);
    }

    /**
     * Returns the Widgets {@link Style}.
     * 
     * @return The current Style for the Widget.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public Style getStyle() {
        checkState();
        Handle hndl = Widget.gtk_widget_get_style(getHandle());
        return Style.getStyle(hndl);
    }

    /**
     * Creates a new Context with the appropriate Colormap, FontDescription, and
     * base direction for drawing text for this widget.
     * 
     * @return A context that can be used for drawig text.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public Context createContext() {
        checkState();
        Handle pc = Widget.gtk_widget_create_pango_context(getHandle());
        return Context.getContextFromHandle(pc);
    }

    /**
     * Gets a Context with the appropriate Colormap, FontDescription and base
     * direction for this widget. Unlike the createContext method, this context
     * is owned by the widget and can be as long as the widget exists. This
     * context will be updated to match any changes to the widget's attributes.
     * 
     * @return A context that can be used for drawing text.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public Context getContext() {
        checkState();
        Handle pc = Widget.gtk_widget_get_pango_context(getHandle());
        return Context.getContextFromHandle(pc);
    }

    /**
     * Creates a new Layout with the appropriate Colormap, FontDescription and
     * base direction for drawing text for this widget.
     * 
     * @param text
     *            The text used for the layout.
     * @return The layout that can be used for drawing text.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public org.gnu.pango.Layout createLayout(String text) {
        checkState();
        Handle layout = Widget
                .gtk_widget_create_pango_layout(getHandle(), text);
        return org.gnu.pango.Layout.getLayoutFromHandle(layout);
    }

    /**
     * Enables/Disables double buffering for this widget. Widgets are double
     * buffered by default.
     * 
     * @param doubleBuffered
     *            Set if the widget should be double buffered.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void setDoubleBuffered(boolean doubleBuffered) {
        checkState();
        Widget.gtk_widget_set_double_buffered(getHandle(), doubleBuffered);
    }

    /**
     * Returns the accessible object associated with this widget.
     * 
     * @return The AtkObject.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public AtkObject getAccessible() {
        checkState();
        Handle ao = Widget.gtk_widget_get_accessible(getHandle());
        return AtkObject.getAtkObjectFromHandle(ao);
    }

    public boolean canActivateAccel(int signalId) {
        checkState();
        return gtk_widget_can_activate_accel(getHandle(), signalId);
    }

    public Screen getScreen() {
        checkState();
        Handle hndl = gtk_widget_get_screen(getHandle());
        return Screen.getScreenFromHandle(hndl);
    }

    public boolean hasScreen() {
        checkState();
        return gtk_widget_has_screen(getHandle());
    }

    public Display getDisplay() {
        checkState();
        Handle hndl = gtk_widget_get_display(getHandle());
        return Display.getDisplayFromHandle(hndl);
    }

    /**
     * Get the root window where this widget is located. This function can only
     * be called after the widget has been added to a widget heirarchy with Gtk
     * {@link org.gnu.gtk.Window} at the top.
     * 
     * @return the Gdk Window backing the root of this particular Widget's
     *         hierarchy.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public Window getRootWindow() {
        checkState();
        Handle hndl = gtk_widget_get_root_window(getHandle());
        return Window.getWindowFromHandle(hndl);
    }

    public void addAccelerator(AccelGroup group, int accelKey,
            ModifierType accelMods, AccelFlags accelFlags) {
        gtk_widget_add_accelerator(this.getHandle(), group.getHandle(),
                accelKey, accelMods.getValue(), accelFlags.getValue());
    }

    public boolean removeAccelerator(AccelGroup group, int accelKey,
            ModifierType accelMods) {
        return gtk_widget_remove_accelerator(this.getHandle(), group
                .getHandle(), accelKey, accelMods.getValue());
    }

    /**
     * Sets the minimum size of a widget. You can use this method to force a
     * widget to be either larger or smaller that it normally be.
     * <p>
     * In most cases <code>Window.setDefaultSize()</code> is a better choice
     * for toplevel windows than this method. Setting the default size will
     * still allow users to shrink the window. Setting the minimum size will
     * force them to leave the window at least as large as the request.
     * <p>
     * Note the inherent danger of setting any fixed size - themes, translations
     * into other languages, different fonts, and user action can change the
     * appropriate size for a given widget. So, it's basically impossible to
     * hardcode a size that will always be correct.
     * <p>
     * If the minimum size in a given direction is -1 then the "natural" size
     * for the widget will be used instead.
     * 
     * @param width
     *            The minimum width size to use.
     * @param height
     *            The minimum height size to use.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void setMinimumSize(int width, int height) {
        checkState();
        Widget.gtk_widget_set_size_request(getHandle(), width, height);
    }

    public Class getEventListenerClass(String signal) {
        checkState();
        Class rv = evtMap.getEventListenerClass(signal);
        if (rv == null)
            rv = super.getEventListenerClass(signal);
        return rv;
    }

    public EventType getEventType(String signal) {
        checkState();
        EventType et = evtMap.getEventType(signal);
        if (et == null)
            et = super.getEventType(signal);
        return et;
    }

    private static EventMap evtMap = new EventMap();
    static {
        addEvents(evtMap);
    }

    /**
     * Implementation method to build an EventMap for this widget class. Not
     * useful (or supported) for application use.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    private static void addEvents(EventMap anEvtMap) {
        anEvtMap.addEvent("hide", "handleHide", LifeCycleEvent.Type.HIDE,
                LifeCycleListener.class);
        anEvtMap.addEvent("show", "handleShow", LifeCycleEvent.Type.SHOW,
                LifeCycleListener.class);
        anEvtMap.addEvent("realize", "handleRealize",
                LifeCycleEvent.Type.REALIZE, LifeCycleListener.class);
        anEvtMap.addEvent("unrealize", "handleUnrealize",
                LifeCycleEvent.Type.UNREALIZE, LifeCycleListener.class);
        anEvtMap.addEvent("destroy_event", "handleDestroy",
                LifeCycleEvent.Type.DESTROY, LifeCycleListener.class);
        anEvtMap.addEvent("delete_event", "handleDelete",
                LifeCycleEvent.Type.DELETE, LifeCycleListener.class);
        anEvtMap.addEvent("map", "handleMap", LifeCycleEvent.Type.MAP,
                LifeCycleListener.class);
        anEvtMap.addEvent("unmap", "handleUnmap", LifeCycleEvent.Type.UNMAP,
                LifeCycleListener.class);
        anEvtMap.addEvent("focus_in_event", "handleFocusIn",
                FocusEvent.Type.FOCUS_IN, FocusListener.class);
        anEvtMap.addEvent("focus_out_event", "handleFocusOut",
                FocusEvent.Type.FOCUS_OUT, FocusListener.class);
        anEvtMap.addEvent("configure_event", "handleConfigure",
                ConfigureEvent.Type.CONFIGURE, ConfigureListener.class);

        anEvtMap.addEvent("key_press_event", "handleKeyPressed",
                KeyEvent.Type.KEY_PRESSED, KeyListener.class);
        anEvtMap.addEvent("key_release_event", "handleKeyReleased",
                KeyEvent.Type.KEY_RELEASED, KeyListener.class);
        anEvtMap.addEvent("button_press_event", "handleButtonPressed",
                MouseEvent.Type.BUTTON_PRESS, MouseListener.class);
        anEvtMap.addEvent("button_release_event", "handleButtonReleased",
                MouseEvent.Type.BUTTON_RELEASE, MouseListener.class);
        anEvtMap.addEvent("scroll_event", "handleScroll",
                MouseEvent.Type.WHEEL_SCROLL, MouseListener.class);
        anEvtMap.addEvent("enter_notify_event", "handleMouseEnter",
                MouseEvent.Type.ENTER, MouseListener.class);
        anEvtMap.addEvent("leave_notify_event", "handleMouseLeave",
                MouseEvent.Type.LEAVE, MouseListener.class);
        anEvtMap.addEvent("expose_event", "handleExpose",
                ExposeEvent.Type.EXPOSE, ExposeListener.class);
        anEvtMap.addEvent("no_expose_event", "handleNoExpose",
                ExposeEvent.Type.NO_EXPOSE, ExposeListener.class);
        anEvtMap.addEvent("motion-notify-event", "handleMouseMotion",
                MouseMotionEvent.Type.MOTION, MouseMotionListener.class);
        anEvtMap.addEvent("drag-begin", "handleDragStarted",
                StartDragEvent.Type.START, DragOriginListener.class);
        anEvtMap.addEvent("drag-data-delete", "handleDragDataDeleted",
                DeleteDragDataEvent.Type.DATA_DELETE, DragOriginListener.class);
        anEvtMap.addEvent("drag-data-get", "handleDragDataRequested",
                RequestDragDataEvent.Type.DATA_REQUEST,
                DragOriginListener.class);
        anEvtMap.addEvent("drag-data-received", "handleDragDataReceived",
                ReceiveDragDataEvent.Type.DATA_RECEIVE,
                DragTargetListener.class);
        anEvtMap.addEvent("drag-drop", "handleDragDropped",
                DropDragEvent.Type.DROP, DragTargetListener.class);
        anEvtMap.addEvent("drag-end", "handleDragEnded", EndDragEvent.Type.END,
                DragOriginListener.class);
        anEvtMap.addEvent("drag-leave", "handleDragDestinationLeft",
                LeaveDragDestinationEvent.Type.LEAVE_DESTINATION,
                DragTargetListener.class);
        anEvtMap.addEvent("drag-motion", "handleDragMotionOccurred",
                DragMotionEvent.Type.MOTION, DragOriginListener.class);
    }

    /***************************************************************************
     * Life Cycle event handling.
     **************************************************************************/
    /**
     * Register an object to receive life cycle event notification.
     * 
     * @param listener
     *            The object that has implemented the LifeCycleListener
     *            interface that is to receive the life cycle events.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void addListener(LifeCycleListener listener) {
        checkState();
        // Don't add the listener a second time if it is in the Vector.
        int i = findListener(lifeCycleListeners, listener);
        if (i == -1) {
            if (null == lifeCycleListeners) {
                evtMap.initialize(this, LifeCycleEvent.Type.HIDE);
                evtMap.initialize(this, LifeCycleEvent.Type.SHOW);
                evtMap.initialize(this, LifeCycleEvent.Type.REALIZE);
                evtMap.initialize(this, LifeCycleEvent.Type.UNREALIZE);
                evtMap.initialize(this, LifeCycleEvent.Type.DESTROY);
                evtMap.initialize(this, LifeCycleEvent.Type.DELETE);
                lifeCycleListeners = new Vector();
            }
            lifeCycleListeners.addElement(listener);
        }
    }

    /**
     * Unregister an object that was receiving life cycle event notification.
     * 
     * @param listener
     *            The object that is to no longer receive life cycle events.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void removeListener(LifeCycleListener listener) {
        checkState();
        int i = findListener(lifeCycleListeners, listener);
        if (i > -1)
            lifeCycleListeners.remove(i);
        if (0 == lifeCycleListeners.size()) {
            evtMap.uninitialize(this, LifeCycleEvent.Type.HIDE);
            evtMap.uninitialize(this, LifeCycleEvent.Type.SHOW);
            evtMap.uninitialize(this, LifeCycleEvent.Type.REALIZE);
            evtMap.uninitialize(this, LifeCycleEvent.Type.UNREALIZE);
            evtMap.uninitialize(this, LifeCycleEvent.Type.DESTROY);
            evtMap.uninitialize(this, LifeCycleEvent.Type.DELETE);
            lifeCycleListeners = null;
        }
    }

    protected void fireLifeCycleEvent(LifeCycleEvent event) {
        if (null == lifeCycleListeners)
            return;
        int size = lifeCycleListeners.size();
        int i = 0;
        while (i < size) {
            LifeCycleListener lc = (LifeCycleListener) lifeCycleListeners
                    .elementAt(i);
            lc.lifeCycleEvent(event);
            i++;
        }
    }

    protected boolean fireBooleanLifeCycleEvent(LifeCycleEvent event,
            boolean defaultValue) {
        boolean returnValue = defaultValue;
        if (null == lifeCycleListeners)
            return defaultValue;
        int size = lifeCycleListeners.size();
        int i = 0;
        while (i < size) {
            LifeCycleListener lc = (LifeCycleListener) lifeCycleListeners
                    .elementAt(i);
            if (lc.lifeCycleQuery(event) != defaultValue)
                returnValue = !defaultValue;
            i++;
        }
        return returnValue;
    }

    protected void handleShow() {
        fireLifeCycleEvent(new LifeCycleEvent(this, LifeCycleEvent.Type.SHOW));
    }

    protected void handleHide() {
        fireLifeCycleEvent(new LifeCycleEvent(this, LifeCycleEvent.Type.HIDE));
    }

    protected void handleRealize() {
        fireLifeCycleEvent(new LifeCycleEvent(this, LifeCycleEvent.Type.REALIZE));
    }

    protected void handleUnrealize() {
        fireLifeCycleEvent(new LifeCycleEvent(this,
                LifeCycleEvent.Type.UNREALIZE));
    }

    protected boolean handleDestroy(Handle event) {
        return fireBooleanLifeCycleEvent(new LifeCycleEvent(this,
                LifeCycleEvent.Type.DESTROY), true);
    }

    protected boolean handleDelete(Handle event) {
        return fireBooleanLifeCycleEvent(new LifeCycleEvent(this,
                LifeCycleEvent.Type.DELETE), false);
    }

    protected void handleMap() {
        fireLifeCycleEvent(new LifeCycleEvent(this, LifeCycleEvent.Type.MAP));
    }

    protected void handleUnmap() {
        fireLifeCycleEvent(new LifeCycleEvent(this, LifeCycleEvent.Type.UNMAP));
    }

    /***************************************************************************
     * Focus event handling.
     **************************************************************************/
    /**
     * Register an object to receive focus event notification.
     * 
     * @param listener
     *            The object that has implemented the FocusListener interface
     *            that is to receive the focus events.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void addListener(FocusListener listener) {
        checkState();
        // Don't add the listener a second time if it is in the Vector.
        int i = findListener(focusListeners, listener);
        if (i == -1) {
            if (null == focusListeners) {
                evtMap.initialize(this, FocusEvent.Type.FOCUS_IN);
                evtMap.initialize(this, FocusEvent.Type.FOCUS_OUT);
                focusListeners = new Vector();
            }
            focusListeners.addElement(listener);
        }
    }

    /**
     * Unregister an object that was receiving focus event notification.
     * 
     * @param listener
     *            The object that is to no longer receive focus events.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void removeListener(FocusListener listener) {
        checkState();
        int i = findListener(focusListeners, listener);
        if (i > -1)
            focusListeners.remove(i);
        if (0 == focusListeners.size()) {
            evtMap.uninitialize(this, FocusEvent.Type.FOCUS_IN);
            evtMap.uninitialize(this, FocusEvent.Type.FOCUS_OUT);
            focusListeners = null;
        }
    }

    protected boolean fireFocusEvent(FocusEvent event) {
        if (null == focusListeners)
            return false;
        boolean retval = false;
        int size = focusListeners.size();
        int i = 0;
        while (i < size) {
            FocusListener fl = (FocusListener) focusListeners.elementAt(i);
            if (fl.focusEvent(event))
                retval = true;
            i++;
        }
        return retval;
    }

    protected boolean handleFocusIn(Handle event) {
        return fireFocusEvent(new FocusEvent(this, FocusEvent.Type.FOCUS_IN));
    }

    protected boolean handleFocusOut(Handle event) {
        return fireFocusEvent(new FocusEvent(this, FocusEvent.Type.FOCUS_OUT));
    }

    /***************************************************************************
     * Configure event handling.
     **************************************************************************/
    /**
     * Register an object to receive configure event notification.
     * 
     * @param listener
     *            The object that has implemented the ConfigureListener
     *            interface that is to receive the configure events.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void addListener(ConfigureListener listener) {
        checkState();
        // Don't add the listener a second time if it is in the Vector.
        int i = findListener(configureListeners, listener);
        if (i == -1) {
            if (null == configureListeners) {
                evtMap.initialize(this, ConfigureEvent.Type.CONFIGURE);
                configureListeners = new Vector();
            }
            configureListeners.addElement(listener);
        }
    }

    /**
     * Unregister an object that was receiving configure event notification.
     * 
     * @param listener
     *            The object that is to no longer receive configure events.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void removeListener(ConfigureListener listener) {
        checkState();
        int i = findListener(configureListeners, listener);
        if (i > -1)
            configureListeners.remove(i);
        if (0 == configureListeners.size()) {
            evtMap.uninitialize(this, ConfigureEvent.Type.CONFIGURE);
            configureListeners = null;
        }
    }

    protected boolean fireConfigureEvent(ConfigureEvent event) {
        if (null == configureListeners)
            return false;
        boolean retval = false;
        int size = configureListeners.size();
        int i = 0;
        while (i < size) {
            ConfigureListener cl = (ConfigureListener) configureListeners
                    .elementAt(i);
            if (cl.configureEvent(event))
                retval = true;
            i++;
        }
        return retval;
    }

    protected boolean handleConfigure(Handle event) {
        return fireConfigureEvent(new ConfigureEvent(this,
                ConfigureEvent.Type.CONFIGURE, new EventConfigure(event)));
    }

    /***************************************************************************
     * Key event handling.
     **************************************************************************/
    /**
     * Register an object to receive key event notification.
     * <p>
     * An important thing to notice is that some widgets don't receive
     * <i>low-level</i> events (such as a key-press event) by default. So if
     * you want to capture events from them, you should add them to an
     * <code>EventBox</code>, and capture events on the <code>EventBox</code>.
     * <p>
     * The reason why this happens is that some widgets, for efficiency, don't
     * have their own X window, which is necessary to receive events. These are
     * the widgets that don't have their own X window:
     * <p>
     * <code>Alignment</code> <br>
     * <code>Arrow</code> <br>
     * <code>Bin</code> <br>
     * <code>Box</code> <br>
     * <code>Image</code> <br>
     * <code>Item</code> <br>
     * <code>Label</code> <br>
     * <code>Pixmap</code> <br>
     * <code>ScrolledWindow</code> <br>
     * <code>Separator</code> <br>
     * <code>Table</code> <br>
     * <code>AspectFrame</code> <br>
     * <code>Frame</code> <br>
     * <code>VBox</code> <br>
     * <code>HBox</code> <br>
     * <code>VSeparator</code> <br>
     * <code>HSeparator</code> <br>
     * 
     * @param listener
     *            The object that has implemented the KeyListener interface that
     *            is to receive the key events.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void addListener(KeyListener listener) {
        checkState();
        // Don't add the listener a second time if it is in the Vector.
        int i = findListener(keyListeners, listener);
        if (i == -1) {
            if (null == keyListeners) {
                evtMap.initialize(this, KeyEvent.Type.KEY_PRESSED);
                evtMap.initialize(this, KeyEvent.Type.KEY_RELEASED);
                keyListeners = new Vector();
            }
            keyListeners.addElement(listener);
        }
    }

    /**
     * Unregister an object that was receiving key event notification.
     * 
     * @param listener
     *            The object that is to no longer receive key events.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void removeListener(KeyListener listener) {
        checkState();
        int i = findListener(keyListeners, listener);
        if (i > -1)
            keyListeners.remove(i);
        if (0 == keyListeners.size()) {
            evtMap.uninitialize(this, KeyEvent.Type.KEY_PRESSED);
            evtMap.uninitialize(this, KeyEvent.Type.KEY_RELEASED);
            keyListeners = null;
        }
    }

    protected boolean fireKeyEvent(KeyEvent event) {
        checkState();
        if (null == keyListeners)
            return false;
        boolean retval = false;
        int size = keyListeners.size();
        int i = 0;
        while (i < size) {
            KeyListener kl = (KeyListener) keyListeners.elementAt(i);
            if (kl.keyEvent(event))
                retval = true;
            i++;
        }
        return retval;
    }

    protected boolean handleKeyPressed(Handle event) {
        return fireKeyEvent(new KeyEvent(this, KeyEvent.Type.KEY_PRESSED,
                new EventKey(event)));
    }

    protected boolean handleKeyReleased(Handle event) {
        return fireKeyEvent(new KeyEvent(this, KeyEvent.Type.KEY_RELEASED,
                new EventKey(event)));
    }

    /***************************************************************************
     * Mouse event handling.
     **************************************************************************/
    /**
     * Register an object to receive mouse event notification.
     * <p>
     * An important thing to notice is that some widgets don't receive
     * <i>low-level</i> events (such as a mouse-click event) by default. So if
     * you want to capture events from them, you should add them to an
     * <code>EventBox</code>, and capture events on the <code>EventBox</code>.
     * <p>
     * The reason why this happens is that some widgets, for efficiency, don't
     * have their own X window, which is necessary to receive events. These are
     * the widgets that don't have their own X window:
     * <p>
     * <code>Alignment</code> <br>
     * <code>Arrow</code> <br>
     * <code>Bin</code> <br>
     * <code>Box</code> <br>
     * <code>Image</code> <br>
     * <code>Item</code> <br>
     * <code>Label</code> <br>
     * <code>Pixmap</code> <br>
     * <code>ScrolledWindow</code> <br>
     * <code>Separator</code> <br>
     * <code>Table</code> <br>
     * <code>AspectFrame</code> <br>
     * <code>Frame</code> <br>
     * <code>VBox</code> <br>
     * <code>HBox</code> <br>
     * <code>VSeparator</code> <br>
     * <code>HSeparator</code> <br>
     * 
     * @param listener
     *            The object that has implemented the MouseListener interface
     *            that is to receive the mouse events.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void addListener(MouseListener listener) {
        checkState();
        // Don't add the listener a second time if it is in the Vector.
        int i = findListener(mouseListeners, listener);
        if (i == -1) {
            if (null == mouseListeners) {
                evtMap.initialize(this, MouseEvent.Type.BUTTON_PRESS);
                evtMap.initialize(this, MouseEvent.Type.BUTTON_RELEASE);
                evtMap.initialize(this, MouseEvent.Type.WHEEL_SCROLL);
                evtMap.initialize(this, MouseEvent.Type.ENTER);
                evtMap.initialize(this, MouseEvent.Type.LEAVE);
                mouseListeners = new Vector();
            }
            mouseListeners.addElement(listener);
        }
    }

    /**
     * Unregister an object that was receiving mouse event notification.
     * 
     * @param listener
     *            The object that is to no longer receive mouse events.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void removeListener(MouseListener listener) {
        checkState();
        int i = findListener(mouseListeners, listener);
        if (i > -1)
            mouseListeners.remove(i);
        if (0 == mouseListeners.size()) {
            evtMap.uninitialize(this, MouseEvent.Type.BUTTON_PRESS);
            evtMap.uninitialize(this, MouseEvent.Type.BUTTON_RELEASE);
            evtMap.uninitialize(this, MouseEvent.Type.WHEEL_SCROLL);
            evtMap.uninitialize(this, MouseEvent.Type.ENTER);
            evtMap.uninitialize(this, MouseEvent.Type.LEAVE);
            mouseListeners = null;
        }
    }

    protected boolean fireMouseEvent(MouseEvent event) {
        if (null == mouseListeners)
            return false;
        boolean retval = false;
        int size = mouseListeners.size();
        int i = 0;
        while (i < size) {
            MouseListener ml = (MouseListener) mouseListeners.elementAt(i);
            if (ml.mouseEvent(event))
                retval = true;
            i++;
        }
        return retval;
    }

    protected boolean handleButtonPressed(Handle event) {
        return fireMouseEvent(new MouseEvent(this,
                MouseEvent.Type.BUTTON_PRESS, new EventButton(event)));
    }

    protected boolean handleButtonReleased(Handle event) {
        return fireMouseEvent(new MouseEvent(this,
                MouseEvent.Type.BUTTON_RELEASE, new EventButton(event)));
    }

    protected boolean handleScroll(Handle event) {
        return fireMouseEvent(new MouseEvent(this,
                MouseEvent.Type.WHEEL_SCROLL, new EventScroll(event)));
    }

    protected boolean handleMouseEnter(Handle event) {
        return fireMouseEvent(new MouseEvent(this, MouseEvent.Type.ENTER,
                new EventCrossing(event)));
    }

    protected boolean handleMouseLeave(Handle event) {
        return fireMouseEvent(new MouseEvent(this, MouseEvent.Type.LEAVE,
                new EventCrossing(event)));
    }

    /**
     * Give us a way to locate a specific listener in a Vector.
     * 
     * @param list
     *            The Vector of listeners to search.
     * @param listener
     *            The object that is to be located in the Vector.
     * @return Returns the index of the listener in the Vector, or -1 if the
     *         listener is not contained in the Vector.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    protected static int findListener(Vector list, Object listener) {
        if (null == list || null == listener)
            return -1;
        return list.indexOf(listener);
    }

    /**
     * Retrieve the runtime type used by the GLib library.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public static Type getType() {
        return new Type(gtk_widget_get_type());
    }

    /**
     * Create a Java-GNOME Widget subclass from an existing native GTK+ handle.
     * 
     * @param handle
     *            The handle that represents a pointer to a native resource.
     * @throws ClassNotFoundException
     *             if a Java-GNOME class cannot be found for the specified
     *             handle.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public static Widget makeWidget(Handle handle)
            throws ClassNotFoundException {
        String widgetClass = getTypeClass(handle);
        String methodName = null;
        if (widgetClass == null)
            throw new ClassNotFoundException(
                    "No GTK class name: invalid handle?");
        try {
            Class cls = Class.forName(widgetClass);
            String className = removePackageName(cls);
            methodName = "get" + className;
            Method factoryMethod = cls.getMethod(methodName, handleClass);
            return (Widget) factoryMethod.invoke(null, new Object[] { handle });
        } catch (ClassNotFoundException e) {
            throw e;
        } catch (NoSuchMethodException e) {
            throw new ClassNotFoundException("Could not find static factory "
                    + "method: " + methodName + "(Handle) in " + widgetClass
                    + ". Please file a bug with this information.");
        } catch (Exception e) {
            throw new ClassNotFoundException(e.toString());
        }
    }

    private static String removePackageName(Class klass) {
        String fullName = klass.getName();
        int length = klass.getPackage().getName().length();
        return fullName.substring(length + 1);
    }

    private static String getTypeClass(Handle handle) {
        String widgetType = Gtk.getTypeName(handle);
        if (widgetType.startsWith("Gtk")) {
            String wname = widgetType.substring(3);
            // Check for naming exceptions.
            if (wname.equals("Statusbar")) {
                wname = "StatusBar";
            } else if (wname.equals("Toolbar")) {
                wname = "ToolBar";
            } else if (wname.equals("HScrollbar")) {
                wname = "HScrollBar";
            } else if (wname.equals("VScrollbar")) {
                wname = "VScrollBar";
            }
            return "org.gnu.gtk." + wname;
        } else if (widgetType.startsWith("Gnome"))
            return "org.gnu.gnome." + widgetType.substring(5);

        // Custom class? See if it exists as specified.
        return widgetType;
    }

    /*
     * Returns a region which has been allocated to the widget by its parent. It
     * is a subregion of its parents allocation.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public Allocation getAllocation() {
        checkState();
        return gtk_widget_get_allocation(getHandle());
    }

    /***************************************************************************
     * Drag and Drop Support
     **************************************************************************/
    /**
     * Sets up the widget so that it can be the source of drag and drop
     * operations.
     * 
     * @param buttons
     *            Buttons which can start the drag
     * @param targets
     *            An array of names of drag and drop operations accepted (these
     *            are made up by the application designers. Widgets must set as
     *            drag sources and destinations with one of these the same)
     * @param actions
     *            Drag action - determines which events will be called.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void setDragSource(ModifierType buttons, TargetEntry[] targets,
            DragAction actions) {
        checkState();
        Handle[] targets_g = new Handle[targets.length];
        for (int i = 0; i < targets.length; i++)
            targets_g[i] = targets[i].getHandle();
        gtk_drag_source_set(getHandle(), buttons.getValue(), targets_g, actions
                .getValue());
    }

    /**
     * Removes support for this widget being a drag and drop source.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void setNoDragSource() {
        checkState();
        gtk_drag_source_unset(getHandle());
    }

    public void setDragIcon(Widget widget, Colormap cmap, Pixmap pixmap,
            Bitmap mask) {
        checkState();
        gtk_drag_source_set_icon(widget.getHandle(), cmap.getHandle(), pixmap
                .getHandle(), mask.getHandle());
    }

    public void setDragIconPixbuf(Widget widget, Pixbuf pixbuf) {
        checkState();
        gtk_drag_source_set_icon_pixbuf(widget.getHandle(), pixbuf.getHandle());
    }

    public void setDragIconStock(Widget widget, String stockId) {
        checkState();
        gtk_drag_source_set_icon_stock(widget.getHandle(), stockId);
    }

    /**
     * Sets up the widget so that is can receive drops as part of drag drop
     * events and specifies what sort of drops it will accept
     * 
     * @param flags
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void setDragDestination(DestDefaults flags, TargetEntry[] targets,
            org.gnu.gdk.DragAction actions) {
        checkState();
        Handle[] targets_g = new Handle[targets.length];
        for (int i = 0; i < targets.length; i++)
            targets_g[i] = targets[i].getHandle();
        gtk_drag_dest_set(getHandle(), flags.getValue(), targets_g, actions
                .getValue());
    }

    public void getDragData(DragContext context, Atom target, int time) {
        checkState();
        gtk_drag_get_data(getHandle(), context.getHandle(), target.getHandle(),
                time);
    }

    /**
     * Removes support for this widget being a drag and drop target
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void setNoDragDestination() {
        checkState();
        gtk_drag_dest_unset(getHandle());
    }

    /**
     * @deprecated Use {@link #getDragData(DragContext, Atom, int)}
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public static void getData(Widget widget, DragContext context, Atom target) {
        gtk_drag_get_data(widget.getHandle(), context.getHandle(), target
                .getHandle(), 0);
    }

    /**
     * @deprecated Use {@link DragContext#finish(boolean, boolean, int)}
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public static void finish(DragContext context, boolean success,
            boolean delete) {
        gtk_drag_finish(context.getHandle(), success, delete, 0);
    }

    /**
     * @deprecated Use {@link #highlight()}.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public static void highlight(Widget widget) {
        gtk_drag_highlight(widget.getHandle());
    }

    public void highlight() {
        checkState();
        gtk_drag_highlight(getHandle());
    }

    /**
     * @deprecated Use {@link #unHighlight()}.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public static void unHighlight(Widget widget) {
        gtk_drag_unhighlight(widget.getHandle());
    }

    public void unHighlight() {
        checkState();
        gtk_drag_unhighlight(getHandle());
    }

    /**
     * Register an object to receive drag drop (destination) events.
     * 
     * @param listener
     *            The object that has implemented the DragDestinationListener
     *            interface
     * @deprecated Use {@link #addListener(DragTargetListener)} instead.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void addListener(DragDestinationListener listener) {
    }

    public void addListener(DragTargetListener listener) {
        checkState();
        // Don't add the listener a second time if it is in the Vector.
        int i = findListener(dragTargetListeners, listener);
        if (i == -1) {
            if (null == dragTargetListeners) {
                evtMap.initialize(this,
                        LeaveDragDestinationEvent.Type.LEAVE_DESTINATION);
                evtMap.initialize(this, DropDragEvent.Type.DROP);
                evtMap.initialize(this, ReceiveDragDataEvent.Type.DATA_RECEIVE);
                evtMap.initialize(this, DragMotionEvent.Type.MOTION);
                dragTargetListeners = new Vector();
            }
            dragTargetListeners.addElement(listener);
        }
    }

    /**
     * Unregister an object that was receiving dragDestination event
     * notification.
     * 
     * @param listener
     *            The object that is to no longer receive dragDestination events
     * @deprecated Use {@link #removeListener(DragTargetListener)} instead.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void removeListener(DragDestinationListener listener) {
    }

    public void removeListener(DragTargetListener listener) {
        checkState();
        int i = findListener(dragTargetListeners, listener);
        if (i > -1)
            dragTargetListeners.remove(i);
        if (0 == dragTargetListeners.size()) {
            dragTargetListeners = null;
            evtMap.uninitialize(this,
                    LeaveDragDestinationEvent.Type.LEAVE_DESTINATION);
            evtMap.uninitialize(this, DropDragEvent.Type.DROP);
            evtMap.uninitialize(this, ReceiveDragDataEvent.Type.DATA_RECEIVE);
            evtMap.uninitialize(this, DragMotionEvent.Type.MOTION);
        }
    }

    protected void fireReceiveDragDataEvent(ReceiveDragDataEvent event) {
        if (null == dragTargetListeners)
            return;
        for (int i = 0, c = dragTargetListeners.size(); i < c; ++i) {
            DragTargetListener lc = (DragTargetListener) dragTargetListeners
                    .elementAt(i);
            lc.dataReceived(event);
        }
    }

    /**
     * Register an object to receive drag source events.
     * 
     * @param listener
     *            The object that has implemented the DragSourceListener
     *            interface
     * @deprecated Use {@link #addListener(DragOriginListener)} instead.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void addListener(DragSourceListener listener) {
    }

    public void addListener(DragOriginListener listener) {
        checkState();
        // Don't add the listener a second time if it is in the Vector.
        int i = findListener(dragOriginListeners, listener);
        if (i == -1) {
            if (null == dragOriginListeners) {
                dragOriginListeners = new Vector();
                evtMap.initialize(this, StartDragEvent.Type.START);
                evtMap.initialize(this, EndDragEvent.Type.END);
                evtMap.initialize(this, RequestDragDataEvent.Type.DATA_REQUEST,
                        false);
                evtMap.initialize(this, DeleteDragDataEvent.Type.DATA_DELETE);
            }
            dragOriginListeners.addElement(listener);
        }
    }

    /**
     * Unregister an object that was receiving drag source event notification.
     * 
     * @param listener
     *            The object that is to no longer receive drag source events
     * @deprecated Use {@link #removeListener(DragOriginListener)}
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void removeListener(DragSourceListener listener) {
    }

    public void removeListener(DragOriginListener listener) {
        checkState();
        int i = findListener(dragOriginListeners, listener);
        if (i > -1)
            dragOriginListeners.remove(i);
        if (0 == dragOriginListeners.size()) {
            dragOriginListeners = null;
            evtMap.uninitialize(this, StartDragEvent.Type.START);
            evtMap.uninitialize(this, EndDragEvent.Type.END);
            evtMap.uninitialize(this, RequestDragDataEvent.Type.DATA_REQUEST);
            evtMap.uninitialize(this, DeleteDragDataEvent.Type.DATA_DELETE);
        }
    }

    protected void fireStartDragEvent(StartDragEvent event) {
        if (dragOriginListeners == null) {
            return;
        }
        for (int i = 0, c = dragOriginListeners.size(); i < c; ++i) {
            DragOriginListener lc = (DragOriginListener) dragOriginListeners
                    .elementAt(i);
            lc.dragStarted(event);
        }
    }

    protected boolean fireDragMotionEvent(DragMotionEvent event) {
        boolean retVal = false;
        if (dragTargetListeners == null) {
            return false;
        }
        for (int i = 0, c = dragTargetListeners.size(); i < c; ++i) {
            DragTargetListener lc = (DragTargetListener) dragTargetListeners
                    .elementAt(i);
            if (lc.motionOcurred(event)) {
                retVal = true;
            }
        }
        return retVal;
    }

    protected void fireLeaveDragDestinationEvent(LeaveDragDestinationEvent event) {
        if (dragTargetListeners == null) {
            return;
        }
        for (int i = 0, c = dragTargetListeners.size(); i < c; ++i) {
            DragTargetListener lc = (DragTargetListener) dragTargetListeners
                    .elementAt(i);
            lc.destinationLeft(event);
        }
    }

    protected void fireDeleteDragDataEvent(DeleteDragDataEvent event) {
        if (dragOriginListeners == null) {
            return;
        }
        for (int i = 0, c = dragOriginListeners.size(); i < c; ++i) {
            DragOriginListener lc = (DragOriginListener) dragOriginListeners
                    .elementAt(i);
            lc.dataDeleted(event);
        }
    }

    protected boolean fireDropDragEvent(DropDragEvent event) {
        boolean retVal = false;
        if (dragTargetListeners == null) {
            return false;
        }
        for (int i = 0, c = dragTargetListeners.size(); i < c; ++i) {
            DragTargetListener lc = (DragTargetListener) dragTargetListeners
                    .elementAt(i);
            if (lc.dropped(event)) {
                retVal = true;
            }
        }
        return retVal;
    }

    protected void fireEndDragEvent(EndDragEvent event) {
        if (dragOriginListeners == null) {
            return;
        }
        for (int i = 0, c = dragOriginListeners.size(); i < c; ++i) {
            DragOriginListener lc = (DragOriginListener) dragOriginListeners
                    .elementAt(i);
            lc.dragEnded(event);
        }
    }

    protected void fireRequestDragDataEvent(RequestDragDataEvent event) {
        if (null == dragOriginListeners)
            return;
        for (int i = 0, c = dragOriginListeners.size(); i < c; ++i) {
            DragOriginListener lc = (DragOriginListener) dragOriginListeners
                    .elementAt(i);
            lc.dataRequested(event);
        }
    }

    protected void handleDragStarted(Handle contextHandle) {
        StartDragEvent event = new StartDragEvent(this,
                StartDragEvent.Type.START, getDragContext(contextHandle));
        fireStartDragEvent(event);
    }

    protected void handleDragDataDeleted(Handle contextHandle) {
        DeleteDragDataEvent event = new DeleteDragDataEvent(this,
                DeleteDragDataEvent.Type.DATA_DELETE,
                getDragContext(contextHandle));
        fireDeleteDragDataEvent(event);
    }

    protected boolean handleDragDropped(Handle contextHandle, int x, int y,
            int time) {
        DragContext dc = getDragContext(contextHandle);
        DragEvent event = new DragEvent(this, DropDragEvent.Type.DROP, dc);
        DropDragEvent dropEvent = new DropDragEvent(event, x, y, time);
        return fireDropDragEvent(dropEvent);
    }

    protected void handleDragEnded(Handle contextHandle) {
        EndDragEvent event = new EndDragEvent(this, EndDragEvent.Type.END,
                getDragContext(contextHandle));
        fireEndDragEvent(event);
    }

    protected void handleDragDataReceived(Handle contextHandle, int x, int y,
            Handle dataHandle, int targetInfo, int time) {
        SelectionData sd = getSelectionData(dataHandle);
        DragContext dc = getDragContext(contextHandle);
        DragEvent event = new DragEvent(this,
                ReceiveDragDataEvent.Type.DATA_RECEIVE, dc);
        ReceiveDragDataEvent dataReceiveEvent = new ReceiveDragDataEvent(event,
                x, y, sd, targetInfo, time);
        fireReceiveDragDataEvent(dataReceiveEvent);
    }

    protected void handleDragDestinationLeft(Handle contextHandle, int time) {
        DragEvent event = new DragEvent(this,
                LeaveDragDestinationEvent.Type.LEAVE_DESTINATION,
                getDragContext(contextHandle));
        LeaveDragDestinationEvent destEvent = new LeaveDragDestinationEvent(
                event, time);
        fireLeaveDragDestinationEvent(destEvent);
    }

    protected boolean handleDragMotionOccurred(Handle contextHandle, int x,
            int y, int time) {
        DragEvent event = new DragEvent(this, DragMotionEvent.Type.MOTION,
                getDragContext(contextHandle));
        DragMotionEvent motionEvent = new DragMotionEvent(event, x, y, time);
        return fireDragMotionEvent(motionEvent);
    }

    protected void handleDragDataRequested(Handle contextHandle,
            Handle dataHandle, int targetInfo, int time) {
        SelectionData sd = getSelectionData(dataHandle);
        DragContext dc = getDragContext(contextHandle);
        DragEvent event = new DragEvent(this,
                RequestDragDataEvent.Type.DATA_REQUEST, dc);
        RequestDragDataEvent dataRequestEvent = new RequestDragDataEvent(event,
                sd, targetInfo, time);
        fireRequestDragDataEvent(dataRequestEvent);
    }

    private SelectionData getSelectionData(Handle selectionDataHandle) {
        SelectionData selectionData = (SelectionData) Boxed
                .getBoxedFromHandle(selectionDataHandle);
        if (selectionData == null) {
            selectionData = new SelectionData(selectionDataHandle);
        }
        return selectionData;
    }

    private DragContext getDragContext(Handle contextHandle) {
        DragContext context = (DragContext) GObject
                .getGObjectFromHandle(contextHandle);
        if (context == null) {
            context = new DragContext(contextHandle);
        }
        return context;
    }

    /***************************************************************************
     * Expose event handling.
     **************************************************************************/
    /**
     * Register an object to receive expose event notification.
     * 
     * @param listener
     *            The object that has implemented the ExposeListener interface
     *            that is to receive the expose events.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void addListener(ExposeListener listener) {
        checkState();
        // Don't add the listener a second time if it is in the Vector.
        int i = findListener(exposeListeners, listener);
        if (i == -1) {
            if (null == exposeListeners) {
                evtMap.initialize(this, ExposeEvent.Type.EXPOSE);
                evtMap.initialize(this, ExposeEvent.Type.NO_EXPOSE);
                exposeListeners = new Vector();
            }
            exposeListeners.addElement(listener);
        }
    }

    /**
     * Unregister an object that was receiving expose event notification.
     * 
     * @param listener
     *            The object that is to no longer receive expose events.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void removeListener(ExposeListener listener) {
        checkState();
        int i = findListener(exposeListeners, listener);
        if (i > -1)
            exposeListeners.remove(i);
        if (0 == exposeListeners.size()) {
            evtMap.uninitialize(this, ExposeEvent.Type.EXPOSE);
            evtMap.uninitialize(this, ExposeEvent.Type.NO_EXPOSE);
            exposeListeners = null;
        }
    }

    protected boolean fireExposeEvent(ExposeEvent event) {
        if (null == exposeListeners)
            return false;
        boolean retval = false;
        int size = exposeListeners.size();
        int i = 0;
        while (i < size) {
            ExposeListener kl = (ExposeListener) exposeListeners.elementAt(i);
            if (kl.exposeEvent(event))
                retval = true;
            i++;
        }
        return retval;
    }

    protected boolean handleExpose(Handle event) {
        return fireExposeEvent(new ExposeEvent(this, EventExpose
                .getEventExpose(event)));
    }

    protected boolean handleNoExpose(Handle event) {
        return fireExposeEvent(new ExposeEvent(this, EventExpose
                .getEventExpose(event)));
    }

    /***************************************************************************
     * MouseMotion event handling.
     **************************************************************************/
    /**
     * Register an object to receive mouse motion event notification.
     * <p>
     * An important thing to notice is that some widgets don't receive
     * <i>low-level</i> events (such as a mouse-enter event) by default. So if
     * you want to capture events from them, you should add them to an
     * <code>EventBox</code>, and capture events on the <code>EventBox</code>.
     * <p>
     * The reason why this happens is that some widgets, for efficiency, don't
     * have their own X window, which is necessary to receive events. These are
     * the widgets that don't have their own X window:
     * <p>
     * <code>Alignment</code> <br>
     * <code>Arrow</code> <br>
     * <code>Bin</code> <br>
     * <code>Box</code> <br>
     * <code>Image</code> <br>
     * <code>Item</code> <br>
     * <code>Label</code> <br>
     * <code>Pixmap</code> <br>
     * <code>ScrolledWindow</code> <br>
     * <code>Separator</code> <br>
     * <code>Table</code> <br>
     * <code>AspectFrame</code> <br>
     * <code>Frame</code> <br>
     * <code>VBox</code> <br>
     * <code>HBox</code> <br>
     * <code>VSeparator</code> <br>
     * <code>HSeparator</code> <br>
     * 
     * @param listener
     *            The object that has implemented the MouseMotionListener
     *            interface that is to receive the mouse motion events.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void addListener(MouseMotionListener listener) {
        this.addEvents(EventMask.POINTER_MOTION_MASK);
        checkState();
        // Don't add the listener a second time if it is in the Vector.
        int i = findListener(mouseMotionListeners, listener);
        if (i == -1) {
            if (null == mouseMotionListeners) {
                evtMap.initialize(this, MouseMotionEvent.Type.MOTION);
                mouseMotionListeners = new Vector();
            }
            mouseMotionListeners.addElement(listener);
        }
    }

    /**
     * Unregister an object that was receiving mouse motion event notification.
     * 
     * @param listener
     *            The object that is to no longer receive mouse motion events.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void removeListener(MouseMotionListener listener) {
        checkState();
        int i = findListener(mouseMotionListeners, listener);
        if (i > -1)
            mouseMotionListeners.remove(i);
        if (0 == mouseMotionListeners.size()) {
            evtMap.uninitialize(this, MouseMotionEvent.Type.MOTION);
            mouseMotionListeners = null;
        }
    }

    protected boolean fireMouseMotionEvent(MouseMotionEvent event) {
        if (null == mouseMotionListeners)
            return false;
        boolean retval = false;
        int size = mouseMotionListeners.size();
        int i = 0;
        while (i < size) {
            MouseMotionListener kl = (MouseMotionListener) mouseMotionListeners
                    .elementAt(i);
            if (kl.mouseMotionEvent(event))
                retval = true;
            i++;
        }
        return retval;
    }

    protected boolean handleMouseMotion(Handle event) {
        return fireMouseMotionEvent(new MouseMotionEvent(this, new EventMotion(
                event)));
    }

    /**
     * <p>
     *   Utility function used for returning the handle of a given Struct.
     *   This funciton is needed in order to avoid null pointer exception.
     *   Some GTK function accept a NULL object, when a corresponding null
     *   object is given to the Java bindings a null pointer is thrown because
     *   the handle can't be fetched. This function prevents such error.
     * </p>
     *
     * <p>
     * <b>NOTE:</b> This function should probably be moved to the class
     * org.gnu.glib.Struct as it's likely that other classes could use it.
     * </p>
     *
     * @param struct any kind of object that provides a handle.
     * @return null if the given struct is null or the struct's handle.
     * @deprecated Superceeded by java-gnome 4.0; we don't use getHandle() anymore
     */
    private Handle getHandle(Struct struct) {
        return struct == null ? null : struct.getHandle();
    }

    native static final protected int gtk_widget_get_type();

    native static final protected void gtk_widget_destroy(Handle widget);

    native static final protected void gtk_widget_destroyed(Handle widget,
            Handle[] widgetPointer);

    native static final protected void gtk_widget_unparent(Handle widget);

    native static final protected void gtk_widget_show(Handle widget);

    native static final protected void gtk_widget_show_now(Handle widget);

    native static final protected void gtk_widget_hide(Handle widget);

    native static final protected void gtk_widget_show_all(Handle widget);

    native static final protected void gtk_widget_hide_all(Handle widget);

    native static final protected void gtk_widget_map(Handle widget);

    native static final protected void gtk_widget_unmap(Handle widget);

    native static final protected void gtk_widget_realize(Handle widget);

    native static final protected void gtk_widget_unrealize(Handle widget);

    native static final protected void gtk_widget_queue_draw(Handle widget);

    native static final protected void gtk_widget_queue_draw_area(
            Handle widget, int x, int y, int width, int height);

    native static final protected void gtk_widget_queue_resize(Handle widget);

    native static final protected void gtk_widget_size_request(Handle widget,
            Handle requisition);

    native static final protected void gtk_widget_get_child_requisition(
            Handle widget, Handle[] requisition);

    native static final protected void gtk_widget_size_allocate(Handle widget,
            Handle allocation);

    native static final protected void gtk_widget_add_accelerator(
            Handle widget, Handle accelGroup, int accelKey, int accelMods,
            int accelFlags);

    native static final protected boolean gtk_widget_remove_accelerator(
            Handle widget, Handle accelGroup, int accelKey, int accelMods);

    native static final protected void gtk_widget_set_accel_path(Handle widget,
            String accelPath, Handle accelGroup);

    // TODO: this signature is wrong - needs to be fixed prior to using
    native static final protected Handle gtk_widget_list_accel_closures(
            Handle widget);

    native static final protected boolean gtk_widget_can_activate_accel(
            Handle widget, int signalId);

    native static final protected boolean gtk_widget_mnemonic_activate(
            Handle widget, boolean groupCycling);

    native static final protected boolean gtk_widget_event(Handle widget,
            Handle event);

    native static final protected int gtk_widget_send_expose(Handle widget,
            Handle event);

    native static final protected boolean gtk_widget_activate(Handle widget);

    native static final protected void gtk_widget_set_scroll_adjustments(
            Handle widget, Handle hadj, Handle vadj);

    native static final protected void gtk_widget_reparent(Handle widget,
            Handle newParent);

    native static final protected Handle gtk_widget_intersect(Handle widget,
            Handle area);

    native static final protected Handle gtk_widget_region_intersect(
            Handle widget, Handle region);

    native static final protected void gtk_widget_freeze_child_notify(
            Handle widget);

    native static final protected void gtk_widget_child_notify(Handle widget,
            String childProperty);

    native static final protected void gtk_widget_thaw_child_notify(
            Handle widget);

    native static final protected boolean gtk_widget_is_focus(Handle widget);

    native static final protected void gtk_widget_grab_focus(Handle widget);

    native static final protected void gtk_widget_grab_default(Handle widget);

    native static final protected void gtk_widget_set_name(Handle widget,
            String name);

    native static final protected String gtk_widget_get_name(Handle widget);

    native static final protected void gtk_widget_set_state(Handle widget,
            int state);

    native static final protected void gtk_widget_set_sensitive(Handle widget,
            boolean sensitive);

    native static final protected void gtk_widget_set_app_paintable(
            Handle widget, boolean appPaintable);

    native static final protected void gtk_widget_set_double_buffered(
            Handle widget, boolean doubleBuffered);

    native static final protected void gtk_widget_set_redraw_on_allocate(
            Handle widget, boolean redrawOnAllocate);

    native static final protected void gtk_widget_set_parent(Handle widget,
            Handle parent);

    native static final protected void gtk_widget_set_parent_window(
            Handle widget, Handle parent);

    native static final protected void gtk_widget_set_child_visible(
            Handle widget, boolean isVisible);

    native static final protected boolean gtk_widget_get_child_visible(
            Handle widget);

    native static final protected Handle gtk_widget_get_parent(Handle widget);

    native static final protected Handle gtk_widget_get_parent_window(
            Handle widget);

    native static final protected Handle gtk_widget_get_window(Handle widget);

    native static final protected boolean gtk_widget_child_focus(Handle widget,
            int direction);

    native static final protected void gtk_widget_set_size_request(
            Handle widget, int width, int height);

    native static final protected void gtk_widget_get_size_request(
            Handle widget, int[] width, int[] height);

    native static final protected void gtk_widget_set_events(Handle widget,
            int events);

    native static final protected void gtk_widget_add_events(Handle widget,
            int events);

    native static final protected void gtk_widget_set_extension_events(
            Handle widget, int mode);

    native static final protected int gtk_widget_get_extension_events(
            Handle widget);

    native static final protected Handle gtk_widget_get_toplevel(Handle widget);

    native static final protected Handle gtk_widget_get_ancestor(Handle widget,
            int widgetType);

    native static final protected Handle gtk_widget_get_colormap(Handle widget);

    native static final protected Handle gtk_widget_get_visual(Handle widget);

    native static final protected Handle gtk_widget_get_screen(Handle widget);

    native static final protected boolean gtk_widget_has_screen(Handle widget);

    native static final protected Handle gtk_widget_get_display(Handle widget);

    native static final protected Handle gtk_widget_get_root_window(
            Handle widget);

    native static final protected boolean gtk_widget_get_sensitive(Handle widget);

    native static final protected Handle gtk_widget_get_settings(Handle widget);

    native static final protected Handle gtk_widget_get_accessible(Handle widget);

    native static final protected void gtk_widget_set_colormap(Handle widget,
            Handle cmap);

    native static final protected int gtk_widget_get_events(Handle widget);

    native static final protected void gtk_widget_get_pointer(Handle widget,
            int[] x, int[] y);

    native static final protected boolean gtk_widget_is_ancestor(Handle widget,
            Handle ancestor);

    native static final protected boolean gtk_widget_translate_coordinates(
            Handle srcWidget, Handle destWidget, int srcX, int srcY,
            int[] destX, int[] destY);

    native static final protected boolean gtk_widget_hide_on_delete(
            Handle widget);

    native static final protected void gtk_widget_set_style(Handle widget,
            Handle style);

    native static final protected void gtk_widget_ensure_style(Handle widget);

    native static final protected Handle gtk_widget_get_style(Handle widget);

    native static final protected void gtk_widget_modify_style(Handle widget,
            Handle style);

    native static final protected Handle gtk_widget_get_modifier_style(
            Handle widget);

    native static final protected void gtk_widget_modify_fg(Handle widget,
            int state, Handle color);

    native static final protected void gtk_widget_modify_bg(Handle widget,
            int state, Handle color);

    native static final protected void gtk_widget_modify_text(Handle widget,
            int state, Handle color);

    native static final protected void gtk_widget_modify_base(Handle widget,
            int state, Handle color);

    native static final protected void gtk_widget_modify_font(Handle widget,
            Handle fontDesc);

    native static final protected Handle gtk_widget_create_pango_context(
            Handle widget);

    native static final protected Handle gtk_widget_get_pango_context(
            Handle widget);

    native static final protected Handle gtk_widget_create_pango_layout(
            Handle widget, String text);

    native static final protected Handle gtk_widget_render_icon(Handle widget,
            String stockID, int size, String detail);

    native static final protected void gtk_widget_set_composite_name(
            Handle widget, String name);

    native static final protected String gtk_widget_get_composite_name(
            Handle widget);

    native static final protected void gtk_widget_reset_rc_styles(Handle widget);

    native static final protected void gtk_widget_push_colormap(Handle cmap);

    native static final protected void gtk_widget_pop_colormap();

    native static final protected void gtk_widget_push_composite_child();

    native static final protected void gtk_widget_pop_composite_child();

    native static final protected void gtk_widget_style_get_property(
            Handle widget, String propertyName, Handle value);

    native static final protected void gtk_widget_set_default_colormap(
            Handle cmap);

    native static final protected Handle gtk_widget_get_default_colormap();

    native static final protected Handle gtk_widget_get_default_visual();

    native static final protected Handle gtk_widget_get_default_style();

    native static final protected void gtk_widget_set_direction(Handle widget,
            int dir);

    native static final protected int gtk_widget_get_direction(Handle widget);

    native static final protected void gtk_widget_set_default_direction(int dir);

    native static final protected int gtk_widget_get_default_direction();

    native static final protected void gtk_widget_shape_combine_mask(
            Handle widget, Handle shapeMask, int offsetX, int offsetY);

    native static final protected void gtk_widget_path(Handle widget,
            int[] pathLength, String[] path, String[] pathReversed);

    native static final protected void gtk_widget_class_path(Handle widget,
            int[] pathLength, String[] path, String[] pathReversed);

    native static final protected Handle[] gtk_widget_list_mnemonic_labels(
            Handle widget);

    native static final protected void gtk_widget_add_mnemonic_label(
            Handle widget, Handle label);

    native static final protected void gtk_widget_remove_mnemonic_label(
            Handle widget, Handle label);

    native static final protected Allocation gtk_widget_get_allocation(
            Handle widget);

    // Drag and Drop support
    native static final protected void gtk_drag_source_set(Handle widget,
            int start_button_mask, Handle[] targets, int actions);

    native static final protected void gtk_drag_source_unset(Handle widget);

    native static final protected void gtk_drag_source_set_icon(Handle widget,
            Handle colormap, Handle pixmap, Handle mask);

    native static final protected void gtk_drag_source_set_icon_pixbuf(
            Handle widget, Handle pixbuf);

    native static final protected void gtk_drag_source_set_icon_stock(
            Handle widget, String stockId);

    native static final protected void gtk_drag_get_data(Handle widget,
            Handle context, Handle target, int time);

    native static final protected void gtk_drag_finish(Handle context,
            boolean success, boolean delete, int time);

    native static final protected void gtk_drag_highlight(Handle widget);

    native static final protected void gtk_drag_unhighlight(Handle widget);

    native static final protected void gtk_drag_dest_set(Handle widget,
            int flags, Handle[] targets, int actions);

    native static final protected void gtk_drag_dest_unset(Handle widget);
}
