1/* 2 * Copyright (C) 2012 Igalia S.L. 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Library General Public 6 * License as published by the Free Software Foundation; either 7 * version 2 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Library General Public License for more details. 13 * 14 * You should have received a copy of the GNU Library General Public License 15 * along with this library; see the file COPYING.LIB. If not, write to 16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 * Boston, MA 02110-1301, USA. 18 */ 19 20#include "config.h" 21#include "WebKitWebViewBaseAccessible.h" 22 23#include "WebKitPrivate.h" 24#include <gtk/gtk.h> 25 26struct _WebKitWebViewBaseAccessiblePrivate { 27 GtkWidget* widget; 28}; 29 30WEBKIT_DEFINE_TYPE(WebKitWebViewBaseAccessible, webkit_web_view_base_accessible, ATK_TYPE_SOCKET) 31 32static void webkitWebViewBaseAccessibleWidgetDestroyed(GtkWidget*, WebKitWebViewBaseAccessible* accessible) 33{ 34 accessible->priv->widget = 0; 35 atk_object_notify_state_change(ATK_OBJECT(accessible), ATK_STATE_DEFUNCT, TRUE); 36} 37 38static void webkitWebViewBaseAccessibleInitialize(AtkObject* atkObject, gpointer data) 39{ 40 if (ATK_OBJECT_CLASS(webkit_web_view_base_accessible_parent_class)->initialize) 41 ATK_OBJECT_CLASS(webkit_web_view_base_accessible_parent_class)->initialize(atkObject, data); 42 43 if (data && GTK_IS_WIDGET(data)) { 44 WebKitWebViewBaseAccessible* accessible = WEBKIT_WEB_VIEW_BASE_ACCESSIBLE(atkObject); 45 accessible->priv->widget = GTK_WIDGET(data); 46 47 g_signal_connect_after(accessible->priv->widget, "destroy", 48 G_CALLBACK(webkitWebViewBaseAccessibleWidgetDestroyed), atkObject); 49 } 50 51 atk_object_set_role(atkObject, ATK_ROLE_FILLER); 52} 53 54static AtkStateSet* webkitWebViewBaseAccessibleRefStateSet(AtkObject* atkObject) 55{ 56 WebKitWebViewBaseAccessible* accessible = WEBKIT_WEB_VIEW_BASE_ACCESSIBLE(atkObject); 57 58 AtkStateSet* stateSet; 59 if (accessible->priv->widget) { 60 // Use the implementation of AtkSocket if the widget is still alive. 61 stateSet = ATK_OBJECT_CLASS(webkit_web_view_base_accessible_parent_class)->ref_state_set(atkObject); 62 } else { 63 // If the widget is no longer alive, save some remote calls 64 // (because of AtkSocket's implementation of ref_state_set()) 65 // and just return that this AtkObject is defunct. 66 stateSet = atk_state_set_new(); 67 atk_state_set_add_state(stateSet, ATK_STATE_DEFUNCT); 68 } 69 70 return stateSet; 71} 72 73static gint webkitWebViewBaseAccessibleGetIndexInParent(AtkObject* atkObject) 74{ 75 AtkObject* atkParent = atk_object_get_parent(atkObject); 76 if (!atkParent) 77 return -1; 78 79 guint count = atk_object_get_n_accessible_children(atkParent); 80 for (guint i = 0; i < count; ++i) { 81 AtkObject* child = atk_object_ref_accessible_child(atkParent, i); 82 bool childIsObject = child == atkObject; 83 g_object_unref(child); 84 if (childIsObject) 85 return i; 86 } 87 88 return -1; 89} 90 91static void webkit_web_view_base_accessible_class_init(WebKitWebViewBaseAccessibleClass* klass) 92{ 93 // No need to implement get_n_children() and ref_child() here 94 // since this is a subclass of AtkSocket and all the logic related 95 // to those functions will be implemented by the ATK bridge. 96 AtkObjectClass* atkObjectClass = ATK_OBJECT_CLASS(klass); 97 atkObjectClass->initialize = webkitWebViewBaseAccessibleInitialize; 98 atkObjectClass->ref_state_set = webkitWebViewBaseAccessibleRefStateSet; 99 atkObjectClass->get_index_in_parent = webkitWebViewBaseAccessibleGetIndexInParent; 100} 101 102WebKitWebViewBaseAccessible* webkitWebViewBaseAccessibleNew(GtkWidget* widget) 103{ 104 AtkObject* object = ATK_OBJECT(g_object_new(WEBKIT_TYPE_WEB_VIEW_BASE_ACCESSIBLE, NULL)); 105 atk_object_initialize(object, widget); 106 return WEBKIT_WEB_VIEW_BASE_ACCESSIBLE(object); 107} 108