Bug 480317 - Provide a way for atk-based plugins to slot into our a11y tree, r=joshmoz, ginn, surkov, trev, patch=btaylor, mcarrion, mgorse
authorBrad Taylor <brad@getcoded.net>
Wed, 27 Apr 2011 22:42:18 +0900
changeset 68669 0c49216dd89f6b887dfcc8db8f2eb1baccc8582a
parent 68668 e4afb9b58f77a4e1b13fee57d5eb5eb6a36bbed9
child 68670 f9a978db810270a3ce6a10e4e581740c14997325
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersjoshmoz, ginn, surkov, trev
bugs480317
milestone6.0a1
Bug 480317 - Provide a way for atk-based plugins to slot into our a11y tree, r=joshmoz, ginn, surkov, trev, patch=btaylor, mcarrion, mgorse
accessible/src/atk/AtkSocketAccessible.cpp
accessible/src/atk/AtkSocketAccessible.h
accessible/src/atk/Makefile.in
accessible/src/atk/nsApplicationAccessibleWrap.cpp
accessible/src/atk/nsMaiInterfaceComponent.cpp
accessible/src/atk/nsMaiInterfaceComponent.h
accessible/src/base/nsAccessibilityService.cpp
dom/plugins/ipc/PPluginInstance.ipdl
dom/plugins/ipc/PluginInstanceChild.cpp
dom/plugins/ipc/PluginInstanceChild.h
dom/plugins/ipc/PluginInstanceParent.cpp
other-licenses/atk-1.0/atk/atk.h
other-licenses/atk-1.0/atk/atkplug.h
other-licenses/atk-1.0/atk/atksocket.h
new file mode 100644
--- /dev/null
+++ b/accessible/src/atk/AtkSocketAccessible.cpp
@@ -0,0 +1,203 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:expandtab:shiftwidth=2:tabstop=2:
+ */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Novell, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Brad Taylor <brad@getcoded.net> (original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include <atk/atk.h>
+#include "AtkSocketAccessible.h"
+#include "nsMai.h"
+#include "nsMaiInterfaceComponent.h"
+
+void (*AtkSocketAccessible::g_atk_socket_embed) (AtkSocket*, gchar*) = NULL;
+GType AtkSocketAccessible::g_atk_socket_type = G_TYPE_INVALID;
+const char* AtkSocketAccessible::sATKSocketEmbedSymbol = "atk_socket_embed";
+const char* AtkSocketAccessible::sATKSocketGetTypeSymbol = "atk_socket_get_type";
+
+bool AtkSocketAccessible::gCanEmbed = FALSE;
+
+/* MaiAtkSocket */
+
+#define MAI_TYPE_ATK_SOCKET              (mai_atk_socket_get_type ())
+#define MAI_ATK_SOCKET(obj)              (G_TYPE_CHECK_INSTANCE_CAST ((obj),\
+                                          MAI_TYPE_ATK_SOCKET, MaiAtkSocket))
+#define MAI_IS_ATK_SOCKET(obj)           (G_TYPE_CHECK_INSTANCE_TYPE ((obj),\
+                                          MAI_TYPE_ATK_SOCKET))
+#define MAI_ATK_SOCKET_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass),\
+                                          MAI_TYPE_ATK_SOCKET,\
+                                          MaiAtkSocketClass))
+#define MAI_IS_ATK_SOCKET_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass),\
+                                          MAI_TYPE_ATK_SOCKET))
+#define MAI_ATK_SOCKET_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj),\
+                                          MAI_TYPE_ATK_SOCKET,\
+                                          MaiAtkSocketClass))
+
+typedef struct _MaiAtkSocket             MaiAtkSocket;
+typedef struct _MaiAtkSocketClass        MaiAtkSocketClass;
+
+struct _MaiAtkSocket
+{
+  AtkSocket parent;
+
+  nsAccessibleWrap* accWrap;
+};
+
+struct _MaiAtkSocketClass
+{
+  AtkSocketClass parent_class;
+};
+
+G_BEGIN_DECLS
+
+GType mai_atk_socket_get_type(void);
+AtkObject* mai_atk_socket_new(nsAccessibleWrap* aAccWrap);
+
+void mai_atk_component_iface_init(AtkComponentIface* aIface);
+AtkObject* mai_atk_socket_ref_accessible_at_point(AtkComponent *aComponent,
+                                                  gint aAccX,
+                                                  gint aAccY,
+                                                  AtkCoordType aCoordType);
+void mai_atk_socket_get_extents(AtkComponent* aComponent,
+                                gint* aAccX,
+                                gint* aAccY,
+                                gint* aAccWidth,
+                                gint* aAccHeight,
+                                AtkCoordType aCoordType);
+
+G_END_DECLS
+
+G_DEFINE_TYPE_EXTENDED(MaiAtkSocket, mai_atk_socket,
+                       AtkSocketAccessible::g_atk_socket_type, 0,
+                       G_IMPLEMENT_INTERFACE(ATK_TYPE_COMPONENT,
+                                             mai_atk_component_iface_init))
+
+void
+mai_atk_socket_class_init(MaiAtkSocketClass* aAcc)
+{
+}
+
+void
+mai_atk_socket_init(MaiAtkSocket* aAcc)
+{
+}
+
+AtkObject*
+mai_atk_socket_new(nsAccessibleWrap* aAccWrap)
+{
+  NS_ENSURE_TRUE(aAccWrap, NULL);
+
+  MaiAtkSocket* acc = nsnull;
+  acc = static_cast<MaiAtkSocket*>(g_object_new(MAI_TYPE_ATK_SOCKET, NULL));
+  NS_ENSURE_TRUE(acc, NULL);
+
+  acc->accWrap = aAccWrap;
+  return ATK_OBJECT(acc);
+}
+
+void
+mai_atk_component_iface_init(AtkComponentIface* aIface)
+{
+  NS_ASSERTION(aIface, "Invalid Interface");
+
+  aIface->ref_accessible_at_point = mai_atk_socket_ref_accessible_at_point;
+  aIface->get_extents = mai_atk_socket_get_extents;
+}
+
+AtkObject*
+mai_atk_socket_ref_accessible_at_point(AtkComponent* aComponent,
+                                       gint aX, gint aY,
+                                       AtkCoordType aCoordType)
+{
+  NS_ENSURE_TRUE(MAI_IS_ATK_SOCKET(aComponent), nsnull);
+
+  return refAccessibleAtPointHelper(MAI_ATK_SOCKET(aComponent)->accWrap,
+                                    aX, aY, aCoordType);
+}
+
+void
+mai_atk_socket_get_extents(AtkComponent* aComponent,
+                           gint* aX, gint* aY, gint* aWidth, gint* aHeight,
+                           AtkCoordType aCoordType)
+{
+  *aX = *aY = *aWidth = *aHeight = 0;
+
+  if (!MAI_IS_ATK_SOCKET(aComponent))
+    return;
+
+  getExtentsHelper(MAI_ATK_SOCKET(aComponent)->accWrap,
+                   aX, aY, aWidth, aHeight, aCoordType);
+}
+
+AtkSocketAccessible::AtkSocketAccessible(nsIContent* aContent,
+                                         nsIWeakReference* aShell,
+                                         const nsCString& aPlugId) :
+  nsAccessibleWrap(aContent, aShell)
+{
+  mAtkObject = mai_atk_socket_new(this);
+  if (!mAtkObject)
+    return;
+
+  // Embeds the children of an AtkPlug, specified by plugId, as the children of
+  // this socket.
+  // Using G_TYPE macros instead of ATK_SOCKET macros to avoid undefined
+  // symbols.
+  if (gCanEmbed && G_TYPE_CHECK_INSTANCE_TYPE(mAtkObject, g_atk_socket_type) &&
+      !aPlugId.IsVoid()) {
+    AtkSocket* accSocket =
+      G_TYPE_CHECK_INSTANCE_CAST(mAtkObject, g_atk_socket_type, AtkSocket);
+    g_atk_socket_embed(accSocket, (gchar*)aPlugId.get());
+  }
+}
+
+NS_IMETHODIMP
+AtkSocketAccessible::GetNativeInterface(void** aOutAccessible)
+{
+  *aOutAccessible = mAtkObject;
+  return NS_OK;
+}
+
+void
+AtkSocketAccessible::Shutdown()
+{
+  if (mAtkObject) {
+    if (MAI_IS_ATK_SOCKET(mAtkObject))
+      MAI_ATK_SOCKET(mAtkObject)->accWrap = nsnull;
+    g_object_unref(mAtkObject);
+    mAtkObject = nsnull;
+  }
+  nsAccessibleWrap::Shutdown();
+}
new file mode 100644
--- /dev/null
+++ b/accessible/src/atk/AtkSocketAccessible.h
@@ -0,0 +1,86 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:expandtab:shiftwidth=2:tabstop=2:
+ */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Novell, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Brad Taylor <brad@getcoded.net> (original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef _AtkSocketAccessible_H_
+#define _AtkSocketAccessible_H_
+
+#include "nsAccessibleWrap.h"
+
+// This file gets included by nsAccessibilityService.cpp, which can't include
+// atk.h (or glib.h), so we can't rely on it being included.
+#ifdef __ATK_H__
+typedef void (*AtkSocketEmbedType) (AtkSocket*, gchar*);
+#else
+typedef void (*AtkSocketEmbedType) (void*, void*);
+#endif
+
+/**
+ * Provides a nsAccessibleWrap wrapper around AtkSocket for out-of-process
+ * accessibles.
+ */
+class AtkSocketAccessible: public nsAccessibleWrap
+{
+public:
+
+  // Soft references to AtkSocket
+  static AtkSocketEmbedType g_atk_socket_embed;
+#ifdef __ATK_H__
+  static GType g_atk_socket_type;
+#endif
+  static const char* sATKSocketEmbedSymbol;
+  static const char* sATKSocketGetTypeSymbol;
+
+  /*
+   * True if the current Atk version supports AtkSocket and it was correctly
+   * loaded.
+   */
+  static bool gCanEmbed;
+
+  AtkSocketAccessible(nsIContent* aContent, nsIWeakReference* aShell,
+                      const nsCString& aPlugId);
+
+  // nsAccessNode
+  virtual void Shutdown();
+
+  // nsIAccessible
+  NS_IMETHODIMP GetNativeInterface(void** aOutAccessible);
+};
+
+#endif
--- a/accessible/src/atk/Makefile.in
+++ b/accessible/src/atk/Makefile.in
@@ -43,16 +43,17 @@ include $(DEPTH)/config/autoconf.mk
 
 MODULE = accessibility
 LIBRARY_NAME = accessibility_toolkit_s
 EXPORT_LIBRARY = ..
 LIBXUL_LIBRARY = 1
 
 
 CPPSRCS = \
+  AtkSocketAccessible.cpp \
   nsAccessNodeWrap.cpp \
   nsAccessibleWrap.cpp \
   nsDocAccessibleWrap.cpp \
   nsRootAccessibleWrap.cpp \
   nsApplicationAccessibleWrap.cpp \
   nsMaiInterfaceComponent.cpp \
   nsMaiInterfaceAction.cpp \
   nsMaiInterfaceText.cpp \
@@ -63,16 +64,17 @@ CPPSRCS = \
   nsMaiInterfaceHypertext.cpp \
   nsMaiInterfaceHyperlinkImpl.cpp \
   nsMaiInterfaceTable.cpp \
   nsMaiInterfaceDocument.cpp \
   nsMaiInterfaceImage.cpp \
   $(NULL)
 
 EXPORTS = \
+  AtkSocketAccessible.h \
   nsAccessNodeWrap.h \
   nsARIAGridAccessibleWrap.h \
   nsAccessibleWrap.h \
   nsDocAccessibleWrap.h \
   nsRootAccessibleWrap.h \
   nsTextAccessibleWrap.h \
   nsXULMenuAccessibleWrap.h \
   nsXULListboxAccessibleWrap.h \
--- a/accessible/src/atk/nsApplicationAccessibleWrap.cpp
+++ b/accessible/src/atk/nsApplicationAccessibleWrap.cpp
@@ -44,16 +44,17 @@
 #include "nsCOMPtr.h"
 #include "nsMai.h"
 #include "prlink.h"
 #include "prenv.h"
 #include "nsIPrefBranch.h"
 #include "nsIServiceManager.h"
 #include "nsAutoPtr.h"
 #include "nsAccessibilityService.h"
+#include "AtkSocketAccessible.h"
 
 #include <gtk/gtk.h>
 #include <atk/atk.h>
 
 typedef GType (* AtkGetTypeType) (void);
 GType g_atk_hyperlink_impl_type = G_TYPE_INVALID;
 static PRBool sATKChecked = PR_FALSE;
 static PRLibrary *sATKLib = nsnull;
@@ -717,18 +718,33 @@ nsApplicationAccessibleWrap::RemoveChild
 
 void
 nsApplicationAccessibleWrap::PreCreate()
 {
     if (!sATKChecked) {
         sATKLib = PR_LoadLibrary(sATKLibName);
         if (sATKLib) {
             AtkGetTypeType pfn_atk_hyperlink_impl_get_type = (AtkGetTypeType) PR_FindFunctionSymbol(sATKLib, sATKHyperlinkImplGetTypeSymbol);
-            if (pfn_atk_hyperlink_impl_get_type) {
+            if (pfn_atk_hyperlink_impl_get_type)
                 g_atk_hyperlink_impl_type = pfn_atk_hyperlink_impl_get_type();
+
+            AtkGetTypeType pfn_atk_socket_get_type;
+            pfn_atk_socket_get_type = (AtkGetTypeType)
+                                      PR_FindFunctionSymbol(sATKLib,
+                                                            AtkSocketAccessible::sATKSocketGetTypeSymbol);
+            if (pfn_atk_socket_get_type) {
+                AtkSocketAccessible::g_atk_socket_type =
+                  pfn_atk_socket_get_type();
+                AtkSocketAccessible::g_atk_socket_embed = (AtkSocketEmbedType)
+                  PR_FindFunctionSymbol(sATKLib,
+                                        AtkSocketAccessible
+                                          ::sATKSocketEmbedSymbol);
+            AtkSocketAccessible::gCanEmbed =
+              AtkSocketAccessible::g_atk_socket_type != G_TYPE_INVALID &&
+              AtkSocketAccessible::g_atk_socket_embed;
             }
         }
         sATKChecked = PR_TRUE;
     }
 }
 
 static nsresult
 LoadGtkModule(GnomeAccessibilityModule& aModule)
--- a/accessible/src/atk/nsMaiInterfaceComponent.cpp
+++ b/accessible/src/atk/nsMaiInterfaceComponent.cpp
@@ -1,10 +1,10 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* vim:expandtab:shiftwidth=4:tabstop=4:
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:expandtab:shiftwidth=2:tabstop=2:
  */
 /* ***** BEGIN LICENSE BLOCK *****
  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  *
  * The contents of this file are subject to the Mozilla Public License Version
  * 1.1 (the "License"); you may not use this file except in compliance with
  * the License. You may obtain a copy of the License at
  * http://www.mozilla.org/MPL/
@@ -62,81 +62,89 @@ componentInterfaceInitCB(AtkComponentIfa
      * Use default implementation in atk for contains, get_position,
      * and get_size
      */
     aIface->ref_accessible_at_point = refAccessibleAtPointCB;
     aIface->get_extents = getExtentsCB;
     aIface->grab_focus = grabFocusCB;
 }
 
-AtkObject *
-refAccessibleAtPointCB(AtkComponent *aComponent,
-                       gint aAccX, gint aAccY,
+AtkObject*
+refAccessibleAtPointCB(AtkComponent* aComponent, gint aAccX, gint aAccY,
                        AtkCoordType aCoordType)
 {
-    nsAccessibleWrap *accWrap = GetAccessibleWrap(ATK_OBJECT(aComponent));
-    if (!accWrap || nsAccUtils::MustPrune(accWrap))
-        return nsnull;
-
-    // nsIAccessible getChildAtPoint (x,y) is in screen pixels.
-    if (aCoordType == ATK_XY_WINDOW) {
-        nsIntPoint winCoords =
-          nsCoreUtils::GetScreenCoordsForWindow(accWrap->GetNode());
-        aAccX += winCoords.x;
-        aAccY += winCoords.y;
-    }
-
-    nsCOMPtr<nsIAccessible> pointAcc;
-    accWrap->GetChildAtPoint(aAccX, aAccY, getter_AddRefs(pointAcc));
-    if (!pointAcc) {
-        return nsnull;
-    }
-
-    AtkObject *atkObj = nsAccessibleWrap::GetAtkObject(pointAcc);
-    if (atkObj) {
-        g_object_ref(atkObj);
-    }
-    return atkObj;
+  return refAccessibleAtPointHelper(GetAccessibleWrap(ATK_OBJECT(aComponent)),
+                                    aAccX, aAccY, aCoordType);
 }
 
 void
-getExtentsCB(AtkComponent *aComponent,
-             gint *aAccX,
-             gint *aAccY,
-             gint *aAccWidth,
-             gint *aAccHeight,
-             AtkCoordType aCoordType)
+getExtentsCB(AtkComponent* aComponent, gint* aX, gint* aY,
+             gint* aWidth, gint* aHeight, AtkCoordType aCoordType)
 {
-    *aAccX = *aAccY = *aAccWidth = *aAccHeight = 0;
-
-    nsAccessibleWrap *accWrap = GetAccessibleWrap(ATK_OBJECT(aComponent));
-    if (!accWrap)
-        return;
-
-    PRInt32 nsAccX, nsAccY, nsAccWidth, nsAccHeight;
-    // Returned in screen coordinates
-    nsresult rv = accWrap->GetBounds(&nsAccX, &nsAccY,
-                                     &nsAccWidth, &nsAccHeight);
-    if (NS_FAILED(rv))
-        return;
-    if (aCoordType == ATK_XY_WINDOW) {
-        nsIntPoint winCoords =
-          nsCoreUtils::GetScreenCoordsForWindow(accWrap->GetNode());
-        nsAccX -= winCoords.x;
-        nsAccY -= winCoords.y;
-    }
-
-    *aAccX = nsAccX;
-    *aAccY = nsAccY;
-    *aAccWidth = nsAccWidth;
-    *aAccHeight = nsAccHeight;
+  getExtentsHelper(GetAccessibleWrap(ATK_OBJECT(aComponent)),
+                   aX, aY, aWidth, aHeight, aCoordType);
 }
 
 gboolean
-grabFocusCB(AtkComponent *aComponent)
+grabFocusCB(AtkComponent* aComponent)
+{
+  nsAccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aComponent));
+  if (!accWrap)
+    return FALSE;
+
+  nsresult rv = accWrap->TakeFocus();
+  return (NS_FAILED(rv)) ? FALSE : TRUE;
+}
+
+AtkObject*
+refAccessibleAtPointHelper(nsAccessibleWrap* aAccWrap, gint aX, gint aY,
+                           AtkCoordType aCoordType)
 {
-    nsAccessibleWrap *accWrap = GetAccessibleWrap(ATK_OBJECT(aComponent));
-    if (!accWrap)
-        return FALSE;
+  if (!aAccWrap || aAccWrap->IsDefunct() || nsAccUtils::MustPrune(aAccWrap))
+    return nsnull;
+
+  // nsAccessible::GetChildAtPoint(x,y) is in screen pixels.
+  if (aCoordType == ATK_XY_WINDOW) {
+    nsIntPoint winCoords =
+      nsCoreUtils::GetScreenCoordsForWindow(aAccWrap->GetNode());
+    aX += winCoords.x;
+    aY += winCoords.y;
+  }
+
+  nsAccessible* accAtPoint = aAccWrap->GetChildAtPoint(aX, aY,
+                                                       nsAccessible::eDirectChild);
+  if (!accAtPoint)
+    return nsnull;
+
+  AtkObject* atkObj = nsAccessibleWrap::GetAtkObject(accAtPoint);
+  if (atkObj)
+    g_object_ref(atkObj);
+  return atkObj;
+}
 
