示例#1
0
static void*
FcitxNotifyCreate(FcitxInstance *instance)
{
    FcitxNotify *notify = fcitx_utils_new(FcitxNotify);
    notify->owner = instance;
    notify->notify_counter = 1;
    notify->conn = FcitxDBusGetConnection(notify->owner);
    if (fcitx_unlikely(!notify->conn))
        goto connect_error;

    DBusError err;
    dbus_error_init(&err);

    dbus_bus_add_match(notify->conn, NOTIFICATIONS_MATCH_ACTION, &err);
    if (fcitx_unlikely(dbus_error_is_set(&err)))
        goto filter_error;

    dbus_bus_add_match(notify->conn, NOTIFICATIONS_MATCH_CLOSED, &err);
    if (fcitx_unlikely(dbus_error_is_set(&err)))
        goto filter_error;

    if (fcitx_unlikely(!dbus_connection_add_filter(notify->conn,
                                                   FcitxNotifyDBusFilter,
                                                   notify, NULL)))
        goto filter_error;
    dbus_error_free(&err);

    notify->hide_notify = fcitx_string_map_new(NULL, '\0');
    fcitx_desktop_file_init(&notify->dconfig, NULL, NULL);
    FcitxNotifyLoadDConfig(notify);

    FcitxDBusWatchName(instance, NOTIFICATIONS_SERVICE_NAME, notify, FcitxNotifyOwnerChanged, NULL, NULL);
    FcitxNotifyGetCapabilities(notify);
    FcitxFreeDesktopNotifyAddFunctions(instance);

    return notify;
filter_error:
    dbus_bus_remove_match(notify->conn, NOTIFICATIONS_MATCH_ACTION, NULL);
    dbus_bus_remove_match(notify->conn, NOTIFICATIONS_MATCH_CLOSED, NULL);
    dbus_error_free(&err);
connect_error:
    free(notify);
    return NULL;
}
示例#2
0
void* FcitxNotificationItemCreate(FcitxInstance* instance)
{
    FcitxNotificationItem* notificationitem = fcitx_utils_new(FcitxNotificationItem);
    notificationitem->owner = instance;
    DBusError err;
    dbus_error_init(&err);
    do {
        DBusConnection *conn = FcitxDBusGetConnection(instance);
        if (conn == NULL) {
            FcitxLog(ERROR, "DBus Not initialized");
            break;
        }

        notificationitem->conn = conn;

        DBusObjectPathVTable fcitxIPCVTable = {NULL, &FcitxNotificationItemEventHandler, NULL, NULL, NULL, NULL };
        if (!dbus_connection_register_object_path(notificationitem->conn, NOTIFICATION_ITEM_DEFAULT_OBJ, &fcitxIPCVTable, notificationitem)) {
            FcitxLog(ERROR, "No memory");
            break;
        }

        if (!FcitxDBusMenuCreate(notificationitem)) {
            FcitxLog(ERROR, "No memory");
            break;
        }


        int id = FcitxDBusWatchName(instance,
                                    NOTIFICATION_WATCHER_DBUS_ADDR,
                                    notificationitem,
                                    FcitxNotificationItemOwnerChanged,
                                    NULL,
                                    NULL);

        if (id == 0) {
            break;
        }

        const char* notificationWatcher = NOTIFICATION_WATCHER_DBUS_ADDR;
        DBusMessage* message = dbus_message_new_method_call(DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, "NameHasOwner");
        dbus_message_append_args(message, DBUS_TYPE_STRING, &notificationWatcher, DBUS_TYPE_INVALID);

        DBusPendingCall* call = NULL;
        dbus_bool_t reply =
            dbus_connection_send_with_reply(notificationitem->conn, message,
                                            &call, DBUS_TIMEOUT_USE_DEFAULT);
        if (reply == TRUE) {
            dbus_pending_call_set_notify(call,
                                         NotificationWatcherServiceExistCallback,
                                         notificationitem,
                                         NULL);
            dbus_pending_call_unref(call);
        }
        dbus_connection_flush(notificationitem->conn);
        dbus_message_unref(message);

        FcitxIMEventHook hk;
        hk.arg = notificationitem;
        hk.func = FcitxNotificationItemIMChanged;
        FcitxInstanceRegisterIMChangedHook(instance, hk);
        FcitxInstanceRegisterInputFocusHook(instance, hk);
        FcitxInstanceRegisterInputUnFocusHook(instance, hk);

        hk.func = FcitxNotificationItemUpdateIMList;
        FcitxInstanceRegisterUpdateIMListHook(instance, hk);

        dbus_error_free(&err);

        FcitxNotificationItemAddFunctions(instance);

        notificationitem->isUnity = fcitx_utils_strcmp0(getenv("XDG_CURRENT_DESKTOP"), "Unity") == 0;

        return notificationitem;
    } while(0);

    dbus_error_free(&err);
    FcitxNotificationItemDestroy(notificationitem);

    return NULL;
}
示例#3
0
文件: xkbdbus.c 项目: HenryHu/fcitx
void* FcitxXkbDBusCreate(FcitxInstance* instance)
{
    FcitxXkbDBus* xkbdbus = fcitx_utils_new(FcitxXkbDBus);
    xkbdbus->owner = instance;
    do {
        DBusConnection *conn = FcitxDBusGetConnection(instance);
        DBusConnection *privconn = FcitxDBusGetPrivConnection(instance);
        if (conn == NULL && privconn == NULL) {
            FcitxLog(ERROR, "DBus Not initialized");
            break;
        }

        DBusObjectPathVTable fcitxIPCVTable = {NULL, &FcitxXkbDBusEventHandler, NULL, NULL, NULL, NULL };

        if (conn) {
            dbus_connection_register_object_path(conn, FCITX_XKB_PATH, &fcitxIPCVTable, xkbdbus);
        }

        if (privconn) {
            dbus_connection_register_object_path(privconn, FCITX_XKB_PATH, &fcitxIPCVTable, xkbdbus);
        }

        xkbdbus->conn = conn;
        xkbdbus->privconn = privconn;

        FcitxXkbRules *rules = FcitxXkbGetRules(instance);

        if (!rules)
            break;

        int id = FcitxDBusWatchName(instance, "org.fcitx.GnomeHelper", xkbdbus,
                                    FcitxXkbDBusHelperOwnerChanged, NULL, NULL);
        if (id == 0) {
            break;
        }

        xkbdbus->watcherId = id;

        const char* helper = GNOME_HELPER_NAME;
        DBusMessage* message = dbus_message_new_method_call(DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, "NameHasOwner");
        dbus_message_append_args(message, DBUS_TYPE_STRING, &helper, DBUS_TYPE_INVALID);

        DBusPendingCall* call = NULL;
        dbus_bool_t reply =
            dbus_connection_send_with_reply(xkbdbus->conn, message,
                                            &call, DBUS_TIMEOUT_USE_DEFAULT);
        if (reply == TRUE) {
            dbus_pending_call_set_notify(call,
                                         FcitxXkbDBusHelperServiceExistCallback,
                                         xkbdbus,
                                         NULL);
            dbus_pending_call_unref(call);
        }
        dbus_connection_flush(xkbdbus->conn);
        dbus_message_unref(message);

        xkbdbus->rules = rules;
        xkbdbus->isocodes = FcitxXkbReadIsoCodes(ISOCODES_ISO639_XML, ISOCODES_ISO3166_XML);
        FcitxXkbDBusAddFunctions(instance);
        return xkbdbus;
    } while(0);

    free(xkbdbus);

    return NULL;
}
示例#4
0
void* FcitxNotificationItemCreate(FcitxInstance* instance)
{
    FcitxNotificationItem* notificationitem = fcitx_utils_new(FcitxNotificationItem);
    notificationitem->owner = instance;
    DBusError err;
    dbus_error_init(&err);
    do {
        DBusConnection *conn = FcitxDBusGetConnection(instance);
        if (conn == NULL) {
            FcitxLog(ERROR, "DBus Not initialized");
            break;
        }

        notificationitem->conn = conn;

        if (!dbus_connection_add_filter(notificationitem->conn, FcitxNotificationItemDBusFilter, notificationitem, NULL)) {
            FcitxLog(ERROR, "No memory");
            break;
        }

        DBusObjectPathVTable fcitxIPCVTable = {NULL, &FcitxNotificationItemEventHandler, NULL, NULL, NULL, NULL };
        if (!dbus_connection_register_object_path(notificationitem->conn, NOTIFICATION_ITEM_DEFAULT_OBJ, &fcitxIPCVTable, notificationitem)) {
            FcitxLog(ERROR, "No memory");
            break;
        }

        if (!FcitxDBusMenuCreate(notificationitem)) {
            FcitxLog(ERROR, "No memory");
            break;
        }

        dbus_bus_add_match(notificationitem->conn,
                           "type='signal',"
                           "interface='" DBUS_INTERFACE_DBUS "',"
                           "path='" DBUS_PATH_DBUS "',"
                           "member='NameOwnerChanged',"
                           "arg0='" NOTIFICATION_WATCHER_DBUS_ADDR "'",
                           &err);
        dbus_connection_flush(notificationitem->conn);
        if (dbus_error_is_set(&err)) {
            FcitxLog(ERROR, "Match Error (%s)", err.message);
            break;
        }

        const char* notificationWatcher = NOTIFICATION_WATCHER_DBUS_ADDR;
        DBusMessage* message = dbus_message_new_method_call(DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, "NameHasOwner");
        dbus_message_append_args(message, DBUS_TYPE_STRING, &notificationWatcher, DBUS_TYPE_INVALID);

        DBusPendingCall* call = NULL;
        dbus_bool_t reply = dbus_connection_send_with_reply(notificationitem->conn, message,
                                                            &call,
                                                            0);
        if (reply == TRUE) {
            dbus_pending_call_set_notify(call,
                                         NotificationWatcherServiceExistCallback,
                                         notificationitem,
                                         NULL);
        }
        dbus_connection_flush(notificationitem->conn);
        dbus_message_unref(message);

        FcitxIMEventHook hk;
        hk.arg = notificationitem;
        hk.func = FcitxNotificationItemIMChanged;
        FcitxInstanceRegisterIMChangedHook(instance, hk);
        FcitxInstanceRegisterInputFocusHook(instance, hk);
        FcitxInstanceRegisterInputUnFocusHook(instance, hk);

        dbus_error_free(&err);

        FcitxNotificationItemAddFunctions(instance);

        return notificationitem;
    } while(0);

    dbus_error_free(&err);
    FcitxNotificationItemDestroy(notificationitem);

    return NULL;
}