示例#1
0
static gboolean axObjectEventListener(GSignalInvocationHint *signalHint, guint numParamValues, const GValue *paramValues, gpointer data)
{
    // At least we should receive the instance emitting the signal.
    if (numParamValues < 1)
        return TRUE;

    AtkObject* accessible = ATK_OBJECT(g_value_get_object(&paramValues[0]));
    if (!accessible || !ATK_IS_OBJECT(accessible))
        return TRUE;

    GSignalQuery signalQuery;
    GOwnPtr<gchar> signalName;
    GOwnPtr<gchar> signalValue;
    String notificationName;

    g_signal_query(signalHint->signal_id, &signalQuery);

    if (!g_strcmp0(signalQuery.signal_name, "state-change")) {
        signalName.set(g_strdup_printf("state-change:%s", g_value_get_string(&paramValues[1])));
        signalValue.set(g_strdup_printf("%d", g_value_get_boolean(&paramValues[2])));
        if (!g_strcmp0(g_value_get_string(&paramValues[1]), "checked"))
            notificationName = "CheckedStateChanged";
    } else if (!g_strcmp0(signalQuery.signal_name, "focus-event")) {
        signalName.set(g_strdup("focus-event"));
        signalValue.set(g_strdup_printf("%d", g_value_get_boolean(&paramValues[1])));
        notificationName = "AXFocusedUIElementChanged";
    } else if (!g_strcmp0(signalQuery.signal_name, "children-changed")) {
        signalName.set(g_strdup("children-changed"));
        signalValue.set(g_strdup_printf("%d", g_value_get_uint(&paramValues[1])));
    } else if (!g_strcmp0(signalQuery.signal_name, "property-change"))
        signalName.set(g_strdup_printf("property-change:%s", g_quark_to_string(signalHint->detail)));
    else
        signalName.set(g_strdup(signalQuery.signal_name));

    if (loggingAccessibilityEvents)
        printAccessibilityEvent(accessible, signalName.get(), signalValue.get());

#if PLATFORM(GTK)
    JSGlobalContextRef jsContext = webkit_web_frame_get_global_context(mainFrame);
#else
    JSContextRef jsContext = 0;
#endif
    if (!jsContext)
        return TRUE;

    if (notificationName.length()) {
        for (HashMap<PlatformUIElement, AccessibilityNotificationHandler*>::iterator it = notificationHandlers.begin(); it != notificationHandlers.end(); ++it) {
            if (it->key == accessible || it->key == GlobalNotificationKey) {
                JSRetainPtr<JSStringRef> jsNotificationEventName(Adopt, JSStringCreateWithUTF8CString(reinterpret_cast<const char*>(notificationName.utf8().data())));
                JSValueRef notificationNameArgument = JSValueMakeString(jsContext, jsNotificationEventName.get());
                AccessibilityNotificationHandler* notificationHandler = it->value;
                if (notificationHandler->platformElement()) {
                    JSValueRef argument = notificationNameArgument;
                    // Listener for one element just gets one argument, the notification name.
                    JSObjectCallAsFunction(jsContext, notificationHandler->notificationFunctionCallback(), 0, 1, &argument, 0);
                } else {
                    // A global listener gets the element and the notification name as arguments.
                    JSValueRef arguments[2];
                    arguments[0] = AccessibilityUIElement::makeJSAccessibilityUIElement(jsContext, AccessibilityUIElement(accessible));
                    arguments[1] = notificationNameArgument;
                    JSObjectCallAsFunction(jsContext, notificationHandler->notificationFunctionCallback(), 0, 2, arguments, 0);
                }
            }
        }
    }

    return TRUE;
}
static gboolean axObjectEventListener(GSignalInvocationHint *signalHint, guint numParamValues, const GValue *paramValues, gpointer data)
{
    // At least we should receive the instance emitting the signal.
    if (numParamValues < 1)
        return true;

    AtkObject* accessible = ATK_OBJECT(g_value_get_object(&paramValues[0]));
    if (!accessible || !ATK_IS_OBJECT(accessible))
        return true;

    GSignalQuery signalQuery;
    GUniquePtr<gchar> signalName;
    GUniquePtr<gchar> signalValue;
    String notificationName;

    g_signal_query(signalHint->signal_id, &signalQuery);

    if (!g_strcmp0(signalQuery.signal_name, "state-change")) {
        signalName.reset(g_strdup_printf("state-change:%s", g_value_get_string(&paramValues[1])));
        signalValue.reset(g_strdup_printf("%d", g_value_get_boolean(&paramValues[2])));
        if (!g_strcmp0(g_value_get_string(&paramValues[1]), "checked"))
            notificationName = "CheckedStateChanged";
        else if (!g_strcmp0(g_value_get_string(&paramValues[1]), "invalid-entry"))
            notificationName = "AXInvalidStatusChanged";
    } else if (!g_strcmp0(signalQuery.signal_name, "focus-event")) {
        signalName.reset(g_strdup("focus-event"));
        signalValue.reset(g_strdup_printf("%d", g_value_get_boolean(&paramValues[1])));
        if (g_value_get_boolean(&paramValues[1]))
            notificationName = "AXFocusedUIElementChanged";
    } else if (!g_strcmp0(signalQuery.signal_name, "children-changed")) {
        const gchar* childrenChangedDetail = g_quark_to_string(signalHint->detail);
        signalName.reset(g_strdup_printf("children-changed:%s", childrenChangedDetail));
        signalValue.reset(g_strdup_printf("%d", g_value_get_uint(&paramValues[1])));
        notificationName = !g_strcmp0(childrenChangedDetail, "add") ? "AXChildrenAdded" : "AXChildrenRemoved";
    } else if (!g_strcmp0(signalQuery.signal_name, "property-change")) {
        signalName.reset(g_strdup_printf("property-change:%s", g_quark_to_string(signalHint->detail)));
        if (!g_strcmp0(g_quark_to_string(signalHint->detail), "accessible-value"))
            notificationName = "AXValueChanged";
    } else if (!g_strcmp0(signalQuery.signal_name, "load-complete"))
        notificationName = "AXLoadComplete";
    else
        signalName.reset(g_strdup(signalQuery.signal_name));

    if (loggingAccessibilityEvents)
        printAccessibilityEvent(accessible, signalName.get(), signalValue.get());

#if PLATFORM(GTK)
    JSGlobalContextRef jsContext = webkit_web_frame_get_global_context(mainFrame);
#elif PLATFORM(EFL)
    JSGlobalContextRef jsContext = DumpRenderTreeSupportEfl::globalContextRefForFrame(browser->mainFrame());
#else
    JSContextRef jsContext = 0;
#endif
    if (!jsContext)
        return true;

    if (notificationName.length()) {
        JSRetainPtr<JSStringRef> jsNotificationEventName(Adopt, JSStringCreateWithUTF8CString(notificationName.utf8().data()));
        JSValueRef notificationNameArgument = JSValueMakeString(jsContext, jsNotificationEventName.get());
        NotificationHandlersMap::iterator elementNotificationHandler = notificationHandlers.find(accessible);
        if (elementNotificationHandler != notificationHandlers.end()) {
            // Listener for one element just gets one argument, the notification name.
            JSObjectCallAsFunction(jsContext, elementNotificationHandler->value->notificationFunctionCallback(), 0, 1, &notificationNameArgument, 0);
        }

        if (globalNotificationHandler) {
            // A global listener gets the element and the notification name as arguments.
            JSValueRef arguments[2];
            arguments[0] = AccessibilityUIElement::makeJSAccessibilityUIElement(jsContext, AccessibilityUIElement(accessible));
            arguments[1] = notificationNameArgument;
            JSObjectCallAsFunction(jsContext, globalNotificationHandler->notificationFunctionCallback(), 0, 2, arguments, 0);
        }
    }

    return true;
}