-    nsresult rv = accWrap->TakeFocus();
-    return (NS_FAILED(rv)) ? FALSE : TRUE;
+void
+getExtentsHelper(nsAccessibleWrap* aAccWrap,
+                 gint* aX, gint* aY, gint* aWidth, gint* aHeight,
+                 AtkCoordType aCoordType)
+{
+  *aX = *aY = *aWidth = *aHeight = 0;
+
+  if (!aAccWrap || aAccWrap->IsDefunct())
+    return;
+
+  PRInt32 x = 0, y = 0, width = 0, height = 0;
+  // Returned in screen coordinates
+  nsresult rv = aAccWrap->GetBounds(&x, &y, &width, &height);
+  if (NS_FAILED(rv))
+    return;
+
+  if (aCoordType == ATK_XY_WINDOW) {
+    nsIntPoint winCoords =
+      nsCoreUtils::GetScreenCoordsForWindow(aAccWrap->GetNode());
+    x -= winCoords.x;
+    y -= winCoords.y;
+  }
+
+  *aX = x;
+  *aY = y;
+  *aWidth = width;
+  *aHeight = height;
 }
--- a/accessible/src/atk/nsMaiInterfaceComponent.h
+++ b/accessible/src/atk/nsMaiInterfaceComponent.h
@@ -1,10 +1,10 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* vim:expandtab:shiftwidth=4:tabstop=4:
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:expandtab:shiftwidth=2:tabstop=2:
  */
 /* ***** BEGIN LICENSE BLOCK *****
  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  *
  * The contents of this file are subject to the Mozilla Public License Version
  * 1.1 (the "License"); you may not use this file except in compliance with
  * the License. You may obtain a copy of the License at
  * http://www.mozilla.org/MPL/
@@ -41,36 +41,40 @@
 #ifndef __MAI_INTERFACE_COMPONENT_H__
 #define __MAI_INTERFACE_COMPONENT_H__
 
 #include "nsMai.h"
 
 G_BEGIN_DECLS
 
 /* component interface callbacks */
