summaryrefslogtreecommitdiff
path: root/gtk/a11y/gtkwindowaccessible.c
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2011-07-01 22:10:27 -0400
committerMatthias Clasen <mclasen@redhat.com>2011-07-05 16:08:57 -0400
commited08baccd9f14e5056dfbcfe648d0071c4c6a9d5 (patch)
tree6b1a8b7aed2e93dc169f9f40c571b4159dd0578c /gtk/a11y/gtkwindowaccessible.c
parent8432ea3574bc71a8a32d8613b84b54bbd84d0057 (diff)
downloadgtk+-ed08baccd9f14e5056dfbcfe648d0071c4c6a9d5.tar.gz
Convert GailWindow to GtkWindowAccessible
While doing this, drop the get_mdi_zorder implementation that really should come from the window manager side. Dropping this saves some 500 lines.
Diffstat (limited to 'gtk/a11y/gtkwindowaccessible.c')
-rw-r--r--gtk/a11y/gtkwindowaccessible.c493
1 files changed, 493 insertions, 0 deletions
diff --git a/gtk/a11y/gtkwindowaccessible.c b/gtk/a11y/gtkwindowaccessible.c
new file mode 100644
index 0000000000..f07d35f550
--- /dev/null
+++ b/gtk/a11y/gtkwindowaccessible.c
@@ -0,0 +1,493 @@
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001, 2002, 2003 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <string.h>
+
+#include <gtk/gtkx.h>
+
+#include "gtkwindowaccessible.h"
+#include "gailtoplevel.h"
+
+enum {
+ ACTIVATE,
+ CREATE,
+ DEACTIVATE,
+ DESTROY,
+ MAXIMIZE,
+ MINIMIZE,
+ MOVE,
+ RESIZE,
+ RESTORE,
+ LAST_SIGNAL
+};
+
+
+/* atkcomponent.h */
+
+static void gtk_window_accessible_get_extents (AtkComponent *component,
+ gint *x,
+ gint *y,
+ gint *width,
+ gint *height,
+ AtkCoordType coord_type);
+static void gtk_window_accessible_get_size (AtkComponent *component,
+ gint *width,
+ gint *height);
+
+static guint gtk_window_accessible_signals [LAST_SIGNAL] = { 0, };
+
+static void atk_component_interface_init (AtkComponentIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GtkWindowAccessible, gtk_window_accessible, GAIL_TYPE_CONTAINER,
+ G_IMPLEMENT_INTERFACE (ATK_TYPE_COMPONENT, atk_component_interface_init))
+
+
+static gboolean
+gtk_window_accessible_focus_gtk (GtkWidget *widget,
+ GdkEventFocus *event)
+{
+ AtkObject* obj;
+
+ obj = gtk_widget_get_accessible (widget);
+ atk_object_notify_state_change (obj, ATK_STATE_ACTIVE, event->in);
+
+ return FALSE;
+}
+
+static void
+gtk_window_accessible_notify_gtk (GObject *obj,
+ GParamSpec *pspec)
+{
+ GtkWidget *widget = GTK_WIDGET (obj);
+ AtkObject* atk_obj = gtk_widget_get_accessible (widget);
+
+ if (strcmp (pspec->name, "title") == 0)
+ {
+ g_object_notify (G_OBJECT (atk_obj), "accessible-name");
+ g_signal_emit_by_name (atk_obj, "visible_data_changed");
+ }
+ else
+ GAIL_WIDGET_CLASS (gtk_window_accessible_parent_class)->notify_gtk (obj, pspec);
+}
+
+static gboolean
+window_state_event_cb (GtkWidget *widget,
+ GdkEventWindowState *event)
+{
+ AtkObject* obj;
+
+ obj = gtk_widget_get_accessible (widget);
+ atk_object_notify_state_change (obj, ATK_STATE_ICONIFIED,
+ (event->new_window_state & GDK_WINDOW_STATE_ICONIFIED) != 0);
+
+ return FALSE;
+}
+
+static void
+gtk_window_accessible_initialize (AtkObject *obj,
+ gpointer data)
+{
+ GtkWidget *widget = GTK_WIDGET (data);
+
+ /* A GtkWindowAccessible can be created for a GtkHandleBox or a GtkWindow */
+ if (!GTK_IS_WINDOW (widget) && !GTK_IS_HANDLE_BOX (widget))
+ return;
+
+ ATK_OBJECT_CLASS (gtk_window_accessible_parent_class)->initialize (obj, data);
+
+ g_signal_connect (data, "window_state_event", G_CALLBACK (window_state_event_cb), NULL);
+ g_object_set_data (G_OBJECT (obj), "atk-component-layer", GINT_TO_POINTER (ATK_LAYER_WINDOW));
+
+ if (GTK_IS_FILE_CHOOSER_DIALOG (widget))
+ obj->role = ATK_ROLE_FILE_CHOOSER;
+ else if (GTK_IS_COLOR_SELECTION_DIALOG (widget))
+ obj->role = ATK_ROLE_COLOR_CHOOSER;
+ else if (GTK_IS_FONT_SELECTION_DIALOG (widget))
+ obj->role = ATK_ROLE_FONT_CHOOSER;
+ else if (GTK_IS_MESSAGE_DIALOG (widget))
+ obj->role = ATK_ROLE_ALERT;
+ else if (GTK_IS_DIALOG (widget))
+ obj->role = ATK_ROLE_DIALOG;
+ else
+ {
+ const gchar *name;
+
+ name = gtk_widget_get_name (widget);
+
+ if (!g_strcmp0 (name, "gtk-tooltip"))
+ obj->role = ATK_ROLE_TOOL_TIP;
+#ifdef GDK_WINDOWING_X11
+ else if (GTK_IS_PLUG (widget))
+ obj->role = ATK_ROLE_PANEL;
+#endif
+ else if (gtk_window_get_window_type (GTK_WINDOW (widget)) == GTK_WINDOW_POPUP)
+ obj->role = ATK_ROLE_WINDOW;
+ else
+ obj->role = ATK_ROLE_FRAME;
+ }
+
+ /* Notify that tooltip is showing */
+ if (obj->role == ATK_ROLE_TOOL_TIP && gtk_widget_get_mapped (widget))
+ atk_object_notify_state_change (obj, ATK_STATE_SHOWING, 1);
+}
+
+static GtkWidget *
+find_label_child (GtkContainer *container)
+{
+ GList *children, *tmp_list;
+ GtkWidget *child;
+
+ children = gtk_container_get_children (container);
+
+ child = NULL;
+ for (tmp_list = children; tmp_list != NULL; tmp_list = tmp_list->next)
+ {
+ if (GTK_IS_LABEL (tmp_list->data))
+ {
+ child = GTK_WIDGET (tmp_list->data);
+ break;
+ }
+ else if (GTK_IS_CONTAINER (tmp_list->data))
+ {
+ child = find_label_child (GTK_CONTAINER (tmp_list->data));
+ if (child)
+ break;
+ }
+ }
+ g_list_free (children);
+ return child;
+}
+
+static const gchar *
+gtk_window_accessible_get_name (AtkObject *accessible)
+{
+ const gchar* name;
+ GtkWidget* widget;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
+ if (widget == NULL)
+ return NULL;
+
+ name = ATK_OBJECT_CLASS (gtk_window_accessible_parent_class)->get_name (accessible);
+ if (name != NULL)
+ return name;
+
+ if (GTK_IS_WINDOW (widget))
+ {
+ GtkWindow *window = GTK_WINDOW (widget);
+
+ name = gtk_window_get_title (window);
+ if (name == NULL && accessible->role == ATK_ROLE_TOOL_TIP)
+ {
+ GtkWidget *child;
+
+ child = find_label_child (GTK_CONTAINER (window));
+ if (GTK_IS_LABEL (child))
+ name = gtk_label_get_text (GTK_LABEL (child));
+ }
+ }
+ return name;
+}
+
+static gint
+gtk_window_accessible_get_index_in_parent (AtkObject *accessible)
+{
+ GtkWidget* widget;
+ AtkObject* atk_obj;
+ gint index = -1;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
+ if (widget == NULL)
+ return -1;
+
+ index = ATK_OBJECT_CLASS (gtk_window_accessible_parent_class)->get_index_in_parent (accessible);
+ if (index != -1)
+ return index;
+
+ atk_obj = atk_get_root ();
+
+ if (GTK_IS_WINDOW (widget))
+ {
+ GtkWindow *window = GTK_WINDOW (widget);
+ if (GAIL_IS_TOPLEVEL (atk_obj))
+ {
+ GailToplevel* toplevel = GAIL_TOPLEVEL (atk_obj);
+ index = g_list_index (toplevel->window_list, window);
+ }
+ else
+ {
+ gint i, sibling_count;
+
+ sibling_count = atk_object_get_n_accessible_children (atk_obj);
+ for (i = 0; i < sibling_count && index == -1; ++i)
+ {
+ AtkObject *child = atk_object_ref_accessible_child (atk_obj, i);
+ if (accessible == child)
+ index = i;
+ g_object_unref (G_OBJECT (child));
+ }
+ }
+ }
+ return index;
+}
+
+static AtkRelationSet *
+gtk_window_accessible_ref_relation_set (AtkObject *obj)
+{
+ GtkWidget *widget;
+ AtkRelationSet *relation_set;
+ AtkObject *array[1];
+ AtkRelation* relation;
+ GtkWidget *current_widget;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
+ if (widget == NULL)
+ return NULL;
+
+ relation_set = ATK_OBJECT_CLASS (gtk_window_accessible_parent_class)->ref_relation_set (obj);
+
+ if (atk_object_get_role (obj) == ATK_ROLE_TOOL_TIP)
+ {
+ relation = atk_relation_set_get_relation_by_type (relation_set, ATK_RELATION_POPUP_FOR);
+ if (relation)
+ atk_relation_set_remove (relation_set, relation);
+
+ if (0) /* FIXME need a way to go from tooltip window to widget */
+ {
+ array[0] = gtk_widget_get_accessible (current_widget);
+ relation = atk_relation_new (array, 1, ATK_RELATION_POPUP_FOR);
+ atk_relation_set_add (relation_set, relation);
+ g_object_unref (relation);
+ }
+ }
+ return relation_set;
+}
+
+static AtkStateSet *
+gtk_window_accessible_ref_state_set (AtkObject *accessible)
+{
+ AtkStateSet *state_set;
+ GtkWidget *widget;
+ GtkWindow *window;
+ GdkWindow *gdk_window;
+ GdkWindowState state;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
+ if (widget == NULL)
+ return NULL;
+
+ state_set = ATK_OBJECT_CLASS (gtk_window_accessible_parent_class)->ref_state_set (accessible);
+
+ window = GTK_WINDOW (widget);
+
+ if (gtk_window_has_toplevel_focus (window) && gtk_window_is_active (window))
+ atk_state_set_add_state (state_set, ATK_STATE_ACTIVE);
+
+ gdk_window = gtk_widget_get_window (widget);
+ if (window)
+ {
+ state = gdk_window_get_state (gdk_window);
+ if (state & GDK_WINDOW_STATE_ICONIFIED)
+ atk_state_set_add_state (state_set, ATK_STATE_ICONIFIED);
+ }
+ if (gtk_window_get_modal (window))
+ atk_state_set_add_state (state_set, ATK_STATE_MODAL);
+
+ if (gtk_window_get_resizable (window))
+ atk_state_set_add_state (state_set, ATK_STATE_RESIZABLE);
+
+ return state_set;
+}
+
+static void
+gtk_window_accessible_class_init (GtkWindowAccessibleClass *klass)
+{
+ GailWidgetClass *widget_class = (GailWidgetClass*)klass;
+ AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
+
+ widget_class->focus_gtk = gtk_window_accessible_focus_gtk;
+ widget_class->notify_gtk = gtk_window_accessible_notify_gtk;
+
+ class->get_name = gtk_window_accessible_get_name;
+ class->get_index_in_parent = gtk_window_accessible_get_index_in_parent;
+ class->ref_relation_set = gtk_window_accessible_ref_relation_set;
+ class->ref_state_set = gtk_window_accessible_ref_state_set;
+ class->initialize = gtk_window_accessible_initialize;
+
+ gtk_window_accessible_signals [ACTIVATE] =
+ g_signal_new ("activate",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+ gtk_window_accessible_signals [CREATE] =
+ g_signal_new ("create",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+ gtk_window_accessible_signals [DEACTIVATE] =
+ g_signal_new ("deactivate",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+ gtk_window_accessible_signals [DESTROY] =
+ g_signal_new ("destroy",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+ gtk_window_accessible_signals [MAXIMIZE] =
+ g_signal_new ("maximize",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+ gtk_window_accessible_signals [MINIMIZE] =
+ g_signal_new ("minimize",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+ gtk_window_accessible_signals [MOVE] =
+ g_signal_new ("move",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+ gtk_window_accessible_signals [RESIZE] =
+ g_signal_new ("resize",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+ gtk_window_accessible_signals [RESTORE] =
+ g_signal_new ("restore",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+}
+
+static void
+gtk_window_accessible_init (GtkWindowAccessible *accessible)
+{
+}
+
+static void
+gtk_window_accessible_get_extents (AtkComponent *component,
+ gint *x,
+ gint *y,
+ gint *width,
+ gint *height,
+ AtkCoordType coord_type)
+{
+ GtkWidget *widget;
+ GdkRectangle rect;
+ gint x_toplevel, y_toplevel;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (component));
+ if (widget == NULL)
+ return;
+
+ if (!gtk_widget_is_toplevel (widget))
+ {
+ AtkComponentIface *parent_iface;
+
+ parent_iface = (AtkComponentIface *) g_type_interface_peek_parent (ATK_COMPONENT_GET_IFACE (component));
+ parent_iface->get_extents (component, x, y, width, height, coord_type);
+ return;
+ }
+
+ gdk_window_get_frame_extents (gtk_widget_get_window (widget), &rect);
+
+ *width = rect.width;
+ *height = rect.height;
+ if (!gtk_widget_is_drawable (widget))
+ {
+ *x = G_MININT;
+ *y = G_MININT;
+ return;
+ }
+
+ *x = rect.x;
+ *y = rect.y;
+ if (coord_type == ATK_XY_WINDOW)
+ {
+ gdk_window_get_origin (gtk_widget_get_window (widget),
+ &x_toplevel, &y_toplevel);
+ *x -= x_toplevel;
+ *y -= y_toplevel;
+ }
+}
+
+static void
+gtk_window_accessible_get_size (AtkComponent *component,
+ gint *width,
+ gint *height)
+{
+ GtkWidget *widget;
+ GdkRectangle rect;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (component));
+ if (widget == NULL)
+ return;
+
+ if (!gtk_widget_is_toplevel (widget))
+ {
+ AtkComponentIface *parent_iface;
+
+ parent_iface = (AtkComponentIface *) g_type_interface_peek_parent (ATK_COMPONENT_GET_IFACE (component));
+ parent_iface->get_size (component, width, height);
+ return;
+ }
+
+ gdk_window_get_frame_extents (gtk_widget_get_window (widget), &rect);
+
+ *width = rect.width;
+ *height = rect.height;
+}
+
+static void
+atk_component_interface_init (AtkComponentIface *iface)
+{
+ iface->get_extents = gtk_window_accessible_get_extents;
+ iface->get_size = gtk_window_accessible_get_size;
+}