void *VKCreate(FcitxInstance* instance) { FcitxVKState *vkstate = fcitx_utils_malloc0(sizeof(FcitxVKState)); FcitxGlobalConfig* config = FcitxInstanceGetGlobalConfig(instance); vkstate->owner = instance; FcitxHotkeyHook hotkey; hotkey.hotkey = config->hkVK; hotkey.hotkeyhandle = ToggleVKStateWithHotkey; hotkey.arg = vkstate; FcitxInstanceRegisterHotkeyFilter(instance, hotkey); FcitxUIRegisterStatus(instance, vkstate, "vk", _("Toggle Virtual Keyboard"), _("Virtual Keyboard State"), ToggleVKState, GetVKState); LoadVKMapFile(vkstate); FcitxKeyFilterHook hk; hk.arg = vkstate ; hk.func = VKPreFilter; FcitxInstanceRegisterPreInputFilter(instance, hk); FcitxIMEventHook resethk; resethk.arg = vkstate; resethk.func = VKReset; FcitxInstanceRegisterTriggerOnHook(instance, resethk); FcitxInstanceRegisterTriggerOffHook(instance, resethk); resethk.func = VKUpdate; FcitxInstanceRegisterInputFocusHook(instance, resethk); FcitxInstanceRegisterInputUnFocusHook(instance, resethk); FcitxMenuInit(&vkstate->vkmenu); vkstate->vkmenu.candStatusBind = strdup("vk"); vkstate->vkmenu.name = strdup(_("Virtual Keyboard")); vkstate->vkmenu.UpdateMenu = UpdateVKMenu; vkstate->vkmenu.MenuAction = VKMenuAction; vkstate->vkmenu.priv = vkstate; vkstate->vkmenu.isSubMenu = false; FcitxUIRegisterMenu(instance, &vkstate->vkmenu); return vkstate; }
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* 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; }
void* CloudPinyinCreate(FcitxInstance* instance) { FcitxCloudPinyin* cloudpinyin = fcitx_utils_malloc0(sizeof(FcitxCloudPinyin)); bindtextdomain("fcitx-cloudpinyin", LOCALEDIR); cloudpinyin->owner = instance; int pipe1[2]; int pipe2[2]; if (!LoadCloudPinyinConfig(&cloudpinyin->config)) { free(cloudpinyin); return NULL; } if (pipe(pipe1) < 0) { free(cloudpinyin); return NULL; } if (pipe(pipe2) < 0) { close(pipe1[0]); close(pipe1[1]); free(cloudpinyin); return NULL; } cloudpinyin->pipeRecv = pipe1[0]; cloudpinyin->pipeNotify = pipe2[1]; fcntl(pipe1[0], F_SETFL, O_NONBLOCK); fcntl(pipe1[1], F_SETFL, O_NONBLOCK); fcntl(pipe2[0], F_SETFL, O_NONBLOCK); fcntl(pipe2[1], F_SETFL, O_NONBLOCK); cloudpinyin->pendingQueue = fcitx_utils_malloc0(sizeof(CurlQueue)); cloudpinyin->finishQueue = fcitx_utils_malloc0(sizeof(CurlQueue)); pthread_mutex_init(&cloudpinyin->pendingQueueLock, NULL); pthread_mutex_init(&cloudpinyin->finishQueueLock, NULL); FcitxFetchThread* fetch = fcitx_utils_malloc0(sizeof(FcitxFetchThread)); cloudpinyin->fetch = fetch; fetch->owner = cloudpinyin; fetch->pipeRecv = pipe2[0]; fetch->pipeNotify = pipe1[1]; fetch->pendingQueueLock = &cloudpinyin->pendingQueueLock; fetch->finishQueueLock = &cloudpinyin->finishQueueLock; fetch->queue = fcitx_utils_malloc0(sizeof(CurlQueue)); FcitxIMEventHook hook; hook.arg = cloudpinyin; hook.func = CloudPinyinAddCandidateWord; FcitxInstanceRegisterUpdateCandidateWordHook(instance, hook); hook.arg = cloudpinyin; hook.func = CloudPinyinHookForNewRequest; FcitxInstanceRegisterResetInputHook(instance, hook); FcitxInstanceRegisterInputFocusHook(instance, hook); FcitxInstanceRegisterInputUnFocusHook(instance, hook); FcitxInstanceRegisterTriggerOnHook(instance, hook); pthread_create(&cloudpinyin->pid, NULL, FetchThread, fetch); CloudPinyinRequestKey(cloudpinyin); return cloudpinyin; }