-void componentInterfaceInitCB(AtkComponentIface *aIface);
-AtkObject *refAccessibleAtPointCB(AtkComponent *aComponent,
-                                  gint aAccX, gint aAccY,
+void componentInterfaceInitCB(AtkComponentIface* aIface);
+AtkObject* refAccessibleAtPointCB(AtkComponent* aComponent,
+                                  gint aX, gint aY,
                                   AtkCoordType aCoordType);
-void getExtentsCB(AtkComponent *aComponent,
-                  gint *aAccX, gint *aAccY,
-                  gint *aAccWidth, gint *aAccHeight,
+void getExtentsCB(AtkComponent* aComponent,
+                  gint* aX, gint* aY, gint* aWidth, gint* aHeight,
                   AtkCoordType aCoordType);
 /* the "contains", "get_position", "get_size" can take advantage of
  * "get_extents", there is no need to implement them now.
  */
-gboolean grabFocusCB(AtkComponent *aComponent);
+gboolean grabFocusCB(AtkComponent* aComponent);
 
-/* what are missing now for atk component */
-
-/* ==================================================
+/* what are missing now for atk component:
+ *
  * add_focus_handler
  * remove_focus_handler
  * set_extents
  * set_position
  * set_size
  * get_layer
  * get_mdi_zorder
- * ==================================================
  */
+
+AtkObject* refAccessibleAtPointHelper(nsAccessibleWrap* aAccWrap,
+                                      gint aX, gint aY, AtkCoordType aCoordType);
+void getExtentsHelper(nsAccessibleWrap* aAccWrap,
+                      gint* aX, gint* aY, gint* aWidth, gint* aHeight,
+                      AtkCoordType aCoordType);
+
 G_END_DECLS
 
 #endif /* __MAI_INTERFACE_COMPONENT_H__ */
--- a/accessible/src/base/nsAccessibilityService.cpp
+++ b/accessible/src/base/nsAccessibilityService.cpp
@@ -90,16 +90,21 @@
 #include "nsXULTreeGridAccessibleWrap.h"
 #endif
 
 // For native window support for object/embed/applet tags
 #ifdef XP_WIN
 #include "nsHTMLWin32ObjectAccessible.h"
 #endif
 
+// For embedding plugin accessibles
+#ifdef MOZ_ACCESSIBILITY_ATK
+#include "AtkSocketAccessible.h"
+#endif
+
 #ifndef DISABLE_XFORMS_HOOKS
 #include "nsXFormsFormControlsAccessible.h"
 #include "nsXFormsWidgetsAccessible.h"
 #endif
 
 #include "mozilla/FunctionTimer.h"
 #include "mozilla/dom/Element.h"
 #include "nsImageMapUtils.h"
@@ -334,30 +339,47 @@ nsAccessibilityService::CreateHTMLObject
   nsCOMPtr<nsIDOMHTMLObjectElement> obj(do_QueryInterface(aContent));
   if (obj) {
     nsCOMPtr<nsIDOMDocument> domDoc;
     obj->GetContentDocument(getter_AddRefs(domDoc));
     if (domDoc)
       return CreateOuterDocAccessible(aContent, aPresShell);
   }
 
-#ifdef XP_WIN
+#if defined(XP_WIN) || defined(MOZ_ACCESSIBILITY_ATK)
   // 2) for plugins
-  nsCOMPtr<nsIPluginInstance> pluginInstance ;
-  aFrame->GetPluginInstance(*getter_AddRefs(pluginInstance));
-  if (pluginInstance) {
+  nsCOMPtr<nsIPluginInstance> pluginInstance;
+  if (NS_SUCCEEDED(aFrame->GetPluginInstance(*getter_AddRefs(pluginInstance))) &&
+      pluginInstance) {
+#ifdef XP_WIN
     // Note: pluginPort will be null if windowless.
     HWND pluginPort = nsnull;
     aFrame->GetPluginPort(&pluginPort);
 
     nsAccessible* accessible = new nsHTMLWin32ObjectOwnerAccessible(aContent,
                                                                     weakShell,
                                                                     pluginPort);
     NS_IF_ADDREF(accessible);
     return accessible;
+
+#elif MOZ_ACCESSIBILITY_ATK
+    if (!AtkSocketAccessible::gCanEmbed)
+      return nsnull;
+
+    nsCString plugId;
+    nsresult rv = pluginInstance->GetValueFromPlugin(
+      NPPVpluginNativeAccessibleAtkPlugId, &plugId);
+    if (NS_SUCCEEDED(rv) && !plugId.IsVoid()) {
+      AtkSocketAccessible* socketAccessible =
+        new AtkSocketAccessible(aContent, weakShell, plugId);
+
+      NS_IF_ADDREF(socketAccessible);
+      return socketAccessible;
+    }
+#endif
   }
 #endif
 
   // 3) for images and imagemaps, or anything else with a child frame
   // we have the object frame, get the image frame
   nsIFrame* frame = aFrame->GetFirstChild(nsnull);
   return frame ? frame->CreateAccessible() : nsnull;
 }
--- a/dom/plugins/ipc/PPluginInstance.ipdl
+++ b/dom/plugins/ipc/PPluginInstance.ipdl
@@ -99,16 +99,18 @@ child:
 
   // this message is not used on non-X platforms
   rpc NPP_GetValue_NPPVpluginNeedsXEmbed()
     returns (bool value, NPError result);
   rpc NPP_GetValue_NPPVpluginScriptableNPObject()
     returns (nullable PPluginScriptableObject value, NPError result);
 
   rpc NPP_SetValue_NPNVprivateModeBool(bool value) returns (NPError result);
+  rpc NPP_GetValue_NPPVpluginNativeAccessibleAtkPlugId()
+    returns (nsCString plug_id, NPError result);
 
   rpc NPP_HandleEvent(NPRemoteEvent event)
     returns (int16_t handled);
   // special cases where we need to a shared memory buffer
   rpc NPP_HandleEvent_Shmem(NPRemoteEvent event, Shmem buffer)
     returns (int16_t handled, Shmem rtnbuffer);
   // special cases where we need an iosurface
   rpc NPP_HandleEvent_IOSurface(NPRemoteEvent event, uint32_t surfaceid)
--- a/dom/plugins/ipc/PluginInstanceChild.cpp
+++ b/dom/plugins/ipc/PluginInstanceChild.cpp
@@ -582,16 +582,45 @@ PluginInstanceChild::AnswerNPP_GetValue_
     }
 
     *aValue = nsnull;
     *aResult = result;
     return true;
 }
 
 bool
