nsresult
nsApplicationAccessibleWrap::AddRootAccessible(nsIAccessible *aRootAccWrap)
{
    NS_ENSURE_ARG_POINTER(aRootAccWrap);

    // add by weak reference
    nsresult rv = nsApplicationAccessible::AddRootAccessible(aRootAccWrap);
    NS_ENSURE_SUCCESS(rv, rv);

    AtkObject *atkAccessible = nsAccessibleWrap::GetAtkObject(aRootAccWrap);
    atk_object_set_parent(atkAccessible, mAtkObject);

    PRUint32 count = 0;
    mChildren->GetLength(&count);
    g_signal_emit_by_name(mAtkObject, "children_changed::add", count - 1,
                          atkAccessible, NULL);

#ifdef MAI_LOGGING
    if (NS_SUCCEEDED(rv)) {
        MAI_LOG_DEBUG(("\nAdd RootAcc=%p OK, count=%d\n",
                       (void*)aRootAccWrap, count));
    }
    else
        MAI_LOG_DEBUG(("\nAdd RootAcc=%p Failed, count=%d\n",
                       (void*)aRootAccWrap, count));
#endif

    return rv;
}
static nsresult
LoadGtkModule(GnomeAccessibilityModule& aModule)
{
    NS_ENSURE_ARG(aModule.libName);

    if (!(aModule.lib = PR_LoadLibrary(aModule.libName))) {

        MAI_LOG_DEBUG(("Fail to load lib: %s in default path\n", aModule.libName));

        //try to load the module with "gtk-2.0/modules" appended
        char *curLibPath = PR_GetLibraryPath();
        nsCAutoString libPath(curLibPath);
#if defined(LINUX) && defined(__x86_64__)
        libPath.Append(":/usr/lib64:/usr/lib");
#else
        libPath.Append(":/usr/lib");
#endif
        MAI_LOG_DEBUG(("Current Lib path=%s\n", libPath.get()));
        PR_FreeLibraryName(curLibPath);

        PRInt16 loc1 = 0, loc2 = 0;
        PRInt16 subLen = 0;
        while (loc2 >= 0) {
            loc2 = libPath.FindChar(':', loc1);
            if (loc2 < 0)
                subLen = libPath.Length() - loc1;
            else
                subLen = loc2 - loc1;
            nsCAutoString sub(Substring(libPath, loc1, subLen));
            sub.Append("/gtk-2.0/modules/");
            sub.Append(aModule.libName);
            aModule.lib = PR_LoadLibrary(sub.get());
            if (aModule.lib) {
                MAI_LOG_DEBUG(("Ok, load %s from %s\n", aModule.libName, sub.get()));
                break;
            }
            loc1 = loc2+1;
        }
        if (!aModule.lib) {
            MAI_LOG_DEBUG(("Fail to load %s\n", aModule.libName));
            return NS_ERROR_FAILURE;
        }
    }

    //we have loaded the library, try to get the function ptrs
    if (!(aModule.init = PR_FindFunctionSymbol(aModule.lib,
                                               aModule.initName)) ||
        !(aModule.shutdown = PR_FindFunctionSymbol(aModule.lib,
                                                   aModule.shutdownName))) {

        //fail, :(
        MAI_LOG_DEBUG(("Fail to find symbol %s in %s",
                       aModule.init ? aModule.shutdownName : aModule.initName,
                       aModule.libName));
        PR_UnloadLibrary(aModule.lib);
        aModule.lib = NULL;
        return NS_ERROR_FAILURE;
    }
    return NS_OK;
}
NS_IMETHODIMP
nsApplicationAccessibleWrap::Init()
{
    // XXX following code is copied from widget/src/gtk2/nsWindow.cpp
    // we should put it to somewhere that can be used from both modules
    // see bug 390761

    // check if accessibility enabled/disabled by environment variable
    PRBool isGnomeATEnabled = PR_FALSE;
    const char *envValue = PR_GetEnv(sAccEnv);
    if (envValue) {
        isGnomeATEnabled = !!atoi(envValue);
    } else {
        //check gconf-2 setting
        nsresult rv;
        nsCOMPtr<nsIPrefBranch> sysPrefService =
            do_GetService(sSysPrefService, &rv);
        if (NS_SUCCEEDED(rv) && sysPrefService) {
            sysPrefService->GetBoolPref(sAccessibilityKey, &isGnomeATEnabled);
        }
    }

    if (isGnomeATEnabled) {
        // load and initialize gail library
        nsresult rv = LoadGtkModule(sGail);
        if (NS_SUCCEEDED(rv)) {
            (*sGail.init)();
        }
        else {
            MAI_LOG_DEBUG(("Fail to load lib: %s\n", sGail.libName));
        }

        MAI_LOG_DEBUG(("Mozilla Atk Implementation initializing\n"));
        // Initialize the MAI Utility class
        // it will overwrite gail_util
        g_type_class_unref(g_type_class_ref(MAI_TYPE_UTIL));

        // Init atk-bridge now
        PR_SetEnv("NO_AT_BRIDGE=0");

        // load and initialize atk-bridge library
        rv = LoadGtkModule(sAtkBridge);
        if (NS_SUCCEEDED(rv)) {
            // init atk-bridge
            (*sAtkBridge.init)();
        }
        else
            MAI_LOG_DEBUG(("Fail to load lib: %s\n", sAtkBridge.libName));
    }

    return nsApplicationAccessible::Init();
}
nsresult
nsAccessibleWrap::FireAtkTextChangedEvent(nsIAccessibleEvent *aEvent,
        AtkObject *aObject)
{
    MAI_LOG_DEBUG(("\n\nReceived: EVENT_TEXT_REMOVED/INSERTED\n"));

    nsCOMPtr<nsIAccessibleTextChangeEvent> event =
        do_QueryInterface(aEvent);
    NS_ENSURE_TRUE(event, NS_ERROR_FAILURE);

    PRInt32 start = 0;
    event->GetStart(&start);

    PRUint32 length = 0;
    event->GetLength(&length);

    PRBool isInserted;
    event->IsInserted(&isInserted);

    PRBool isFromUserInput;
    event->GetIsFromUserInput(&isFromUserInput);

    char *signal_name = g_strconcat(isInserted ? "text_changed::insert" : "text_changed::delete",
                                    isFromUserInput ? "" : kNonUserInputEvent, NULL);
    g_signal_emit_by_name(aObject, signal_name, start, length);
    g_free (signal_name);

    return NS_OK;
}
void
insertTextCB(AtkEditableText *aText,
             const gchar *aString, gint aLength, gint *aPosition)
{
    nsAccessibleWrap *accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
    if (!accWrap)
        return;

    nsCOMPtr<nsIAccessibleEditableText> accText;
    accWrap->QueryInterface(NS_GET_IID(nsIAccessibleEditableText),
                            getter_AddRefs(accText));
    if (!accText)
        return;

    NS_ConvertUTF8toUTF16 strContent(aString);

    // interface changed in nsIAccessibleEditableText.idl ???
    //
    // PRInt32 pos = *aPosition;
    // nsresult rv = accText->InsertText(strContent, aLength, &pos);
    // *aPosition = pos;

    accText->InsertText(strContent, *aPosition);

    MAI_LOG_DEBUG(("EditableText: insert aString=%s, aLength=%d, aPosition=%d",
                   aString, aLength, *aPosition));
}
void
initializeCB(AtkObject *aAtkObj, gpointer aData)
{
    NS_ASSERTION((IS_MAI_OBJECT(aAtkObj)), "Invalid AtkObject");
    NS_ASSERTION(aData, "Invalid Data to init AtkObject");
    if (!aAtkObj || !aData)
        return;

    /* call parent init function */
    /* AtkObjectClass has not a "initialize" function now,
     * maybe it has later
     */

    if (ATK_OBJECT_CLASS(parent_class)->initialize)
        ATK_OBJECT_CLASS(parent_class)->initialize(aAtkObj, aData);

    /* initialize object */
    MAI_ATK_OBJECT(aAtkObj)->accWrap =
        static_cast<nsAccessibleWrap*>(aData);

#ifdef MAI_LOGGING
    ++sMaiAtkObjCreated;
#endif
    MAI_LOG_DEBUG(("MaiAtkObj Create obj=%p for AccWrap=%p, all=%d, left=%d\n",
                   (void*)aAtkObj, (void*)aData, sMaiAtkObjCreated,
                   (sMaiAtkObjCreated-sMaiAtkObjDeleted)));
}
Exemple #7
0
nsresult
nsAccessibleWrap::FireAtkStateChangeEvent(AccEvent* aEvent,
                                          AtkObject *aObject)
{
    MAI_LOG_DEBUG(("\n\nReceived: EVENT_STATE_CHANGE\n"));

    AccStateChangeEvent* event = downcast_accEvent(aEvent);
    NS_ENSURE_TRUE(event, NS_ERROR_FAILURE);

    PRUint32 state = event->GetState();
    PRBool isExtra = event->IsExtraState();
    PRBool isEnabled = event->IsStateEnabled();

    PRInt32 stateIndex = AtkStateMap::GetStateIndexFor(state);
    if (stateIndex >= 0) {
        const AtkStateMap *atkStateMap = isExtra ? gAtkStateMapExt : gAtkStateMap;
        NS_ASSERTION(atkStateMap[stateIndex].stateMapEntryType != kNoSuchState,
                     "No such state");

        if (atkStateMap[stateIndex].atkState != kNone) {
            NS_ASSERTION(atkStateMap[stateIndex].stateMapEntryType != kNoStateChange,
                         "State changes should not fired for this state");

            if (atkStateMap[stateIndex].stateMapEntryType == kMapOpposite)
                isEnabled = !isEnabled;

            // Fire state change for first state if there is one to map
            atk_object_notify_state_change(aObject,
                                           atkStateMap[stateIndex].atkState,
                                           isEnabled);
        }
    }

    return NS_OK;
}
nsAccessibleWrap::~nsAccessibleWrap()
{
    NS_ASSERTION(!mAtkObject, "ShutdownAtkObject() is not called");

#ifdef MAI_LOGGING
    ++mAccWrapDeleted;
#endif
    MAI_LOG_DEBUG(("==nsAccessibleWrap deleting: this=%p,total=%d left=%d\n",
                   (void*)this, mAccWrapDeleted,
                   (mAccWrapCreated-mAccWrapDeleted)));
}
Exemple #9
0
nsAccessibleWrap::
    nsAccessibleWrap(nsIContent *aContent, nsIWeakReference *aShell) :
    nsAccessible(aContent, aShell), mAtkObject(nsnull)
{
#ifdef MAI_LOGGING
    ++mAccWrapCreated;
#endif
    MAI_LOG_DEBUG(("==nsAccessibleWrap creating: this=%p,total=%d left=%d\n",
                   (void*)this, mAccWrapCreated,
                  (mAccWrapCreated-mAccWrapDeleted)));
}
Exemple #10
0
nsresult
nsAccessibleWrap::FireAtkShowHideEvent(AccEvent* aEvent,
                                       AtkObject *aObject, PRBool aIsAdded)
{
    if (aIsAdded)
        MAI_LOG_DEBUG(("\n\nReceived: Show event\n"));
    else
        MAI_LOG_DEBUG(("\n\nReceived: Hide event\n"));

    PRInt32 indexInParent = getIndexInParentCB(aObject);
    AtkObject *parentObject = getParentCB(aObject);
    NS_ENSURE_STATE(parentObject);

    PRBool isFromUserInput = aEvent->IsFromUserInput();
    char *signal_name = g_strconcat(aIsAdded ? "children_changed::add" :  "children_changed::remove",
                                    isFromUserInput ? "" : kNonUserInputEvent, NULL);
    g_signal_emit_by_name(parentObject, signal_name, indexInParent, aObject, NULL);
    g_free(signal_name);

    return NS_OK;
}
static void
pasteTextCB(AtkEditableText *aText, gint aPosition)
{
  AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
  if (!accWrap)
    return;

  HyperTextAccessible* text = accWrap->AsHyperText();
  if (!text || !text->IsTextRole())
    return;

  MAI_LOG_DEBUG(("EditableText: pasteTextCB, aPosition=%d", aPosition));
  text->PasteText(aPosition);
}
Exemple #12
0
nsAccessibleWrap::nsAccessibleWrap(nsIDOMNode* aNode,
                                   nsIWeakReference *aShell)
    : nsAccessible(aNode, aShell),
      mMaiAtkObject(nsnull),
      mInterfaces(nsnull),
      mInterfaceCount(0)
{
#ifdef MAI_LOGGING
    ++mAccWrapCreated;
#endif
    MAI_LOG_DEBUG(("==nsAccessibleWrap creating: this=%p,total=%d left=%d\n",
                   (void*)this, mAccWrapCreated,
                  (mAccWrapCreated-mAccWrapDeleted)));
}
nsresult
nsApplicationAccessibleWrap::RemoveRootAccessible(nsIAccessible *aRootAccWrap)
{
    NS_ENSURE_ARG_POINTER(aRootAccWrap);

    PRUint32 index = 0;
    nsresult rv = NS_ERROR_FAILURE;

    // we must use weak ref to get the index
    nsCOMPtr<nsIWeakReference> weakPtr = do_GetWeakReference(aRootAccWrap);
    rv = mChildren->IndexOf(0, weakPtr, &index);

    AtkObject *atkAccessible = nsAccessibleWrap::GetAtkObject(aRootAccWrap);
    atk_object_set_parent(atkAccessible, NULL);
    g_signal_emit_by_name(mAtkObject, "children_changed::remove", index,
                          atkAccessible, NULL);

#ifdef MAI_LOGGING
    PRUint32 count = 0;
    mChildren->GetLength(&count);

    if (NS_SUCCEEDED(rv)) {
        rv = mChildren->RemoveElementAt(index);
        MAI_LOG_DEBUG(("\nRemove RootAcc=%p, count=%d\n",
                       (void*)aRootAccWrap, (count-1)));
    }
    else
        MAI_LOG_DEBUG(("\nFail to Remove RootAcc=%p, count=%d\n",
                       (void*)aRootAccWrap, count));
#else
    NS_ENSURE_SUCCESS(rv, rv);
    rv = mChildren->RemoveElementAt(index);

#endif
    InvalidateChildren();
    return rv;
}
static void
deleteTextCB(AtkEditableText *aText, gint aStartPos, gint aEndPos)
{
  AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
  if (!accWrap)
    return;

  HyperTextAccessible* text = accWrap->AsHyperText();
  if (!text || !text->IsTextRole())
    return;

  MAI_LOG_DEBUG(("EditableText: deleteTextCB, aStartPos=%d, aEndPos=%d",
                 aStartPos, aEndPos));
  text->DeleteText(aStartPos, aEndPos);
}
static void
setTextContentsCB(AtkEditableText *aText, const gchar *aString)
{
  AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
  if (!accWrap)
    return;

  HyperTextAccessible* text = accWrap->AsHyperText();
  if (!text || !text->IsTextRole())
    return;

  MAI_LOG_DEBUG(("EditableText: setTextContentsCB, aString=%s", aString));

  NS_ConvertUTF8toUTF16 strContent(aString);
  text->SetTextContents(strContent);
}
static const char *
GetUniqueMaiAtkTypeName(PRUint16 interfacesBits)
{
#define MAI_ATK_TYPE_NAME_LEN (30)     /* 10+sizeof(PRUint16)*8/4+1 < 30 */

    static gchar namePrefix[] = "MaiAtkType";   /* size = 10 */
    static gchar name[MAI_ATK_TYPE_NAME_LEN + 1];

    PR_snprintf(name, MAI_ATK_TYPE_NAME_LEN, "%s%x", namePrefix,
                interfacesBits);
    name[MAI_ATK_TYPE_NAME_LEN] = '\0';

    MAI_LOG_DEBUG(("MaiWidget::LastedTypeName=%s\n", name));

    return name;
}
void
cutTextCB(AtkEditableText *aText, gint aStartPos, gint aEndPos)
{
    nsAccessibleWrap *accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
    if (!accWrap)
        return;

    nsCOMPtr<nsIAccessibleEditableText> accText;
    accWrap->QueryInterface(NS_GET_IID(nsIAccessibleEditableText),
                            getter_AddRefs(accText));
    if (!accText)
        return;
    MAI_LOG_DEBUG(("EditableText: cutTextCB, aStartPos=%d, aEndPos=%d",
                   aStartPos, aEndPos));
    accText->CutText(aStartPos, aEndPos);
}
void
pasteTextCB(AtkEditableText *aText, gint aPosition)
{
    nsAccessibleWrap *accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
    if (!accWrap)
        return;

    nsCOMPtr<nsIAccessibleEditableText> accText;
    accWrap->QueryInterface(NS_GET_IID(nsIAccessibleEditableText),
                            getter_AddRefs(accText));
    if (!accText)
        return;

    MAI_LOG_DEBUG(("EditableText: pasteTextCB, aPosition=%d", aPosition));
    accText->PasteText(aPosition);
}
void
setTextContentsCB(AtkEditableText *aText, const gchar *aString)
{
    nsAccessibleWrap *accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
    if (!accWrap)
        return;

    nsCOMPtr<nsIAccessibleEditableText> accText;
    accWrap->QueryInterface(NS_GET_IID(nsIAccessibleEditableText),
                            getter_AddRefs(accText));
    if (!accText)
        return;

    MAI_LOG_DEBUG(("EditableText: setTextContentsCB, aString=%s", aString));

    NS_ConvertUTF8toUTF16 strContent(aString);
    accText->SetTextContents(strContent);
}
static void
insertTextCB(AtkEditableText *aText,
             const gchar *aString, gint aLength, gint *aPosition)
{
  AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
  if (!accWrap)
    return;

  HyperTextAccessible* text = accWrap->AsHyperText();
  if (!text || !text->IsTextRole())
    return;

  NS_ConvertUTF8toUTF16 strContent(aString, aLength);
  text->InsertText(strContent, *aPosition);

  MAI_LOG_DEBUG(("EditableText: insert aString=%s, aLength=%d, aPosition=%d",
                 aString, aLength, *aPosition));
}
void
finalizeCB(GObject *aObj)
{
    if (!IS_MAI_OBJECT(aObj))
        return;
    NS_ASSERTION(MAI_ATK_OBJECT(aObj)->accWrap == nsnull, "AccWrap NOT null");

#ifdef MAI_LOGGING
    ++sMaiAtkObjDeleted;
#endif
    MAI_LOG_DEBUG(("MaiAtkObj Delete obj=%p, all=%d, left=%d\n",
                   (void*)aObj, sMaiAtkObjCreated,
                   (sMaiAtkObjCreated-sMaiAtkObjDeleted)));

    // call parent finalize function
    // finalize of GObjectClass will unref the accessible parent if has
    if (G_OBJECT_CLASS (parent_class)->finalize)
        G_OBJECT_CLASS (parent_class)->finalize(aObj);
}
Exemple #22
0
nsAccessibleWrap::~nsAccessibleWrap()
{

#ifdef MAI_LOGGING
    ++mAccWrapDeleted;
#endif
    MAI_LOG_DEBUG(("==nsAccessibleWrap deleting: this=%p,total=%d left=%d\n",
                   (void*)this, mAccWrapDeleted,
                   (mAccWrapCreated-mAccWrapDeleted)));

    if (mMaiAtkObject) {
        MAI_ATK_OBJECT(mMaiAtkObject)->accWrap = nsnull;
        g_object_unref(mMaiAtkObject);
    }
    if (mInterfaces) {
        for (int index = 0; index < MAI_INTERFACE_NUM; ++index)
            delete mInterfaces[index];
        delete [] mInterfaces;
    }
}
Exemple #23
0
nsresult
nsAccessibleWrap::FireAtkTextChangedEvent(AccEvent* aEvent,
                                          AtkObject *aObject)
{
    MAI_LOG_DEBUG(("\n\nReceived: EVENT_TEXT_REMOVED/INSERTED\n"));

    AccTextChangeEvent* event = downcast_accEvent(aEvent);
    NS_ENSURE_TRUE(event, NS_ERROR_FAILURE);

    PRInt32 start = event->GetStartOffset();
    PRUint32 length = event->GetLength();
    PRBool isInserted = event->IsTextInserted();

    PRBool isFromUserInput = aEvent->IsFromUserInput();

    char *signal_name = g_strconcat(isInserted ? "text_changed::insert" : "text_changed::delete",
                                    isFromUserInput ? "" : kNonUserInputEvent, NULL);
    g_signal_emit_by_name(aObject, signal_name, start, length);
    g_free (signal_name);

    return NS_OK;
}
static AtkKeyEventStruct *
atk_key_event_from_gdk_event_key (GdkEventKey *key)
{
    AtkKeyEventStruct *event = g_new0(AtkKeyEventStruct, 1);
    switch (key->type) {
    case GDK_KEY_PRESS:
        event->type = ATK_KEY_EVENT_PRESS;
        break;
    case GDK_KEY_RELEASE:
        event->type = ATK_KEY_EVENT_RELEASE;
        break;
    default:
        g_assert_not_reached ();
        return NULL;
    }
    event->state = key->state;
    event->keyval = key->keyval;
    event->length = key->length;
    if (key->string && key->string [0] && 
        (key->state & GDK_CONTROL_MASK ||
         g_unichar_isgraph (g_utf8_get_char (key->string)))) {
        event->string = key->string;
    }
    else if (key->type == GDK_KEY_PRESS ||
             key->type == GDK_KEY_RELEASE) {
        event->string = gdk_keyval_name (key->keyval);	    
    }
    event->keycode = key->hardware_keycode;
    event->timestamp = key->time;

    MAI_LOG_DEBUG(("MaiKey:\tsym %u\n\tmods %x\n\tcode %u\n\ttime %lx\n",
                   (unsigned int) event->keyval,
                   (unsigned int) event->state,
                   (unsigned int) event->keycode,
                   (unsigned long int) event->timestamp));
    return event;
}
nsApplicationAccessibleWrap::~nsApplicationAccessibleWrap()
{
    MAI_LOG_DEBUG(("======Destory AppRootAcc=%p\n", (void*)this));
    nsAccessibleWrap::ShutdownAtkObject();
}
nsApplicationAccessibleWrap::nsApplicationAccessibleWrap():
    nsApplicationAccessible()
{
    MAI_LOG_DEBUG(("======Create AppRootAcc=%p\n", (void*)this));
}
nsresult
nsAccessibleWrap::FirePlatformEvent(nsIAccessibleEvent *aEvent)
{
    nsCOMPtr<nsIAccessible> accessible;
    aEvent->GetAccessible(getter_AddRefs(accessible));
    NS_ENSURE_TRUE(accessible, NS_ERROR_FAILURE);

    PRUint32 type = 0;
    nsresult rv = aEvent->GetEventType(&type);
    NS_ENSURE_SUCCESS(rv, rv);

    AtkObject *atkObj = nsAccessibleWrap::GetAtkObject(accessible);

    // We don't create ATK objects for nsIAccessible plain text leaves,
    // just return NS_OK in such case
    if (!atkObj) {
        NS_ASSERTION(type == nsIAccessibleEvent::EVENT_ASYNCH_SHOW ||
                     type == nsIAccessibleEvent::EVENT_ASYNCH_HIDE ||
                     type == nsIAccessibleEvent::EVENT_DOM_CREATE ||
                     type == nsIAccessibleEvent::EVENT_DOM_DESTROY,
                     "Event other than SHOW and HIDE fired for plain text leaves");
        return NS_OK;
    }

    nsAccessibleWrap *accWrap = GetAccessibleWrap(atkObj);
    if (!accWrap) {
        return NS_OK; // Node is shut down
    }

    switch (type) {
    case nsIAccessibleEvent::EVENT_STATE_CHANGE:
        return FireAtkStateChangeEvent(aEvent, atkObj);

    case nsIAccessibleEvent::EVENT_TEXT_REMOVED:
    case nsIAccessibleEvent::EVENT_TEXT_INSERTED:
        return FireAtkTextChangedEvent(aEvent, atkObj);

    case nsIAccessibleEvent::EVENT_FOCUS:
    {
        MAI_LOG_DEBUG(("\n\nReceived: EVENT_FOCUS\n"));
        nsRefPtr<nsRootAccessible> rootAccWrap = accWrap->GetRootAccessible();
        if (rootAccWrap && rootAccWrap->mActivated) {
            atk_focus_tracker_notify(atkObj);
            // Fire state change event for focus
            nsCOMPtr<nsIAccessibleStateChangeEvent> stateChangeEvent =
                new nsAccStateChangeEvent(accessible,
                                          nsIAccessibleStates::STATE_FOCUSED,
                                          PR_FALSE, PR_TRUE);
            return FireAtkStateChangeEvent(stateChangeEvent, atkObj);
        }
    }
    break;

    case nsIAccessibleEvent::EVENT_VALUE_CHANGE:
    {
        MAI_LOG_DEBUG(("\n\nReceived: EVENT_VALUE_CHANGE\n"));
        nsCOMPtr<nsIAccessibleValue> value(do_QueryInterface(accessible));
        if (value) {    // Make sure this is a numeric value
            // Don't fire for MSAA string value changes (e.g. text editing)
            // ATK values are always numeric
            g_object_notify( (GObject*)atkObj, "accessible-value" );
        }
    }
    break;

    case nsIAccessibleEvent::EVENT_SELECTION_CHANGED:
        MAI_LOG_DEBUG(("\n\nReceived: EVENT_SELECTION_CHANGED\n"));
        g_signal_emit_by_name(atkObj, "selection_changed");
        break;

    case nsIAccessibleEvent::EVENT_TEXT_SELECTION_CHANGED:
        MAI_LOG_DEBUG(("\n\nReceived: EVENT_TEXT_SELECTION_CHANGED\n"));
        g_signal_emit_by_name(atkObj, "text_selection_changed");
        break;

    case nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED:
    {
        MAI_LOG_DEBUG(("\n\nReceived: EVENT_TEXT_CARET_MOVED\n"));

        nsCOMPtr<nsIAccessibleCaretMoveEvent> caretMoveEvent(do_QueryInterface(aEvent));
        NS_ASSERTION(caretMoveEvent, "Event needs event data");
        if (!caretMoveEvent)
            break;

        PRInt32 caretOffset = -1;
        caretMoveEvent->GetCaretOffset(&caretOffset);

        MAI_LOG_DEBUG(("\n\nCaret postion: %d", caretOffset));
        g_signal_emit_by_name(atkObj,
                              "text_caret_moved",
                              // Curent caret position
                              caretOffset);
    }
    break;

    case nsIAccessibleEvent::EVENT_TEXT_ATTRIBUTE_CHANGED:
        MAI_LOG_DEBUG(("\n\nReceived: EVENT_TEXT_ATTRIBUTE_CHANGED\n"));

        g_signal_emit_by_name(atkObj,
                              "text-attributes-changed");
        break;

    case nsIAccessibleEvent::EVENT_TABLE_MODEL_CHANGED:
        MAI_LOG_DEBUG(("\n\nReceived: EVENT_TABLE_MODEL_CHANGED\n"));
        g_signal_emit_by_name(atkObj, "model_changed");
        break;

    case nsIAccessibleEvent::EVENT_TABLE_ROW_INSERT:
    {
        MAI_LOG_DEBUG(("\n\nReceived: EVENT_TABLE_ROW_INSERT\n"));
        nsCOMPtr<nsIAccessibleTableChangeEvent> tableEvent = do_QueryInterface(aEvent);
        NS_ENSURE_TRUE(tableEvent, NS_ERROR_FAILURE);

        PRInt32 rowIndex, numRows;
        tableEvent->GetRowOrColIndex(&rowIndex);
        tableEvent->GetNumRowsOrCols(&numRows);

        g_signal_emit_by_name(atkObj,
                              "row_inserted",
                              // After which the rows are inserted
                              rowIndex,
                              // The number of the inserted
                              numRows);
    }
    break;

    case nsIAccessibleEvent::EVENT_TABLE_ROW_DELETE:
    {
        MAI_LOG_DEBUG(("\n\nReceived: EVENT_TABLE_ROW_DELETE\n"));
        nsCOMPtr<nsIAccessibleTableChangeEvent> tableEvent = do_QueryInterface(aEvent);
        NS_ENSURE_TRUE(tableEvent, NS_ERROR_FAILURE);

        PRInt32 rowIndex, numRows;
        tableEvent->GetRowOrColIndex(&rowIndex);
        tableEvent->GetNumRowsOrCols(&numRows);

        g_signal_emit_by_name(atkObj,
                              "row_deleted",
                              // After which the rows are deleted
                              rowIndex,
                              // The number of the deleted
                              numRows);
    }
    break;

    case nsIAccessibleEvent::EVENT_TABLE_ROW_REORDER:
    {
        MAI_LOG_DEBUG(("\n\nReceived: EVENT_TABLE_ROW_REORDER\n"));
        g_signal_emit_by_name(atkObj, "row_reordered");
        break;
    }

    case nsIAccessibleEvent::EVENT_TABLE_COLUMN_INSERT:
    {
        MAI_LOG_DEBUG(("\n\nReceived: EVENT_TABLE_COLUMN_INSERT\n"));
        nsCOMPtr<nsIAccessibleTableChangeEvent> tableEvent = do_QueryInterface(aEvent);
        NS_ENSURE_TRUE(tableEvent, NS_ERROR_FAILURE);

        PRInt32 colIndex, numCols;
        tableEvent->GetRowOrColIndex(&colIndex);
        tableEvent->GetNumRowsOrCols(&numCols);

        g_signal_emit_by_name(atkObj,
                              "column_inserted",
                              // After which the columns are inserted
                              colIndex,
                              // The number of the inserted
                              numCols);
    }
    break;

    case nsIAccessibleEvent::EVENT_TABLE_COLUMN_DELETE:
    {
        MAI_LOG_DEBUG(("\n\nReceived: EVENT_TABLE_COLUMN_DELETE\n"));
        nsCOMPtr<nsIAccessibleTableChangeEvent> tableEvent = do_QueryInterface(aEvent);
        NS_ENSURE_TRUE(tableEvent, NS_ERROR_FAILURE);

        PRInt32 colIndex, numCols;
        tableEvent->GetRowOrColIndex(&colIndex);
        tableEvent->GetNumRowsOrCols(&numCols);

        g_signal_emit_by_name(atkObj,
                              "column_deleted",
                              // After which the columns are deleted
                              colIndex,
                              // The number of the deleted
                              numCols);
    }
    break;

    case nsIAccessibleEvent::EVENT_TABLE_COLUMN_REORDER:
        MAI_LOG_DEBUG(("\n\nReceived: EVENT_TABLE_COLUMN_REORDER\n"));
        g_signal_emit_by_name(atkObj, "column_reordered");
        break;

    case nsIAccessibleEvent::EVENT_SECTION_CHANGED:
        MAI_LOG_DEBUG(("\n\nReceived: EVENT_SECTION_CHANGED\n"));
        g_signal_emit_by_name(atkObj, "visible_data_changed");
        break;

    case nsIAccessibleEvent::EVENT_DOM_CREATE:
    case nsIAccessibleEvent::EVENT_ASYNCH_SHOW:
        return FireAtkShowHideEvent(aEvent, atkObj, PR_TRUE);

    case nsIAccessibleEvent::EVENT_DOM_DESTROY:
    case nsIAccessibleEvent::EVENT_ASYNCH_HIDE:
        return FireAtkShowHideEvent(aEvent, atkObj, PR_FALSE);

    /*
     * Because dealing with menu is very different between nsIAccessible
     * and ATK, and the menu activity is important, specially transfer the
     * following two event.
     * Need more verification by AT test.
     */
    case nsIAccessibleEvent::EVENT_MENU_START:
        MAI_LOG_DEBUG(("\n\nReceived: EVENT_MENU_START\n"));
        break;

    case nsIAccessibleEvent::EVENT_MENU_END:
        MAI_LOG_DEBUG(("\n\nReceived: EVENT_MENU_END\n"));
        break;

    case nsIAccessibleEvent::EVENT_WINDOW_ACTIVATE:
    {
        MAI_LOG_DEBUG(("\n\nReceived: EVENT_WINDOW_ACTIVATED\n"));
        nsRootAccessible *rootAcc =
            static_cast<nsRootAccessible *>(accessible.get());
        rootAcc->mActivated = PR_TRUE;
        guint id = g_signal_lookup ("activate", MAI_TYPE_ATK_OBJECT);
        g_signal_emit(atkObj, id, 0);

        // Always fire a current focus event after activation.
        rootAcc->FireCurrentFocusEvent();
    }
    break;

    case nsIAccessibleEvent::EVENT_WINDOW_DEACTIVATE:
    {
        MAI_LOG_DEBUG(("\n\nReceived: EVENT_WINDOW_DEACTIVATED\n"));
        nsRootAccessible *rootAcc =
            static_cast<nsRootAccessible *>(accessible.get());
        rootAcc->mActivated = PR_FALSE;
        guint id = g_signal_lookup ("deactivate", MAI_TYPE_ATK_OBJECT);
        g_signal_emit(atkObj, id, 0);
    }
    break;

    case nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE:
    {
        MAI_LOG_DEBUG(("\n\nReceived: EVENT_DOCUMENT_LOAD_COMPLETE\n"));
        g_signal_emit_by_name (atkObj, "load_complete");
    }
    break;

    case nsIAccessibleEvent::EVENT_DOCUMENT_RELOAD:
    {
        MAI_LOG_DEBUG(("\n\nReceived: EVENT_DOCUMENT_RELOAD\n"));
        g_signal_emit_by_name (atkObj, "reload");
    }
    break;

    case nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_STOPPED:
    {
        MAI_LOG_DEBUG(("\n\nReceived: EVENT_DOCUMENT_LOAD_STOPPED\n"));
        g_signal_emit_by_name (atkObj, "load_stopped");
    }
    break;

    case nsIAccessibleEvent::EVENT_MENUPOPUP_START:
        MAI_LOG_DEBUG(("\n\nReceived: EVENT_MENUPOPUP_START\n"));
        atk_focus_tracker_notify(atkObj); // fire extra focus event
        atk_object_notify_state_change(atkObj, ATK_STATE_VISIBLE, PR_TRUE);
        atk_object_notify_state_change(atkObj, ATK_STATE_SHOWING, PR_TRUE);
        break;

    case nsIAccessibleEvent::EVENT_MENUPOPUP_END:
        MAI_LOG_DEBUG(("\n\nReceived: EVENT_MENUPOPUP_END\n"));
        atk_object_notify_state_change(atkObj, ATK_STATE_VISIBLE, PR_FALSE);
        atk_object_notify_state_change(atkObj, ATK_STATE_SHOWING, PR_FALSE);
        break;
    }

    return NS_OK;
}