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(¬ify->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; }
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, ¬ificationWatcher, 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; }
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; }
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, ¬ificationWatcher, 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; }