+PluginInstanceChild::AnswerNPP_GetValue_NPPVpluginNativeAccessibleAtkPlugId(
+                                          nsCString* aPlugId,
+                                          NPError* aResult)
+{
+    AssertPluginThread();
+
+#if MOZ_ACCESSIBILITY_ATK
+
+    char* plugId = NULL;
+    NPError result = NPERR_GENERIC_ERROR;
+    if (mPluginIface->getvalue) {
+        result = mPluginIface->getvalue(GetNPP(),
+                                        NPPVpluginNativeAccessibleAtkPlugId,
+                                        &plugId);
+    }
+
+    *aPlugId = nsCString(plugId);
+    *aResult = result;
+    return true;
+
+#else
+
+    NS_RUNTIMEABORT("shouldn't be called on non-ATK platforms");
+    return false;
+
+#endif
+}
+
+bool
 PluginInstanceChild::AnswerNPP_SetValue_NPNVprivateModeBool(const bool& value,
                                                             NPError* result)
 {
     if (!mPluginIface->setvalue) {
         *result = NPERR_GENERIC_ERROR;
         return true;
     }
 
--- a/dom/plugins/ipc/PluginInstanceChild.h
+++ b/dom/plugins/ipc/PluginInstanceChild.h
@@ -87,17 +87,19 @@ class PluginInstanceChild : public PPlug
 protected:
     virtual bool AnswerNPP_SetWindow(const NPRemoteWindow& window);
 
     virtual bool
     AnswerNPP_GetValue_NPPVpluginNeedsXEmbed(bool* needs, NPError* rv);
     virtual bool
     AnswerNPP_GetValue_NPPVpluginScriptableNPObject(PPluginScriptableObjectChild** value,
                                                     NPError* result);
-
+    virtual bool
+    AnswerNPP_GetValue_NPPVpluginNativeAccessibleAtkPlugId(nsCString* aPlugId,
+                                                     NPError* aResult);
     virtual bool
     AnswerNPP_SetValue_NPNVprivateModeBool(const bool& value, NPError* result);
 
     virtual bool
     AnswerNPP_HandleEvent(const NPRemoteEvent& event, int16_t* handled);
     virtual bool
     AnswerNPP_HandleEvent_Shmem(const NPRemoteEvent& event, Shmem& mem, int16_t* handled, Shmem* rtnmem);
     virtual bool
--- a/dom/plugins/ipc/PluginInstanceParent.cpp
+++ b/dom/plugins/ipc/PluginInstanceParent.cpp
@@ -956,16 +956,33 @@ PluginInstanceParent::NPP_GetValue(NPPVa
         NPObject* object =
             static_cast<PluginScriptableObjectParent*>(actor)->GetObject(true);
         NS_ASSERTION(object, "This shouldn't ever be null!");
 
         (*(NPObject**)_retval) = npn->retainobject(object);
         return NPERR_NO_ERROR;
     }
 
+#ifdef MOZ_ACCESSIBILITY_ATK
+    case NPPVpluginNativeAccessibleAtkPlugId: {
+        nsCString plugId;
+        NPError rv;
+        if (!CallNPP_GetValue_NPPVpluginNativeAccessibleAtkPlugId(&plugId, &rv)) {
+            return NPERR_GENERIC_ERROR;
+        }
+
+        if (NPERR_NO_ERROR != rv) {
+            return rv;
+        }
+
+        (*(nsCString*)_retval) = plugId;
+        return NPERR_NO_ERROR;
+    }
+#endif
+
     default:
         PR_LOG(gPluginLog, PR_LOG_WARNING,
                ("In PluginInstanceParent::NPP_GetValue: Unhandled NPPVariable %i (%s)",
                 (int) aVariable, NPPVariableToString(aVariable)));
         return NPERR_GENERIC_ERROR;
     }
 }
 
