Blame modules/other/gail/gailwidget.c

Packit Service fb6fa5
/* GAIL - The GNOME Accessibility Implementation Library
Packit Service fb6fa5
 * Copyright 2001, 2002, 2003 Sun Microsystems Inc.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * This library is free software; you can redistribute it and/or
Packit Service fb6fa5
 * modify it under the terms of the GNU Lesser General Public
Packit Service fb6fa5
 * License as published by the Free Software Foundation; either
Packit Service fb6fa5
 * version 2 of the License, or (at your option) any later version.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * This library is distributed in the hope that it will be useful,
Packit Service fb6fa5
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service fb6fa5
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service fb6fa5
 * Lesser General Public License for more details.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * You should have received a copy of the GNU Lesser General Public
Packit Service fb6fa5
 * License along with this library; if not, write to the
Packit Service fb6fa5
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Packit Service fb6fa5
 * Boston, MA 02111-1307, USA.
Packit Service fb6fa5
 */
Packit Service fb6fa5
Packit Service fb6fa5
#include "config.h"
Packit Service fb6fa5
Packit Service fb6fa5
#include <string.h>
Packit Service fb6fa5
Packit Service fb6fa5
#undef GTK_DISABLE_DEPRECATED
Packit Service fb6fa5
Packit Service fb6fa5
#include <gtk/gtk.h>
Packit Service fb6fa5
#ifdef GDK_WINDOWING_X11
Packit Service fb6fa5
#include <gdk/x11/gdkx.h>
Packit Service fb6fa5
#endif
Packit Service fb6fa5
#include "gailwidget.h"
Packit Service fb6fa5
#include "gailnotebookpage.h"
Packit Service fb6fa5
#include "gail-private-macros.h"
Packit Service fb6fa5
Packit Service fb6fa5
extern GtkWidget *focus_widget;
Packit Service fb6fa5
Packit Service fb6fa5
static void gail_widget_class_init (GailWidgetClass *klass);
Packit Service fb6fa5
static void gail_widget_init                     (GailWidget       *accessible);
Packit Service fb6fa5
static void gail_widget_connect_widget_destroyed (GtkAccessible    *accessible);
Packit Service fb6fa5
static void gail_widget_destroyed                (GtkWidget        *widget,
Packit Service fb6fa5
                                                  GtkAccessible    *accessible);
Packit Service fb6fa5
Packit Service fb6fa5
static const gchar* gail_widget_get_description (AtkObject *accessible);
Packit Service fb6fa5
static AtkObject* gail_widget_get_parent (AtkObject *accessible);
Packit Service fb6fa5
static AtkStateSet* gail_widget_ref_state_set (AtkObject *accessible);
Packit Service fb6fa5
static AtkRelationSet* gail_widget_ref_relation_set (AtkObject *accessible);
Packit Service fb6fa5
static gint gail_widget_get_index_in_parent (AtkObject *accessible);
Packit Service fb6fa5
Packit Service fb6fa5
static void atk_component_interface_init (AtkComponentIface *iface);
Packit Service fb6fa5
Packit Service fb6fa5
static guint    gail_widget_add_focus_handler
Packit Service fb6fa5
                                           (AtkComponent    *component,
Packit Service fb6fa5
                                            AtkFocusHandler handler);
Packit Service fb6fa5
Packit Service fb6fa5
static void     gail_widget_get_extents    (AtkComponent    *component,
Packit Service fb6fa5
                                            gint            *x,
Packit Service fb6fa5
                                            gint            *y,
Packit Service fb6fa5
                                            gint            *width,
Packit Service fb6fa5
                                            gint            *height,
Packit Service fb6fa5
                                            AtkCoordType    coord_type);
Packit Service fb6fa5
Packit Service fb6fa5
static void     gail_widget_get_size       (AtkComponent    *component,
Packit Service fb6fa5
                                            gint            *width,
Packit Service fb6fa5
                                            gint            *height);
Packit Service fb6fa5
Packit Service fb6fa5
static AtkLayer gail_widget_get_layer      (AtkComponent *component);
Packit Service fb6fa5
Packit Service fb6fa5
static gboolean gail_widget_grab_focus     (AtkComponent    *component);
Packit Service fb6fa5
Packit Service fb6fa5
Packit Service fb6fa5
static void     gail_widget_remove_focus_handler 
Packit Service fb6fa5
                                           (AtkComponent    *component,
Packit Service fb6fa5
                                            guint           handler_id);
Packit Service fb6fa5
Packit Service fb6fa5
static gboolean gail_widget_set_extents    (AtkComponent    *component,
Packit Service fb6fa5
                                            gint            x,
Packit Service fb6fa5
                                            gint            y,
Packit Service fb6fa5
                                            gint            width,
Packit Service fb6fa5
                                            gint            height,
Packit Service fb6fa5
                                            AtkCoordType    coord_type);
Packit Service fb6fa5
Packit Service fb6fa5
static gboolean gail_widget_set_position   (AtkComponent    *component,
Packit Service fb6fa5
                                            gint            x,
Packit Service fb6fa5
                                            gint            y,
Packit Service fb6fa5
                                            AtkCoordType    coord_type);
Packit Service fb6fa5
Packit Service fb6fa5
static gboolean gail_widget_set_size       (AtkComponent    *component,
Packit Service fb6fa5
                                            gint            width,
Packit Service fb6fa5
                                            gint            height);
Packit Service fb6fa5
Packit Service fb6fa5
static gint       gail_widget_map_gtk            (GtkWidget     *widget);
Packit Service fb6fa5
static void       gail_widget_real_notify_gtk    (GObject       *obj,
Packit Service fb6fa5
                                                  GParamSpec    *pspec);
Packit Service fb6fa5
static void       gail_widget_notify_gtk         (GObject       *obj,
Packit Service fb6fa5
                                                  GParamSpec    *pspec);
Packit Service fb6fa5
static gboolean   gail_widget_focus_gtk          (GtkWidget     *widget,
Packit Service fb6fa5
                                                  GdkEventFocus *event);
Packit Service fb6fa5
static gboolean   gail_widget_real_focus_gtk     (GtkWidget     *widget,
Packit Service fb6fa5
                                                  GdkEventFocus *event);
Packit Service fb6fa5
static void       gail_widget_size_allocate_gtk  (GtkWidget     *widget,
Packit Service fb6fa5
                                                  GtkAllocation *allocation);
Packit Service fb6fa5
Packit Service fb6fa5
static void       gail_widget_focus_event        (AtkObject     *obj,
Packit Service fb6fa5
                                                  gboolean      focus_in);
Packit Service fb6fa5
Packit Service fb6fa5
static void       gail_widget_real_initialize    (AtkObject     *obj,
Packit Service fb6fa5
                                                  gpointer      data);
Packit Service fb6fa5
static GtkWidget* gail_widget_find_viewport      (GtkWidget     *widget);
Packit Service fb6fa5
static gboolean   gail_widget_on_screen          (GtkWidget     *widget);
Packit Service fb6fa5
static gboolean   gail_widget_all_parents_visible(GtkWidget     *widget);
Packit Service fb6fa5
Packit Service fb6fa5
G_DEFINE_TYPE_WITH_CODE (GailWidget, gail_widget, GTK_TYPE_ACCESSIBLE,
Packit Service fb6fa5
                         G_IMPLEMENT_INTERFACE (ATK_TYPE_COMPONENT, atk_component_interface_init))
