Bug 480317 - Provide a way for atk-based plugins to slot into our a11y tree, r=joshmoz, ginn, surkov, trev, patch=btaylor, mcarrion, mgorse

This commit is contained in:
Brad Taylor 2011-04-27 22:42:18 +09:00
parent e80a0ff0ba
commit 2d0ff623b4
14 changed files with 605 additions and 82 deletions

View File

@ -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();
}

View File

@ -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

View File

@ -48,6 +48,7 @@ LIBXUL_LIBRARY = 1
CPPSRCS = \ CPPSRCS = \
AtkSocketAccessible.cpp \
nsAccessNodeWrap.cpp \ nsAccessNodeWrap.cpp \
nsAccessibleWrap.cpp \ nsAccessibleWrap.cpp \
nsDocAccessibleWrap.cpp \ nsDocAccessibleWrap.cpp \
@ -68,6 +69,7 @@ CPPSRCS = \
$(NULL) $(NULL)
EXPORTS = \ EXPORTS = \
AtkSocketAccessible.h \
nsAccessNodeWrap.h \ nsAccessNodeWrap.h \
nsARIAGridAccessibleWrap.h \ nsARIAGridAccessibleWrap.h \
nsAccessibleWrap.h \ nsAccessibleWrap.h \

View File

@ -49,6 +49,7 @@
#include "nsIServiceManager.h" #include "nsIServiceManager.h"
#include "nsAutoPtr.h" #include "nsAutoPtr.h"
#include "nsAccessibilityService.h" #include "nsAccessibilityService.h"
#include "AtkSocketAccessible.h"
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include <atk/atk.h> #include <atk/atk.h>
@ -722,8 +723,23 @@ nsApplicationAccessibleWrap::PreCreate()
sATKLib = PR_LoadLibrary(sATKLibName); sATKLib = PR_LoadLibrary(sATKLibName);
if (sATKLib) { if (sATKLib) {
AtkGetTypeType pfn_atk_hyperlink_impl_get_type = (AtkGetTypeType) PR_FindFunctionSymbol(sATKLib, sATKHyperlinkImplGetTypeSymbol); 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(); 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; sATKChecked = PR_TRUE;

View File

@ -1,5 +1,5 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:expandtab:shiftwidth=4:tabstop=4: /* vim:expandtab:shiftwidth=2:tabstop=2:
*/ */
/* ***** BEGIN LICENSE BLOCK ***** /* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
@ -67,76 +67,84 @@ componentInterfaceInitCB(AtkComponentIface *aIface)
aIface->grab_focus = grabFocusCB; aIface->grab_focus = grabFocusCB;
} }
AtkObject * AtkObject*
refAccessibleAtPointCB(AtkComponent *aComponent, refAccessibleAtPointCB(AtkComponent* aComponent, gint aAccX, gint aAccY,
gint aAccX, gint aAccY,
AtkCoordType aCoordType) AtkCoordType aCoordType)
{ {
nsAccessibleWrap *accWrap = GetAccessibleWrap(ATK_OBJECT(aComponent)); return refAccessibleAtPointHelper(GetAccessibleWrap(ATK_OBJECT(aComponent)),
if (!accWrap || nsAccUtils::MustPrune(accWrap)) aAccX, aAccY, aCoordType);
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;
} }
void void
getExtentsCB(AtkComponent *aComponent, getExtentsCB(AtkComponent* aComponent, gint* aX, gint* aY,
gint *aAccX, gint* aWidth, gint* aHeight, AtkCoordType aCoordType)
gint *aAccY,
gint *aAccWidth,
gint *aAccHeight,
AtkCoordType aCoordType)
{ {
*aAccX = *aAccY = *aAccWidth = *aAccHeight = 0; getExtentsHelper(GetAccessibleWrap(ATK_OBJECT(aComponent)),
aX, aY, aWidth, aHeight, aCoordType);
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;
} }
gboolean gboolean
grabFocusCB(AtkComponent *aComponent) grabFocusCB(AtkComponent* aComponent)
{ {
nsAccessibleWrap *accWrap = GetAccessibleWrap(ATK_OBJECT(aComponent)); nsAccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aComponent));
if (!accWrap) if (!accWrap)
return FALSE; return FALSE;
nsresult rv = accWrap->TakeFocus(); nsresult rv = accWrap->TakeFocus();
return (NS_FAILED(rv)) ? FALSE : TRUE; return (NS_FAILED(rv)) ? FALSE : TRUE;
}
AtkObject*
refAccessibleAtPointHelper(nsAccessibleWrap* aAccWrap, gint aX, gint aY,
AtkCoordType aCoordType)
{
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;
}
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;
} }

View File

@ -1,5 +1,5 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:expandtab:shiftwidth=4:tabstop=4: /* vim:expandtab:shiftwidth=2:tabstop=2:
*/ */
/* ***** BEGIN LICENSE BLOCK ***** /* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
@ -46,22 +46,20 @@
G_BEGIN_DECLS G_BEGIN_DECLS
/* component interface callbacks */ /* component interface callbacks */
void componentInterfaceInitCB(AtkComponentIface *aIface); void componentInterfaceInitCB(AtkComponentIface* aIface);
AtkObject *refAccessibleAtPointCB(AtkComponent *aComponent, AtkObject* refAccessibleAtPointCB(AtkComponent* aComponent,
gint aAccX, gint aAccY, gint aX, gint aY,
AtkCoordType aCoordType); AtkCoordType aCoordType);
void getExtentsCB(AtkComponent *aComponent, void getExtentsCB(AtkComponent* aComponent,
gint *aAccX, gint *aAccY, gint* aX, gint* aY, gint* aWidth, gint* aHeight,
gint *aAccWidth, gint *aAccHeight,
AtkCoordType aCoordType); AtkCoordType aCoordType);
/* the "contains", "get_position", "get_size" can take advantage of /* the "contains", "get_position", "get_size" can take advantage of
* "get_extents", there is no need to implement them now. * "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 * add_focus_handler
* remove_focus_handler * remove_focus_handler
* set_extents * set_extents
@ -69,8 +67,14 @@ gboolean grabFocusCB(AtkComponent *aComponent);
* set_size * set_size
* get_layer * get_layer
* get_mdi_zorder * 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 G_END_DECLS
#endif /* __MAI_INTERFACE_COMPONENT_H__ */ #endif /* __MAI_INTERFACE_COMPONENT_H__ */

View File

@ -95,6 +95,11 @@
#include "nsHTMLWin32ObjectAccessible.h" #include "nsHTMLWin32ObjectAccessible.h"
#endif #endif
// For embedding plugin accessibles
#ifdef MOZ_ACCESSIBILITY_ATK
#include "AtkSocketAccessible.h"
#endif
#ifndef DISABLE_XFORMS_HOOKS #ifndef DISABLE_XFORMS_HOOKS
#include "nsXFormsFormControlsAccessible.h" #include "nsXFormsFormControlsAccessible.h"
#include "nsXFormsWidgetsAccessible.h" #include "nsXFormsWidgetsAccessible.h"
@ -339,11 +344,12 @@ nsAccessibilityService::CreateHTMLObjectFrameAccessible(nsObjectFrame* aFrame,
return CreateOuterDocAccessible(aContent, aPresShell); return CreateOuterDocAccessible(aContent, aPresShell);
} }
#ifdef XP_WIN #if defined(XP_WIN) || defined(MOZ_ACCESSIBILITY_ATK)
// 2) for plugins // 2) for plugins
nsCOMPtr<nsIPluginInstance> pluginInstance ; nsCOMPtr<nsIPluginInstance> pluginInstance;
aFrame->GetPluginInstance(*getter_AddRefs(pluginInstance)); if (NS_SUCCEEDED(aFrame->GetPluginInstance(*getter_AddRefs(pluginInstance))) &&
if (pluginInstance) { pluginInstance) {
#ifdef XP_WIN
// Note: pluginPort will be null if windowless. // Note: pluginPort will be null if windowless.
HWND pluginPort = nsnull; HWND pluginPort = nsnull;
aFrame->GetPluginPort(&pluginPort); aFrame->GetPluginPort(&pluginPort);
@ -353,6 +359,22 @@ nsAccessibilityService::CreateHTMLObjectFrameAccessible(nsObjectFrame* aFrame,
pluginPort); pluginPort);
NS_IF_ADDREF(accessible); NS_IF_ADDREF(accessible);
return 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 #endif

View File

@ -104,6 +104,8 @@ child:
returns (nullable PPluginScriptableObject value, NPError result); returns (nullable PPluginScriptableObject value, NPError result);
rpc NPP_SetValue_NPNVprivateModeBool(bool value) returns (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) rpc NPP_HandleEvent(NPRemoteEvent event)
returns (int16_t handled); returns (int16_t handled);

View File

@ -586,6 +586,35 @@ PluginInstanceChild::AnswerNPP_GetValue_NPPVpluginScriptableNPObject(
return true; 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 bool
PluginInstanceChild::AnswerNPP_SetValue_NPNVprivateModeBool(const bool& value, PluginInstanceChild::AnswerNPP_SetValue_NPNVprivateModeBool(const bool& value,
NPError* result) NPError* result)

View File

@ -92,7 +92,9 @@ protected:
virtual bool virtual bool
AnswerNPP_GetValue_NPPVpluginScriptableNPObject(PPluginScriptableObjectChild** value, AnswerNPP_GetValue_NPPVpluginScriptableNPObject(PPluginScriptableObjectChild** value,
NPError* result); NPError* result);
virtual bool
AnswerNPP_GetValue_NPPVpluginNativeAccessibleAtkPlugId(nsCString* aPlugId,
NPError* aResult);
virtual bool virtual bool
AnswerNPP_SetValue_NPNVprivateModeBool(const bool& value, NPError* result); AnswerNPP_SetValue_NPNVprivateModeBool(const bool& value, NPError* result);

View File

@ -961,6 +961,23 @@ PluginInstanceParent::NPP_GetValue(NPPVariable aVariable,
return NPERR_NO_ERROR; 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: default:
PR_LOG(gPluginLog, PR_LOG_WARNING, PR_LOG(gPluginLog, PR_LOG_WARNING,
("In PluginInstanceParent::NPP_GetValue: Unhandled NPPVariable %i (%s)", ("In PluginInstanceParent::NPP_GetValue: Unhandled NPPVariable %i (%s)",

View File

@ -20,6 +20,8 @@
#ifndef __ATK_H__ #ifndef __ATK_H__
#define __ATK_H__ #define __ATK_H__
#define __ATK_H_INSIDE__
#include <atk/atkobject.h> #include <atk/atkobject.h>
#include <atk/atkaction.h> #include <atk/atkaction.h>
#include <atk/atkcomponent.h> #include <atk/atkcomponent.h>
@ -33,11 +35,13 @@
#include <atk/atknoopobject.h> #include <atk/atknoopobject.h>
#include <atk/atknoopobjectfactory.h> #include <atk/atknoopobjectfactory.h>
#include <atk/atkobjectfactory.h> #include <atk/atkobjectfactory.h>
#include <atk/atkplug.h>
#include <atk/atkregistry.h> #include <atk/atkregistry.h>
#include <atk/atkrelation.h> #include <atk/atkrelation.h>
#include <atk/atkrelationset.h> #include <atk/atkrelationset.h>
#include <atk/atkrelationtype.h> #include <atk/atkrelationtype.h>
#include <atk/atkselection.h> #include <atk/atkselection.h>
#include <atk/atksocket.h>
#include <atk/atkstate.h> #include <atk/atkstate.h>
#include <atk/atkstateset.h> #include <atk/atkstateset.h>
#include <atk/atkstreamablecontent.h> #include <atk/atkstreamablecontent.h>
@ -46,4 +50,6 @@
#include <atk/atkutil.h> #include <atk/atkutil.h>
#include <atk/atkvalue.h> #include <atk/atkvalue.h>
#undef __ATK_H_INSIDE__
#endif /* __ATK_H__ */ #endif /* __ATK_H__ */

View File

@ -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__ */

View File

@ -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__ */