--- a/other-licenses/atk-1.0/atk/atk.h
+++ b/other-licenses/atk-1.0/atk/atk.h
@@ -15,35 +15,41 @@
  * License along with this library; if not, write to the
  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  * Boston, MA 02111-1307, USA.
  */
 
 #ifndef __ATK_H__
 #define __ATK_H__
 
+#define __ATK_H_INSIDE__
+
 #include <atk/atkobject.h>
 #include <atk/atkaction.h>
 #include <atk/atkcomponent.h>
 #include <atk/atkdocument.h>
 #include <atk/atkeditabletext.h>
 #include <atk/atkgobjectaccessible.h>
 #include <atk/atkhyperlink.h>
 #include <atk/atkhyperlinkimpl.h>
 #include <atk/atkhypertext.h>
 #include <atk/atkimage.h>
 #include <atk/atknoopobject.h>
 #include <atk/atknoopobjectfactory.h>
 #include <atk/atkobjectfactory.h>
+#include <atk/atkplug.h>
 #include <atk/atkregistry.h>
 #include <atk/atkrelation.h>
 #include <atk/atkrelationset.h>
 #include <atk/atkrelationtype.h>
 #include <atk/atkselection.h>
+#include <atk/atksocket.h>
 #include <atk/atkstate.h>
 #include <atk/atkstateset.h>
 #include <atk/atkstreamablecontent.h>
 #include <atk/atktable.h>
 #include <atk/atktext.h>
 #include <atk/atkutil.h>
 #include <atk/atkvalue.h>
 