Packit Service fb6fa5
Packit Service fb6fa5
static void
Packit Service fb6fa5
gail_widget_class_init (GailWidgetClass *klass)
Packit Service fb6fa5
{
Packit Service fb6fa5
  AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
Packit Service fb6fa5
  GtkAccessibleClass *accessible_class = GTK_ACCESSIBLE_CLASS (klass);
Packit Service fb6fa5
Packit Service fb6fa5
  klass->notify_gtk = gail_widget_real_notify_gtk;
Packit Service fb6fa5
  klass->focus_gtk = gail_widget_real_focus_gtk;
Packit Service fb6fa5
Packit Service fb6fa5
  accessible_class->connect_widget_destroyed = gail_widget_connect_widget_destroyed;
Packit Service fb6fa5
Packit Service fb6fa5
  class->get_description = gail_widget_get_description;
Packit Service fb6fa5
  class->get_parent = gail_widget_get_parent;
Packit Service fb6fa5
  class->ref_relation_set = gail_widget_ref_relation_set;
Packit Service fb6fa5
  class->ref_state_set = gail_widget_ref_state_set;
Packit Service fb6fa5
  class->get_index_in_parent = gail_widget_get_index_in_parent;
Packit Service fb6fa5
  class->initialize = gail_widget_real_initialize;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static void
Packit Service fb6fa5
gail_widget_init (GailWidget *accessible)
Packit Service fb6fa5
{
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * This function  specifies the GtkWidget for which the GailWidget was created 
Packit Service fb6fa5
 * and specifies a handler to be called when the GtkWidget is destroyed.
Packit Service fb6fa5
 **/
Packit Service fb6fa5
static void 
Packit Service fb6fa5
gail_widget_real_initialize (AtkObject *obj,
Packit Service fb6fa5
                             gpointer  data)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GtkAccessible *accessible;
Packit Service fb6fa5
  GtkWidget *widget;
Packit Service fb6fa5
Packit Service fb6fa5
  g_return_if_fail (GTK_IS_WIDGET (data));
Packit Service fb6fa5
Packit Service fb6fa5
  widget = GTK_WIDGET (data);
Packit Service fb6fa5
Packit Service fb6fa5
  accessible = GTK_ACCESSIBLE (obj);
Packit Service fb6fa5
  accessible->widget = widget;
Packit Service fb6fa5
  gtk_accessible_connect_widget_destroyed (accessible);
Packit Service fb6fa5
  g_signal_connect_after (widget,
Packit Service fb6fa5
                          "focus-in-event",
Packit Service fb6fa5
                          G_CALLBACK (gail_widget_focus_gtk),
Packit Service fb6fa5
                          NULL);
Packit Service fb6fa5
  g_signal_connect_after (widget,
Packit Service fb6fa5
                          "focus-out-event",
Packit Service fb6fa5
                          G_CALLBACK (gail_widget_focus_gtk),
Packit Service fb6fa5
                          NULL);
Packit Service fb6fa5
  g_signal_connect (widget,
Packit Service fb6fa5
                    "notify",
Packit Service fb6fa5
                    G_CALLBACK (gail_widget_notify_gtk),
Packit Service fb6fa5
                    NULL);
Packit Service fb6fa5
  g_signal_connect (widget,
Packit Service fb6fa5
                    "size_allocate",
Packit Service fb6fa5
                    G_CALLBACK (gail_widget_size_allocate_gtk),
Packit Service fb6fa5
                    NULL);
Packit Service fb6fa5
  atk_component_add_focus_handler (ATK_COMPONENT (accessible),
Packit Service fb6fa5
                                   gail_widget_focus_event);
Packit Service fb6fa5
  /*
Packit Service fb6fa5
   * Add signal handlers for GTK signals required to support property changes
Packit Service fb6fa5
   */
Packit Service fb6fa5
  g_signal_connect (widget,
Packit Service fb6fa5
                    "map",
Packit Service fb6fa5
                    G_CALLBACK (gail_widget_map_gtk),
Packit Service fb6fa5
                    NULL);
Packit Service fb6fa5
  g_signal_connect (widget,
Packit Service fb6fa5
                    "unmap",
Packit Service fb6fa5
                    G_CALLBACK (gail_widget_map_gtk),
Packit Service fb6fa5
                    NULL);
Packit Service fb6fa5
  g_object_set_data (G_OBJECT (obj), "atk-component-layer",
Packit Service fb6fa5
		     GINT_TO_POINTER (ATK_LAYER_WIDGET));
Packit Service fb6fa5
Packit Service fb6fa5
  obj->role = ATK_ROLE_UNKNOWN;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
AtkObject* 
Packit Service fb6fa5
gail_widget_new (GtkWidget *widget)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GObject *object;
Packit Service fb6fa5
  AtkObject *accessible;
Packit Service fb6fa5
Packit Service fb6fa5
  g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
Packit Service fb6fa5
Packit Service fb6fa5
  object = g_object_new (GAIL_TYPE_WIDGET, NULL);
Packit Service fb6fa5
Packit Service fb6fa5
  accessible = ATK_OBJECT (object);
Packit Service fb6fa5
  atk_object_initialize (accessible, widget);
Packit Service fb6fa5
Packit Service fb6fa5
  return accessible;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/*
Packit Service fb6fa5
 * This function specifies the function to be called when the widget
Packit Service fb6fa5
 * is destroyed
Packit Service fb6fa5
 */
Packit Service fb6fa5
static void
Packit Service fb6fa5
gail_widget_connect_widget_destroyed (GtkAccessible *accessible)
Packit Service fb6fa5
{
Packit Service fb6fa5
  if (accessible->widget)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      g_signal_connect_after (accessible->widget,
Packit Service fb6fa5
                              "destroy",
Packit Service fb6fa5
                              G_CALLBACK (gail_widget_destroyed),
Packit Service fb6fa5
                              accessible);
Packit Service fb6fa5
    }
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/*
Packit Service fb6fa5
 * This function is called when the widget is destroyed.
Packit Service fb6fa5
 * It sets the widget field in the GtkAccessible structure to NULL
Packit Service fb6fa5
 * and emits a state-change signal for the state ATK_STATE_DEFUNCT
Packit Service fb6fa5
 */
Packit Service fb6fa5
static void 
Packit Service fb6fa5
gail_widget_destroyed (GtkWidget     *widget,
Packit Service fb6fa5
                       GtkAccessible *accessible)
Packit Service fb6fa5
{
Packit Service fb6fa5
  accessible->widget = NULL;
Packit Service fb6fa5
  atk_object_notify_state_change (ATK_OBJECT (accessible), ATK_STATE_DEFUNCT,
Packit Service fb6fa5
                                  TRUE);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static const gchar*
Packit Service fb6fa5
gail_widget_get_description (AtkObject *accessible)
Packit Service fb6fa5
{
Packit Service fb6fa5
  if (accessible->description)
Packit Service fb6fa5
    return accessible->description;
Packit Service fb6fa5
  else
Packit Service fb6fa5
    {
Packit Service fb6fa5
      /* Get the tooltip from the widget */
Packit Service fb6fa5
      GtkAccessible *obj = GTK_ACCESSIBLE (accessible);
Packit Service fb6fa5
Packit Service fb6fa5
      gail_return_val_if_fail (obj, NULL);
Packit Service fb6fa5
Packit Service fb6fa5
      if (obj->widget == NULL)
Packit Service fb6fa5
        /*
Packit Service fb6fa5
         * Object is defunct
Packit Service fb6fa5
         */
Packit Service fb6fa5
        return NULL;
Packit Service fb6fa5
 
Packit Service fb6fa5
      gail_return_val_if_fail (GTK_WIDGET (obj->widget), NULL);
Packit Service fb6fa5
Packit Service fb6fa5
      return gtk_widget_get_tooltip_text (obj->widget);
Packit Service fb6fa5
    }
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static AtkObject* 
Packit Service fb6fa5
gail_widget_get_parent (AtkObject *accessible)
Packit Service fb6fa5
{
Packit Service fb6fa5
  AtkObject *parent;
Packit Service fb6fa5
Packit Service fb6fa5
  parent = accessible->accessible_parent;
Packit Service fb6fa5
Packit Service fb6fa5
  if (parent != NULL)
Packit Service fb6fa5
    g_return_val_if_fail (ATK_IS_OBJECT (parent), NULL);
Packit Service fb6fa5
  else
Packit Service fb6fa5
    {
Packit Service fb6fa5
      GtkWidget *widget, *parent_widget;
Packit Service fb6fa5
Packit Service fb6fa5
      widget = GTK_ACCESSIBLE (accessible)->widget;
Packit Service fb6fa5
      if (widget == NULL)
Packit Service fb6fa5
        /*
Packit Service fb6fa5
         * State is defunct
Packit Service fb6fa5
         */
Packit Service fb6fa5
        return NULL;
Packit Service fb6fa5
      gail_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
Packit Service fb6fa5
Packit Service fb6fa5
      parent_widget = widget->parent;
Packit Service fb6fa5
      if (parent_widget == NULL)
Packit Service fb6fa5
        return NULL;
Packit Service fb6fa5
Packit Service fb6fa5
      /*
Packit Service fb6fa5
       * For a widget whose parent is a GtkNoteBook, we return the
Packit Service fb6fa5
       * accessible object corresponding the GtkNotebookPage containing
Packit Service fb6fa5
       * the widget as the accessible parent.
Packit Service fb6fa5
       */
Packit Service fb6fa5
      if (GTK_IS_NOTEBOOK (parent_widget))
Packit Service fb6fa5
        {
Packit Service fb6fa5
          gint page_num;
Packit Service fb6fa5
          GtkWidget *child;
Packit Service fb6fa5
          GtkNotebook *notebook;
Packit Service fb6fa5
Packit Service fb6fa5
          page_num = 0;
Packit Service fb6fa5
          notebook = GTK_NOTEBOOK (parent_widget);
Packit Service fb6fa5
          while (TRUE)
Packit Service fb6fa5
            {
Packit Service fb6fa5
              child = gtk_notebook_get_nth_page (notebook, page_num);
Packit Service fb6fa5
              if (!child)
Packit Service fb6fa5
                break;
Packit Service fb6fa5
              if (child == widget)
Packit Service fb6fa5
                {
Packit Service fb6fa5
                  parent = gtk_widget_get_accessible (parent_widget);
Packit Service fb6fa5
                  parent = atk_object_ref_accessible_child (parent, page_num);
Packit Service fb6fa5
                  g_object_unref (parent);
Packit Service fb6fa5
                  return parent;
Packit Service fb6fa5
                }
Packit Service fb6fa5
              page_num++;
Packit Service fb6fa5
            }
Packit Service fb6fa5
        }
Packit Service fb6fa5
Packit Service fb6fa5
      parent = gtk_widget_get_accessible (parent_widget);
Packit Service fb6fa5
    }
Packit Service fb6fa5
  return parent;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static GtkWidget*
Packit Service fb6fa5
find_label (GtkWidget *widget)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GList *labels;
Packit Service fb6fa5
  GtkWidget *label;
Packit Service fb6fa5
  GtkWidget *temp_widget;
Packit Service fb6fa5
Packit Service fb6fa5
  labels = gtk_widget_list_mnemonic_labels (widget);
Packit Service fb6fa5
  label = NULL;
Packit Service fb6fa5
  if (labels)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      if (labels->data)
Packit Service fb6fa5
        {
Packit Service fb6fa5
          if (labels->next)
Packit Service fb6fa5
            {
Packit Service fb6fa5
              g_warning ("Widget (%s) has more than one label", G_OBJECT_TYPE_NAME (widget));
Packit Service fb6fa5
              
Packit Service fb6fa5
            }
Packit Service fb6fa5
          else
Packit Service fb6fa5
            {
Packit Service fb6fa5
              label = labels->data;
Packit Service fb6fa5
            }
Packit Service fb6fa5
        }
Packit Service fb6fa5
      g_list_free (labels);
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  /*
Packit Service fb6fa5
   * Ignore a label within a button; bug #136602
Packit Service fb6fa5
   */
Packit Service fb6fa5
  if (label && GTK_IS_BUTTON (widget))
Packit Service fb6fa5
    {
Packit Service fb6fa5
      temp_widget = label;
Packit Service fb6fa5
      while (temp_widget)
Packit Service fb6fa5
        {
Packit Service fb6fa5
          if (temp_widget == widget)
Packit Service fb6fa5
            {
Packit Service fb6fa5
              label = NULL;
Packit Service fb6fa5
              break;
Packit Service fb6fa5
            }
Packit Service fb6fa5
          temp_widget = gtk_widget_get_parent (temp_widget);
Packit Service fb6fa5
        }
Packit Service fb6fa5
    } 
Packit Service fb6fa5
  return label;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static AtkRelationSet*
Packit Service fb6fa5
gail_widget_ref_relation_set (AtkObject *obj)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GtkWidget *widget;
Packit Service fb6fa5
  AtkRelationSet *relation_set;
Packit Service fb6fa5
  GtkWidget *label;
Packit Service fb6fa5
  AtkObject *array[1];
Packit Service fb6fa5
  AtkRelation* relation;
Packit Service fb6fa5
Packit Service fb6fa5
  gail_return_val_if_fail (GAIL_IS_WIDGET (obj), NULL);
Packit Service fb6fa5
Packit Service fb6fa5
  widget = GTK_ACCESSIBLE (obj)->widget;
Packit Service fb6fa5
  if (widget == NULL)
Packit Service fb6fa5
    /*
Packit Service fb6fa5
     * State is defunct
Packit Service fb6fa5
     */
Packit Service fb6fa5
    return NULL;
Packit Service fb6fa5
Packit Service fb6fa5
  relation_set = ATK_OBJECT_CLASS (gail_widget_parent_class)->ref_relation_set (obj);
Packit Service fb6fa5
Packit Service fb6fa5
  if (GTK_IS_BOX (widget) && !GTK_IS_COMBO (widget))
Packit Service fb6fa5
      /*
Packit Service fb6fa5
       * Do not report labelled-by for a GtkBox which could be a 
Packit Service fb6fa5
       * GnomeFileEntry.
Packit Service fb6fa5
       */
Packit Service fb6fa5
    return relation_set;
Packit Service fb6fa5
Packit Service fb6fa5
  if (!atk_relation_set_contains (relation_set, ATK_RELATION_LABELLED_BY))
Packit Service fb6fa5
    {
Packit Service fb6fa5
      label = find_label (widget);
Packit Service fb6fa5
      if (label == NULL)
Packit Service fb6fa5
        {
Packit Service fb6fa5
          if (GTK_IS_BUTTON (widget))
Packit Service fb6fa5
            /*
Packit Service fb6fa5
             * Handle the case where GnomeIconEntry is the mnemonic widget.
Packit Service fb6fa5
             * The GtkButton which is a grandchild of the GnomeIconEntry
Packit Service fb6fa5
             * should really be the mnemonic widget. See bug #133967.
Packit Service fb6fa5
             */
Packit Service fb6fa5
            {
Packit Service fb6fa5
              GtkWidget *temp_widget;
Packit Service fb6fa5
Packit Service fb6fa5
              temp_widget = gtk_widget_get_parent (widget);
Packit Service fb6fa5
Packit Service fb6fa5
              if (GTK_IS_ALIGNMENT (temp_widget))
Packit Service fb6fa5
                {
Packit Service fb6fa5
                  temp_widget = gtk_widget_get_parent (temp_widget);
Packit Service fb6fa5
                  if (GTK_IS_BOX (temp_widget))
Packit Service fb6fa5
                    {
Packit Service fb6fa5
                      label = find_label (temp_widget);
Packit Service fb6fa5
                 
Packit Service fb6fa5
                      if (!label)
Packit Service fb6fa5
                        label = find_label (gtk_widget_get_parent (temp_widget));
Packit Service fb6fa5
                    }
Packit Service fb6fa5
                }
Packit Service fb6fa5
            }
Packit Service fb6fa5
          else if (GTK_IS_COMBO (widget))
Packit Service fb6fa5
            /*
Packit Service fb6fa5
             * Handle the case when GnomeFileEntry is the mnemonic widget.
Packit Service fb6fa5
             * The GnomeEntry which is a grandchild of the GnomeFileEntry
Packit Service fb6fa5
             * should be the mnemonic widget. See bug #137584.
Packit Service fb6fa5
             */
Packit Service fb6fa5
            {
Packit Service fb6fa5
              GtkWidget *temp_widget;
Packit Service fb6fa5
Packit Service fb6fa5
              temp_widget = gtk_widget_get_parent (widget);
Packit Service fb6fa5
Packit Service fb6fa5
              if (GTK_IS_HBOX (temp_widget))
Packit Service fb6fa5
                {
Packit Service fb6fa5
                  temp_widget = gtk_widget_get_parent (temp_widget);
Packit Service fb6fa5
                  if (GTK_IS_BOX (temp_widget))
Packit Service fb6fa5
                    {
Packit Service fb6fa5
                      label = find_label (temp_widget);
Packit Service fb6fa5
                    }
Packit Service fb6fa5
                }
Packit Service fb6fa5
            }
Packit Service fb6fa5
          else if (GTK_IS_COMBO_BOX (widget))
Packit Service fb6fa5
            /*
Packit Service fb6fa5
             * Handle the case when GtkFileChooserButton is the mnemonic
Packit Service fb6fa5
             * widget.  The GtkComboBox which is a child of the
Packit Service fb6fa5
             * GtkFileChooserButton should be the mnemonic widget.
Packit Service fb6fa5
             * See bug #359843.
Packit Service fb6fa5
             */
Packit Service fb6fa5
            {
Packit Service fb6fa5
              GtkWidget *temp_widget;
Packit Service fb6fa5
Packit Service fb6fa5
              temp_widget = gtk_widget_get_parent (widget);
Packit Service fb6fa5
              if (GTK_IS_HBOX (temp_widget))
Packit Service fb6fa5
                {
Packit Service fb6fa5
                  label = find_label (temp_widget);
Packit Service fb6fa5
                }
Packit Service fb6fa5
            }
Packit Service fb6fa5
        }
Packit Service fb6fa5
Packit Service fb6fa5
      if (label)
Packit Service fb6fa5
        {
Packit Service fb6fa5
	  array [0] = gtk_widget_get_accessible (label);
Packit Service fb6fa5
Packit Service fb6fa5
	  relation = atk_relation_new (array, 1, ATK_RELATION_LABELLED_BY);
Packit Service fb6fa5
	  atk_relation_set_add (relation_set, relation);
Packit Service fb6fa5
	  g_object_unref (relation);
Packit Service fb6fa5
        }
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  return relation_set;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static AtkStateSet*
Packit Service fb6fa5
gail_widget_ref_state_set (AtkObject *accessible)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GtkWidget *widget = GTK_ACCESSIBLE (accessible)->widget;
Packit Service fb6fa5
  AtkStateSet *state_set;
Packit Service fb6fa5
Packit Service fb6fa5
  state_set = ATK_OBJECT_CLASS (gail_widget_parent_class)->ref_state_set (accessible);
Packit Service fb6fa5
Packit Service fb6fa5
  if (widget == NULL)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      atk_state_set_add_state (state_set, ATK_STATE_DEFUNCT);
Packit Service fb6fa5
    }
Packit Service fb6fa5
  else
Packit Service fb6fa5
    {
Packit Service fb6fa5
      if (gtk_widget_is_sensitive (widget))
Packit Service fb6fa5
        {
Packit Service fb6fa5
          atk_state_set_add_state (state_set, ATK_STATE_SENSITIVE);
Packit Service fb6fa5
          atk_state_set_add_state (state_set, ATK_STATE_ENABLED);
Packit Service fb6fa5
        }
Packit Service fb6fa5
  
Packit Service fb6fa5
      if (gtk_widget_get_can_focus (widget))
Packit Service fb6fa5
        {
Packit Service fb6fa5
          atk_state_set_add_state (state_set, ATK_STATE_FOCUSABLE);
Packit Service fb6fa5
        }
Packit Service fb6fa5
      /*
Packit Service fb6fa5
       * We do not currently generate notifications when an ATK object 
Packit Service fb6fa5
       * corresponding to a GtkWidget changes visibility by being scrolled 
Packit Service fb6fa5
       * on or off the screen.  The testcase for this is the main window 
Packit Service fb6fa5
       * of the testgtk application in which a set of buttons in a GtkVBox 
Packit Service fb6fa5
       * is in a scrooled window with a viewport.
Packit Service fb6fa5
       *
Packit Service fb6fa5
       * To generate the notifications we would need to do the following: 
Packit Service fb6fa5
       * 1) Find the GtkViewPort among the antecendents of the objects
Packit Service fb6fa5
       * 2) Create an accesible for the GtkViewPort
Packit Service fb6fa5
       * 3) Connect to the value-changed signal on the viewport
Packit Service fb6fa5
       * 4) When the signal is received we need to traverse the children 
Packit Service fb6fa5
       * of the viewport and check whether the children are visible or not 
Packit Service fb6fa5
       * visible; we may want to restrict this to the widgets for which 
Packit Service fb6fa5
       * accessible objects have been created.
Packit Service fb6fa5
       * 5) We probably need to store a variable on_screen in the 
Packit Service fb6fa5
       * GailWidget data structure so we can determine whether the value has 
Packit Service fb6fa5
       * changed.
Packit Service fb6fa5
       */
Packit Service fb6fa5
      if (gtk_widget_get_visible (widget))
Packit Service fb6fa5
        {
Packit Service fb6fa5
          atk_state_set_add_state (state_set, ATK_STATE_VISIBLE);
Packit Service fb6fa5
          if (gail_widget_on_screen (widget) && gtk_widget_get_mapped (widget) &&
Packit Service fb6fa5
              gail_widget_all_parents_visible (widget))
Packit Service fb6fa5
            {
Packit Service fb6fa5
              atk_state_set_add_state (state_set, ATK_STATE_SHOWING);
Packit Service fb6fa5
            }
Packit Service fb6fa5
        }
Packit Service fb6fa5
  
Packit Service fb6fa5
      if (gtk_widget_has_focus (widget) && (widget == focus_widget))
Packit Service fb6fa5
        {
Packit Service fb6fa5
          AtkObject *focus_obj;
Packit Service fb6fa5
Packit Service fb6fa5
          focus_obj = g_object_get_data (G_OBJECT (accessible), "gail-focus-object");
Packit Service fb6fa5
          if (focus_obj == NULL)
Packit Service fb6fa5
            atk_state_set_add_state (state_set, ATK_STATE_FOCUSED);
Packit Service fb6fa5
        }
Packit Service fb6fa5
      if (gtk_widget_has_default (widget))
Packit Service fb6fa5
        {
Packit Service fb6fa5
          atk_state_set_add_state (state_set, ATK_STATE_DEFAULT);
Packit Service fb6fa5
        }
Packit Service fb6fa5
    }
Packit Service fb6fa5
  return state_set;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static gint
Packit Service fb6fa5
gail_widget_get_index_in_parent (AtkObject *accessible)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GtkWidget *widget;
Packit Service fb6fa5
  GtkWidget *parent_widget;
Packit Service fb6fa5
  gint index;
Packit Service fb6fa5
  GList *children;
Packit Service fb6fa5
  GType type;
Packit Service fb6fa5
Packit Service fb6fa5
  type = g_type_from_name ("GailCanvasWidget");
Packit Service fb6fa5
  widget = GTK_ACCESSIBLE (accessible)->widget;
Packit Service fb6fa5
Packit Service fb6fa5
  if (widget == NULL)
Packit Service fb6fa5
    /*
Packit Service fb6fa5
     * State is defunct
Packit Service fb6fa5
     */
Packit Service fb6fa5
    return -1;
Packit Service fb6fa5
Packit Service fb6fa5
  if (accessible->accessible_parent)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      AtkObject *parent;
Packit Service fb6fa5
Packit Service fb6fa5
      parent = accessible->accessible_parent;
Packit Service fb6fa5
Packit Service fb6fa5
      if (GAIL_IS_NOTEBOOK_PAGE (parent) ||
Packit Service fb6fa5
          G_TYPE_CHECK_INSTANCE_TYPE ((parent), type))
Packit Service fb6fa5
        return 0;
Packit Service fb6fa5
      else
Packit Service fb6fa5
        {
Packit Service fb6fa5
          gint n_children, i;
Packit Service fb6fa5
          gboolean found = FALSE;
Packit Service fb6fa5
Packit Service fb6fa5
          n_children = atk_object_get_n_accessible_children (parent);
Packit Service fb6fa5
          for (i = 0; i < n_children; i++)
Packit Service fb6fa5
            {
Packit Service fb6fa5
              AtkObject *child;
Packit Service fb6fa5
Packit Service fb6fa5
              child = atk_object_ref_accessible_child (parent, i);
Packit Service fb6fa5
              if (child == accessible)
Packit Service fb6fa5
                found = TRUE;
Packit Service fb6fa5
Packit Service fb6fa5
              g_object_unref (child); 
Packit Service fb6fa5
              if (found)
Packit Service fb6fa5
                return i;
Packit Service fb6fa5
            }
Packit Service fb6fa5
        }
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  gail_return_val_if_fail (GTK_IS_WIDGET (widget), -1);
Packit Service fb6fa5
  parent_widget = widget->parent;
Packit Service fb6fa5
  if (parent_widget == NULL)
Packit Service fb6fa5
    return -1;
Packit Service fb6fa5
  gail_return_val_if_fail (GTK_IS_CONTAINER (parent_widget), -1);
Packit Service fb6fa5
Packit Service fb6fa5
  children = gtk_container_get_children (GTK_CONTAINER (parent_widget));
Packit Service fb6fa5
Packit Service fb6fa5
  index = g_list_index (children, widget);
Packit Service fb6fa5
  g_list_free (children);
Packit Service fb6fa5
  return index;  
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static void 
Packit Service fb6fa5
atk_component_interface_init (AtkComponentIface *iface)
Packit Service fb6fa5
{
Packit Service fb6fa5
  /*
Packit Service fb6fa5
   * Use default implementation for contains and get_position
Packit Service fb6fa5
   */
Packit Service fb6fa5
  iface->add_focus_handler = gail_widget_add_focus_handler;
Packit Service fb6fa5
  iface->get_extents = gail_widget_get_extents;
Packit Service fb6fa5
  iface->get_size = gail_widget_get_size;
Packit Service fb6fa5
  iface->get_layer = gail_widget_get_layer;
Packit Service fb6fa5
  iface->grab_focus = gail_widget_grab_focus;
Packit Service fb6fa5
  iface->remove_focus_handler = gail_widget_remove_focus_handler;
Packit Service fb6fa5
  iface->set_extents = gail_widget_set_extents;
Packit Service fb6fa5
  iface->set_position = gail_widget_set_position;
Packit Service fb6fa5
  iface->set_size = gail_widget_set_size;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static guint 
Packit Service fb6fa5
gail_widget_add_focus_handler (AtkComponent    *component,
Packit Service fb6fa5
                               AtkFocusHandler handler)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GSignalMatchType match_type;
Packit Service fb6fa5
  gulong ret;
Packit Service fb6fa5
  guint signal_id;
Packit Service fb6fa5
Packit Service fb6fa5
  match_type = G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC;
Packit Service fb6fa5
  signal_id = g_signal_lookup ("focus-event", ATK_TYPE_OBJECT);
Packit Service fb6fa5
Packit Service fb6fa5
  ret = g_signal_handler_find (component, match_type, signal_id, 0, NULL,
Packit Service fb6fa5
                               (gpointer) handler, NULL);
Packit Service fb6fa5
  if (!ret)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      return g_signal_connect_closure_by_id (component, 
Packit Service fb6fa5
                                             signal_id, 0,
Packit Service fb6fa5
                                             g_cclosure_new (
Packit Service fb6fa5
                                             G_CALLBACK (handler), NULL,
Packit Service fb6fa5
                                             (GClosureNotify) NULL),
Packit Service fb6fa5
                                             FALSE);
Packit Service fb6fa5
    }
Packit Service fb6fa5
  else
Packit Service fb6fa5
    {
Packit Service fb6fa5
      return 0;
Packit Service fb6fa5
    }
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static void 
Packit Service fb6fa5
gail_widget_get_extents (AtkComponent   *component,
Packit Service fb6fa5
                         gint           *x,
Packit Service fb6fa5
                         gint           *y,
Packit Service fb6fa5
                         gint           *width,
Packit Service fb6fa5
                         gint           *height,
Packit Service fb6fa5
                         AtkCoordType   coord_type)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GdkWindow *window;
Packit Service fb6fa5
  gint x_window, y_window;
Packit Service fb6fa5
  gint x_toplevel, y_toplevel;
Packit Service fb6fa5
  GtkWidget *widget = GTK_ACCESSIBLE (component)->widget;
Packit Service fb6fa5
Packit Service fb6fa5
  if (widget == NULL)
Packit Service fb6fa5
    /*
Packit Service fb6fa5
     * Object is defunct
Packit Service fb6fa5
     */
Packit Service fb6fa5
    return;
Packit Service fb6fa5
Packit Service fb6fa5
  gail_return_if_fail (GTK_IS_WIDGET (widget));
Packit Service fb6fa5
Packit Service fb6fa5
  *width = widget->allocation.width;
Packit Service fb6fa5
  *height = widget->allocation.height;
Packit Service fb6fa5
  if (!gail_widget_on_screen (widget) || (!gtk_widget_is_drawable (widget)))
Packit Service fb6fa5
    {
Packit Service fb6fa5
      *x = G_MININT;
Packit Service fb6fa5
      *y = G_MININT;
Packit Service fb6fa5
      return;
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  if (widget->parent)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      *x = widget->allocation.x;
Packit Service fb6fa5
      *y = widget->allocation.y;
Packit Service fb6fa5
      window = gtk_widget_get_parent_window (widget);
Packit Service fb6fa5
    }
Packit Service fb6fa5
  else
Packit Service fb6fa5
    {
Packit Service fb6fa5
      *x = 0;
Packit Service fb6fa5
      *y = 0;
Packit Service fb6fa5
      window = widget->window;
Packit Service fb6fa5
    }
Packit Service fb6fa5
  gdk_window_get_origin (window, &x_window, &y_window);
Packit Service fb6fa5
  *x += x_window;
Packit Service fb6fa5
  *y += y_window;
Packit Service fb6fa5
Packit Service fb6fa5
 
Packit Service fb6fa5
 if (coord_type == ATK_XY_WINDOW) 
Packit Service fb6fa5
    { 
Packit Service fb6fa5
      window = gdk_window_get_toplevel (widget->window);
Packit Service fb6fa5
      gdk_window_get_origin (window, &x_toplevel, &y_toplevel);
Packit Service fb6fa5
Packit Service fb6fa5
      *x -= x_toplevel;
Packit Service fb6fa5
      *y -= y_toplevel;
Packit Service fb6fa5
    }
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static void 
Packit Service fb6fa5
gail_widget_get_size (AtkComponent   *component,
Packit Service fb6fa5
                      gint           *width,
Packit Service fb6fa5
                      gint           *height)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GtkWidget *widget = GTK_ACCESSIBLE (component)->widget;
Packit Service fb6fa5
Packit Service fb6fa5
  if (widget == NULL)
Packit Service fb6fa5
    /*
Packit Service fb6fa5
     * Object is defunct
Packit Service fb6fa5
     */
Packit Service fb6fa5
    return;
Packit Service fb6fa5
Packit Service fb6fa5
  gail_return_if_fail (GTK_IS_WIDGET (widget));
Packit Service fb6fa5
Packit Service fb6fa5
  *width = widget->allocation.width;
Packit Service fb6fa5
  *height = widget->allocation.height;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static AtkLayer
Packit Service fb6fa5
gail_widget_get_layer (AtkComponent *component)
Packit Service fb6fa5
{
Packit Service fb6fa5
  gint layer;
Packit Service fb6fa5
  layer = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (component), "atk-component-layer"));
Packit Service fb6fa5
Packit Service fb6fa5
  return (AtkLayer) layer;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static gboolean 
Packit Service fb6fa5
gail_widget_grab_focus (AtkComponent   *component)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GtkWidget *widget = GTK_ACCESSIBLE (component)->widget;
Packit Service fb6fa5
  GtkWidget *toplevel;
Packit Service fb6fa5
Packit Service fb6fa5
  gail_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
Packit Service fb6fa5
  if (gtk_widget_get_can_focus (widget))
Packit Service fb6fa5
    {
Packit Service fb6fa5
      gtk_widget_grab_focus (widget);
Packit Service fb6fa5
      toplevel = gtk_widget_get_toplevel (widget);
Packit Service fb6fa5
      if (gtk_widget_is_toplevel (toplevel))
Packit Service fb6fa5
	{
Packit Service fb6fa5
#ifdef GDK_WINDOWING_X11
Packit Service fb6fa5
	  gtk_window_present_with_time (GTK_WINDOW (toplevel), gdk_x11_get_server_time (widget->window));
Packit Service fb6fa5
#else
Packit Service fb6fa5
	  gtk_window_present (GTK_WINDOW (toplevel));
Packit Service fb6fa5
#endif
Packit Service fb6fa5
	}
Packit Service fb6fa5
      return TRUE;
Packit Service fb6fa5
    }
Packit Service fb6fa5
  else
Packit Service fb6fa5
    return FALSE;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static void 
Packit Service fb6fa5
gail_widget_remove_focus_handler (AtkComponent   *component,
Packit Service fb6fa5
                                  guint          handler_id)
Packit Service fb6fa5
{
Packit Service fb6fa5
  g_signal_handler_disconnect (component, handler_id);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static gboolean 
Packit Service fb6fa5
gail_widget_set_extents (AtkComponent   *component,
Packit Service fb6fa5
                         gint           x,
Packit Service fb6fa5
                         gint           y,
Packit Service fb6fa5
                         gint           width,
Packit Service fb6fa5
                         gint           height,
Packit Service fb6fa5
                         AtkCoordType   coord_type)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GtkWidget *widget = GTK_ACCESSIBLE (component)->widget;
Packit Service fb6fa5
Packit Service fb6fa5
  if (widget == NULL)
Packit Service fb6fa5
    /*
Packit Service fb6fa5
     * Object is defunct
Packit Service fb6fa5
     */
Packit Service fb6fa5
    return FALSE;
Packit Service fb6fa5
  gail_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
Packit Service fb6fa5
Packit Service fb6fa5
  if (gtk_widget_is_toplevel (widget))
Packit Service fb6fa5
    {
Packit Service fb6fa5
      if (coord_type == ATK_XY_WINDOW)
Packit Service fb6fa5
        {
Packit Service fb6fa5
          gint x_current, y_current;
Packit Service fb6fa5
          GdkWindow *window = widget->window;
Packit Service fb6fa5
Packit Service fb6fa5
          gdk_window_get_origin (window, &x_current, &y_current);
Packit Service fb6fa5
          x_current += x;
Packit Service fb6fa5
          y_current += y;
Packit Service fb6fa5
          if (x_current < 0 || y_current < 0)
Packit Service fb6fa5
            return FALSE;
Packit Service fb6fa5
          else
Packit Service fb6fa5
            {
Packit Service fb6fa5
              gtk_widget_set_uposition (widget, x_current, y_current);
Packit Service fb6fa5
              gtk_widget_set_size_request (widget, width, height);
Packit Service fb6fa5
              return TRUE;
Packit Service fb6fa5
            }
Packit Service fb6fa5
        }
Packit Service fb6fa5
      else if (coord_type == ATK_XY_SCREEN)
Packit Service fb6fa5
        {  
Packit Service fb6fa5
          gtk_widget_set_uposition (widget, x, y);
Packit Service fb6fa5
          gtk_widget_set_size_request (widget, width, height);
Packit Service fb6fa5
          return TRUE;
Packit Service fb6fa5
        }
Packit Service fb6fa5
    }
Packit Service fb6fa5
  return FALSE;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static gboolean
Packit Service fb6fa5
gail_widget_set_position (AtkComponent   *component,
Packit Service fb6fa5
                          gint           x,
Packit Service fb6fa5
                          gint           y,
Packit Service fb6fa5
                          AtkCoordType   coord_type)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GtkWidget *widget = GTK_ACCESSIBLE (component)->widget;
Packit Service fb6fa5
Packit Service fb6fa5
  if (widget == NULL)
Packit Service fb6fa5
    /*
Packit Service fb6fa5
     * Object is defunct
Packit Service fb6fa5
     */
Packit Service fb6fa5
    return FALSE;
Packit Service fb6fa5
  gail_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
Packit Service fb6fa5
Packit Service fb6fa5
  if (gtk_widget_is_toplevel (widget))
Packit Service fb6fa5
    {
Packit Service fb6fa5
      if (coord_type == ATK_XY_WINDOW)
Packit Service fb6fa5
        {
Packit Service fb6fa5
          gint x_current, y_current;
Packit Service fb6fa5
          GdkWindow *window = widget->window;
Packit Service fb6fa5
Packit Service fb6fa5
          gdk_window_get_origin (window, &x_current, &y_current);
Packit Service fb6fa5
          x_current += x;
Packit Service fb6fa5
          y_current += y;
Packit Service fb6fa5
          if (x_current < 0 || y_current < 0)
Packit Service fb6fa5
            return FALSE;
Packit Service fb6fa5
          else
Packit Service fb6fa5
            {
Packit Service fb6fa5
              gtk_widget_set_uposition (widget, x_current, y_current);
Packit Service fb6fa5
              return TRUE;
Packit Service fb6fa5
            }
Packit Service fb6fa5
        }
Packit Service fb6fa5
      else if (coord_type == ATK_XY_SCREEN)
Packit Service fb6fa5
        {  
Packit Service fb6fa5
          gtk_widget_set_uposition (widget, x, y);
Packit Service fb6fa5
          return TRUE;
Packit Service fb6fa5
        }
Packit Service fb6fa5
    }
Packit Service fb6fa5
  return FALSE;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static gboolean 
Packit Service fb6fa5
gail_widget_set_size (AtkComponent   *component,
Packit Service fb6fa5
                      gint           width,
Packit Service fb6fa5
                      gint           height)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GtkWidget *widget = GTK_ACCESSIBLE (component)->widget;
Packit Service fb6fa5
Packit Service fb6fa5
  if (widget == NULL)
Packit Service fb6fa5
    /*
Packit Service fb6fa5
     * Object is defunct
Packit Service fb6fa5
     */
Packit Service fb6fa5
    return FALSE;
Packit Service fb6fa5
  gail_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
Packit Service fb6fa5
Packit Service fb6fa5
  if (gtk_widget_is_toplevel (widget))
Packit Service fb6fa5
    {
Packit Service fb6fa5
      gtk_widget_set_size_request (widget, width, height);
Packit Service fb6fa5
      return TRUE;
Packit Service fb6fa5
    }
Packit Service fb6fa5
  else
Packit Service fb6fa5
   return FALSE;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/*
Packit Service fb6fa5
 * This function is a signal handler for notify_in_event and focus_out_event
Packit Service fb6fa5
 * signal which gets emitted on a GtkWidget.
Packit Service fb6fa5
 */
Packit Service fb6fa5
static gboolean
Packit Service fb6fa5
gail_widget_focus_gtk (GtkWidget     *widget,
Packit Service fb6fa5
                       GdkEventFocus *event)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GailWidget *gail_widget;
Packit Service fb6fa5
  GailWidgetClass *klass;
Packit Service fb6fa5
Packit Service fb6fa5
  gail_widget = GAIL_WIDGET (gtk_widget_get_accessible (widget));
Packit Service fb6fa5
  klass = GAIL_WIDGET_GET_CLASS (gail_widget);
Packit Service fb6fa5
  if (klass->focus_gtk)
Packit Service fb6fa5
    return klass->focus_gtk (widget, event);
Packit Service fb6fa5
  else
Packit Service fb6fa5
    return FALSE;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/*
Packit Service fb6fa5
 * This function is the signal handler defined for focus_in_event and
Packit Service fb6fa5
 * focus_out_event got GailWidget.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * It emits a focus-event signal on the GailWidget.
Packit Service fb6fa5
 */
Packit Service fb6fa5
static gboolean
Packit Service fb6fa5
gail_widget_real_focus_gtk (GtkWidget     *widget,
Packit Service fb6fa5
                            GdkEventFocus *event)
Packit Service fb6fa5
{
Packit Service fb6fa5
  AtkObject* accessible;
Packit Service fb6fa5
  gboolean return_val;
Packit Service fb6fa5
  return_val = FALSE;
Packit Service fb6fa5
Packit Service fb6fa5
  accessible = gtk_widget_get_accessible (widget);
Packit Service fb6fa5
  g_signal_emit_by_name (accessible, "focus_event", event->in, &return_val);
Packit Service fb6fa5
  return FALSE;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static void
Packit Service fb6fa5
gail_widget_size_allocate_gtk (GtkWidget     *widget,
Packit Service fb6fa5
                               GtkAllocation *allocation)
Packit Service fb6fa5
{
Packit Service fb6fa5
  AtkObject* accessible;
Packit Service fb6fa5
  AtkRectangle rect;
Packit Service fb6fa5
Packit Service fb6fa5
  accessible = gtk_widget_get_accessible (widget);
Packit Service fb6fa5
  if (ATK_IS_COMPONENT (accessible))
Packit Service fb6fa5
    {
Packit Service fb6fa5
      rect.x = allocation->x;
Packit Service fb6fa5
      rect.y = allocation->y;
Packit Service fb6fa5
      rect.width = allocation->width;
Packit Service fb6fa5
      rect.height = allocation->height;
Packit Service fb6fa5
      g_signal_emit_by_name (accessible, "bounds_changed", &rect);
Packit Service fb6fa5
    }
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/*
Packit Service fb6fa5
 * This function is the signal handler defined for map and unmap signals.
Packit Service fb6fa5
 */
Packit Service fb6fa5
static gint
Packit Service fb6fa5
gail_widget_map_gtk (GtkWidget     *widget)
Packit Service fb6fa5
{
Packit Service fb6fa5
  AtkObject* accessible;
Packit Service fb6fa5
Packit Service fb6fa5
  accessible = gtk_widget_get_accessible (widget);
Packit Service fb6fa5
  atk_object_notify_state_change (accessible, ATK_STATE_SHOWING,
Packit Service fb6fa5
                                  gtk_widget_get_mapped (widget));
Packit Service fb6fa5
  return 1;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/*
Packit Service fb6fa5
 * This function is a signal handler for notify signal which gets emitted 
Packit Service fb6fa5
 * when a property changes value on the GtkWidget associated with the object.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * It calls a function for the GailWidget type
Packit Service fb6fa5
 */
Packit Service fb6fa5
static void 
Packit Service fb6fa5
gail_widget_notify_gtk (GObject     *obj,
Packit Service fb6fa5
                        GParamSpec  *pspec)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GailWidget *widget;
Packit Service fb6fa5
  GailWidgetClass *klass;
Packit Service fb6fa5
Packit Service fb6fa5
  widget = GAIL_WIDGET (gtk_widget_get_accessible (GTK_WIDGET (obj)));
Packit Service fb6fa5
  klass = GAIL_WIDGET_GET_CLASS (widget);
Packit Service fb6fa5
  if (klass->notify_gtk)
Packit Service fb6fa5
    klass->notify_gtk (obj, pspec);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/*
Packit Service fb6fa5
 * This function is a signal handler for notify signal which gets emitted 
Packit Service fb6fa5
 * when a property changes value on the GtkWidget associated with a GailWidget.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * It constructs an AtkPropertyValues structure and emits a "property_changed"
Packit Service fb6fa5
 * signal which causes the user specified AtkPropertyChangeHandler
Packit Service fb6fa5
 * to be called.
Packit Service fb6fa5
 */
Packit Service fb6fa5
static void 
Packit Service fb6fa5
gail_widget_real_notify_gtk (GObject     *obj,
Packit Service fb6fa5
                             GParamSpec  *pspec)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GtkWidget* widget = GTK_WIDGET (obj);
Packit Service fb6fa5
  AtkObject* atk_obj = gtk_widget_get_accessible (widget);
Packit Service fb6fa5
  AtkState state;
Packit Service fb6fa5
  gboolean value;
Packit Service fb6fa5
Packit Service fb6fa5
  if (strcmp (pspec->name, "has-focus") == 0)
Packit Service fb6fa5
    /*
Packit Service fb6fa5
     * We use focus-in-event and focus-out-event signals to catch
Packit Service fb6fa5
     * focus changes so we ignore this.
Packit Service fb6fa5
     */
Packit Service fb6fa5
    return;
Packit Service fb6fa5
  else if (atk_obj->description == NULL &&
Packit Service fb6fa5
           strcmp (pspec->name, "tooltip-text") == 0)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      g_object_notify (G_OBJECT (atk_obj), "accessible-description");
Packit Service fb6fa5
      return;
Packit Service fb6fa5
    }
Packit Service fb6fa5
  else if (strcmp (pspec->name, "visible") == 0)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      state = ATK_STATE_VISIBLE;
Packit Service fb6fa5
      value = gtk_widget_get_visible (widget);
Packit Service fb6fa5
    }
Packit Service fb6fa5
  else if (strcmp (pspec->name, "sensitive") == 0)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      state = ATK_STATE_SENSITIVE;
Packit Service fb6fa5
      value = gtk_widget_get_sensitive (widget);
Packit Service fb6fa5
    }
Packit Service fb6fa5
  else
Packit Service fb6fa5
    return;
Packit Service fb6fa5
Packit Service fb6fa5
  atk_object_notify_state_change (atk_obj, state, value);
Packit Service fb6fa5
  if (state == ATK_STATE_SENSITIVE)
Packit Service fb6fa5
    atk_object_notify_state_change (atk_obj, ATK_STATE_ENABLED, value);
Packit Service fb6fa5
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static void 
Packit Service fb6fa5
gail_widget_focus_event (AtkObject   *obj,
Packit Service fb6fa5
                         gboolean    focus_in)
Packit Service fb6fa5
{
Packit Service fb6fa5
  AtkObject *focus_obj;
Packit Service fb6fa5
Packit Service fb6fa5
  focus_obj = g_object_get_data (G_OBJECT (obj), "gail-focus-object");
Packit Service fb6fa5
  if (focus_obj == NULL)
Packit Service fb6fa5
    focus_obj = obj;
Packit Service fb6fa5
  atk_object_notify_state_change (focus_obj, ATK_STATE_FOCUSED, focus_in);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static GtkWidget*
Packit Service fb6fa5
gail_widget_find_viewport (GtkWidget *widget)
Packit Service fb6fa5
{
Packit Service fb6fa5
  /*
Packit Service fb6fa5
   * Find an antecedent which is a GtkViewPort
Packit Service fb6fa5
   */
Packit Service fb6fa5
  GtkWidget *parent;
Packit Service fb6fa5
Packit Service fb6fa5
  parent = widget->parent;
Packit Service fb6fa5
  while (parent != NULL)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      if (GTK_IS_VIEWPORT (parent))
Packit Service fb6fa5
        break;
Packit Service fb6fa5
      parent = parent->parent;
Packit Service fb6fa5
    }
Packit Service fb6fa5
  return parent;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/*
Packit Service fb6fa5
 * This function checks whether the widget has an antecedent which is 
Packit Service fb6fa5
 * a GtkViewport and, if so, whether any part of the widget intersects
Packit Service fb6fa5
 * the visible rectangle of the GtkViewport.
Packit Service fb6fa5
 */ 
Packit Service fb6fa5
static gboolean gail_widget_on_screen (GtkWidget *widget)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GtkWidget *viewport;
Packit Service fb6fa5
  gboolean return_value;
Packit Service fb6fa5
Packit Service fb6fa5
  viewport = gail_widget_find_viewport (widget);
Packit Service fb6fa5
  if (viewport)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      GtkAdjustment *adjustment;
Packit Service fb6fa5
      GdkRectangle visible_rect;
Packit Service fb6fa5
Packit Service fb6fa5
      adjustment = gtk_viewport_get_vadjustment (GTK_VIEWPORT (viewport));
Packit Service fb6fa5
      visible_rect.y = adjustment->value;
Packit Service fb6fa5
      adjustment = gtk_viewport_get_hadjustment (GTK_VIEWPORT (viewport));
Packit Service fb6fa5
      visible_rect.x = adjustment->value;
Packit Service fb6fa5
      visible_rect.width = viewport->allocation.width;
Packit Service fb6fa5
      visible_rect.height = viewport->allocation.height;
Packit Service fb6fa5
             
Packit Service fb6fa5
      if (((widget->allocation.x + widget->allocation.width) < visible_rect.x) ||
Packit Service fb6fa5
         ((widget->allocation.y + widget->allocation.height) < visible_rect.y) ||
Packit Service fb6fa5
         (widget->allocation.x > (visible_rect.x + visible_rect.width)) ||
Packit Service fb6fa5
         (widget->allocation.y > (visible_rect.y + visible_rect.height)))
Packit Service fb6fa5
        return_value = FALSE;
Packit Service fb6fa5
      else
Packit Service fb6fa5
        return_value = TRUE;
Packit Service fb6fa5
    }
Packit Service fb6fa5
  else
Packit Service fb6fa5
    {
Packit Service fb6fa5
      /*
Packit Service fb6fa5
       * Check whether the widget has been placed of the screen. The
Packit Service fb6fa5
       * widget may be MAPPED as when toolbar items do not fit on the toolbar.
Packit Service fb6fa5
       */
Packit Service fb6fa5
      if (widget->allocation.x + widget->allocation.width <= 0 &&
Packit Service fb6fa5
          widget->allocation.y + widget->allocation.height <= 0)
Packit Service fb6fa5
        return_value = FALSE;
Packit Service fb6fa5
      else 
Packit Service fb6fa5
        return_value = TRUE;
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  return return_value;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gail_widget_all_parents_visible:
Packit Service fb6fa5
 * @widget: a #GtkWidget
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Checks if all the predecesors (the parent widget, his parent, etc) are visible
Packit Service fb6fa5
 * Used to check properly the SHOWING state.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Return value: TRUE if all the parent hierarchy is visible, FALSE otherwise
Packit Service fb6fa5
 **/
Packit Service fb6fa5
static gboolean gail_widget_all_parents_visible (GtkWidget *widget)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GtkWidget *iter_parent = NULL;
Packit Service fb6fa5
  gboolean result = TRUE;
Packit Service fb6fa5
Packit Service fb6fa5
  for (iter_parent = gtk_widget_get_parent (widget); iter_parent;
Packit Service fb6fa5
       iter_parent = gtk_widget_get_parent (iter_parent))
Packit Service fb6fa5
    {
Packit Service fb6fa5
      if (!gtk_widget_get_visible (iter_parent))
Packit Service fb6fa5
        {
Packit Service fb6fa5
          result = FALSE;
Packit Service fb6fa5
          break;
Packit Service fb6fa5
        }
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  return result;
Packit Service fb6fa5
}