+#undef __ATK_H_INSIDE__
+
 #endif /* __ATK_H__ */
new file mode 100644
--- /dev/null
+++ b/other-licenses/atk-1.0/atk/atkplug.h
@@ -0,0 +1,61 @@
+/* ATK -  Accessibility Toolkit
+ * Copyright 2009 Novell, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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.
+ */
+
+#if defined(ATK_DISABLE_SINGLE_INCLUDES) && !defined (__ATK_H_INSIDE__) && !defined (ATK_COMPILATION)
+#error "Only <atk/atk.h> can be included directly."
+#endif
+
+#ifndef __ATK_PLUG_H__
+#define __ATK_PLUG_H__
+
+G_BEGIN_DECLS
+
+#define ATK_TYPE_PLUG               (atk_plug_get_type ())
+#define ATK_PLUG(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), ATK_TYPE_PLUG, AtkPlug))
+#define ATK_IS_PLUG(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), ATK_TYPE_PLUG))
+#define ATK_PLUG_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), ATK_TYPE_PLUG, AtkPlugClass))
+#define ATK_IS_PLUG_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE ((klass), ATK_TYPE_PLUG))
+#define ATK_PLUG_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), ATK_TYPE_PLUG, AtkPlugClass))
+
+typedef struct _AtkPlug         AtkPlug;
+typedef struct _AtkPlugClass    AtkPlugClass;
+
+struct _AtkPlug
+{
+  AtkObject parent;
+};
+
+GType atk_plug_get_type (void);
+
+struct _AtkPlugClass
+{
+  AtkObjectClass parent_class;
+  
+  /* to be subscribed to by atk-bridge */
+
+  /*< protected >*/
+  gchar* (* get_object_id) (AtkPlug* obj);
+};
+
+AtkObject*    atk_plug_new     (void);
+gchar*        atk_plug_get_id  (AtkPlug* plug);
+
+G_END_DECLS
+
+#endif /* __ATK_PLUG_H__ */
new file mode 100644
--- /dev/null
+++ b/other-licenses/atk-1.0/atk/atksocket.h
@@ -0,0 +1,65 @@
+/* ATK -  Accessibility Toolkit
+ * Copyright 2009 Novell, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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.
+ */
+
+#if defined(ATK_DISABLE_SINGLE_INCLUDES) && !defined (__ATK_H_INSIDE__) && !defined (ATK_COMPILATION)
+#error "Only <atk/atk.h> can be included directly."
+#endif
+
+#ifndef __ATK_SOCKET_H__
+#define __ATK_SOCKET_H__
+
+G_BEGIN_DECLS
+
+#define ATK_TYPE_SOCKET               (atk_socket_get_type ())
+#define ATK_SOCKET(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), ATK_TYPE_SOCKET, AtkSocket))
+#define ATK_IS_SOCKET(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), ATK_TYPE_SOCKET))
+#define ATK_SOCKET_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), ATK_TYPE_SOCKET, AtkSocketClass))
+#define ATK_IS_SOCKET_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE ((klass), ATK_TYPE_SOCKET))
+#define ATK_SOCKET_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), ATK_TYPE_SOCKET, AtkSocketClass))
+
+typedef struct _AtkSocket         AtkSocket;
+typedef struct _AtkSocketClass    AtkSocketClass;
+
+struct _AtkSocket
+{
+  AtkObject parent;
+
+  /*< private >*/
+  gchar* embedded_plug_id;
+};
+
+GType atk_socket_get_type (void);
+
+struct _AtkSocketClass
+{
+  AtkObjectClass parent_class;
+  
+  /* to be subscribed to by atk-bridge */
+
+  /*< protected >*/
+  void (* embed) (AtkSocket *obj, gchar* plug_id);
+};
+
+AtkObject*    atk_socket_new           (void);
+void          atk_socket_embed         (AtkSocket* obj, gchar* plug_id);
+gboolean      atk_socket_is_occupied   (AtkSocket* obj);
+
+G_END_DECLS
+
+#endif /* __ATK_SOCKET_H__ */