boolean FcitxNotificationItemEnable(FcitxNotificationItem* notificationitem, FcitxNotificationItemAvailableCallback callback, void* data) { if (!callback || notificationitem->callback) return false; if (notificationitem->serviceName) { FcitxLog(ERROR, "This should not happen, please report bug."); return false; } notificationitem->callback = callback; notificationitem->data = data; asprintf(¬ificationitem->serviceName, "org.kde.StatusNotifierItem-%u-%d", getpid(), ++notificationitem->index); /* once we have name, request it first */ DBusError err; dbus_error_init(&err); dbus_bus_request_name(notificationitem->conn, notificationitem->serviceName, DBUS_NAME_FLAG_DO_NOT_QUEUE, &err); if (dbus_error_is_set(&err)) { FcitxLog(WARNING, "NotificationItem Name Error (%s)", err.message); } dbus_error_free(&err); if (notificationitem->available) { if (notificationitem->callback) { FcitxNotificationItemRegister(notificationitem); } } return true; }
void* FcitxXkbDBusCreate(FcitxInstance* instance) { FcitxXkbDBus* xkbdbus = fcitx_utils_new(FcitxXkbDBus); xkbdbus->owner = instance; do { FcitxModuleFunctionArg arg; DBusConnection* conn = InvokeFunction(instance, FCITX_DBUS, GETCONNECTION, arg); if (conn == NULL) { FcitxLog(ERROR, "DBus Not initialized"); break; } DBusObjectPathVTable fcitxIPCVTable = {NULL, &FcitxXkbDBusEventHandler, NULL, NULL, NULL, NULL }; if (!dbus_connection_register_object_path(conn, FCITX_XKB_PATH, &fcitxIPCVTable, xkbdbus)) { FcitxLog(ERROR, "No memory"); break; } FcitxModuleFunctionArg args; FcitxXkbRules* rules = InvokeFunction(instance, FCITX_XKB, GETRULES, args); if (!rules) break; xkbdbus->rules = rules; xkbdbus->isocodes = FcitxXkbReadIsoCodes(ISOCODES_ISO639_XML, ISOCODES_ISO3166_XML); return xkbdbus; } while(0); free(xkbdbus); return NULL; }
static int LoadLuaConfig(LuaModule *luamodule) { int count = 0; FcitxStringHashSet *sset = FcitxXDGGetFiles("lua", NULL, ".lua"); FcitxStringHashSet *str; for (str = sset; str != NULL;) { FcitxStringHashSet *tmp = str->hh.next; char *path; FILE *f = FcitxXDGGetFileWithPrefix("lua", str->name, "r", &path); if (f && path) { if (LoadExtension(luamodule, path)) { FcitxLog(INFO, "lua load extension file:%s", path); ++count; } else { FcitxLog(ERROR, "LoadExtension() failed"); } } if (f) { fclose(f); } if (path) { free(path); } HASH_DEL(sset, str); free(str->name); free(str); str = tmp; } return count; }
void LoadAutoEng(FcitxAutoEngState* autoEngState) { FILE *fp; char *buf = NULL; size_t length = 0; LoadAutoEngConfig(&autoEngState->config); fp = FcitxXDGGetFileWithPrefix("data", "AutoEngNg.dat", "r", NULL); if (!fp) { FcitxLog(WARNING, "Load AutoEngNg.dat failed"); return; } utarray_new(autoEngState->autoEng, &autoeng_icd); AUTO_ENG autoeng; while (getline(&buf, &length, fp) != -1) { char* line = fcitx_utils_trim(buf); if (strlen(line) > MAX_AUTO_TO_ENG) FcitxLog(WARNING, _("Too long item for AutoEngNg")); strncpy(autoeng.str, line, MAX_AUTO_TO_ENG); free(line); autoeng.str[MAX_AUTO_TO_ENG] = '\0'; utarray_push_back(autoEngState->autoEng, &autoeng); } free(buf); fclose(fp); }
/** * @brief initialize the extra input method * * @param arg * @return successful or not **/ __EXPORT_API void* FcitxChewingCreate(FcitxInstance* instance) { if (GetFcitxChewingConfigDesc() == NULL) return NULL; char* user_path = NULL; FILE* fp = FcitxXDGGetFileUserWithPrefix("chewing", ".place_holder", "w", NULL); if (fp) fclose(fp); FcitxXDGGetFileUserWithPrefix("chewing", "", NULL, &user_path); FcitxLog(INFO, "Chewing storage path %s", user_path); if (0 == chewing_Init(CHEWING_DATADIR, user_path)) { FcitxLog(DEBUG, "chewing init ok"); } else { FcitxLog(DEBUG, "chewing init failed"); return NULL; } FcitxChewing* chewing = (FcitxChewing*) fcitx_utils_malloc0(sizeof(FcitxChewing)); FcitxGlobalConfig* config = FcitxInstanceGetGlobalConfig(instance); FcitxInputState *input = FcitxInstanceGetInputState(instance); FcitxCandidateWordSetChoose(FcitxInputStateGetCandidateList(input), DIGIT_STR_CHOOSE); bindtextdomain("fcitx-chewing", LOCALEDIR); chewing->context = chewing_new(); ChewingContext * c = chewing->context; chewing->owner = instance; chewing_set_ChiEngMode(c, CHINESE_MODE); chewing_set_maxChiSymbolLen(c, 16); // chewing will crash without set page chewing_set_candPerPage(c, config->iMaxCandWord); FcitxCandidateWordSetPageSize(FcitxInputStateGetCandidateList(input), config->iMaxCandWord); chewing_set_selKey(c, selKey, 10); LoadChewingConfig(&chewing->config); ConfigChewing(chewing); FcitxInstanceRegisterIM( instance, chewing, "chewing", _("Chewing"), "chewing", FcitxChewingInit, FcitxChewingReset, FcitxChewingDoInput, FcitxChewingGetCandWords, NULL, NULL, FcitxChewingReloadConfig, NULL, 1, "zh_TW" ); return chewing; }
// Adds a new coordinate to the stroke buffer, enlarging if necessary static void PushCoordinate(FcitxTablet* tablet, pt_t newpt) { *tablet->strokesPtr++ = newpt; if(tablet->strokesPtr == &tablet->strokesBuffer[tablet->strokesBufferSize]) { // if we overflow the buffer, increase it FcitxLog(WARNING, "Resizing stroke buffer"); int newsize = tablet->strokesBufferSize + 1024; pt_t* newbuf = (pt_t*) realloc(tablet->strokesBuffer, sizeof(pt_t)*newsize); if(newbuf == NULL) FcitxLog(ERROR, "Failed to allocate more stroke memory"); tablet->strokesBuffer = newbuf; tablet->strokesPtr = &tablet->strokesBuffer[tablet->strokesBufferSize]; tablet->strokesBufferSize = newsize; } }
void* LuaCreate(FcitxInstance* instance) { LuaModule *luamodule = LuaModuleAlloc(instance); if (luamodule == NULL) { FcitxLog(ERROR, "LuaModule alloc failed"); goto err; } LoadLuaConfig(luamodule); FcitxIMEventHook hook = {.arg = luamodule, .func = LuaUpdateCandidateWordHookCallback}; FcitxInstanceRegisterUpdateCandidateWordHook(instance, hook); FcitxAddon* luaAddon = FcitxAddonsGetAddonByName( FcitxInstanceGetAddons(instance), FCITX_LUA_NAME); AddFunction(luaAddon, LuaCallCommand); return luamodule; err: if (luamodule) { LuaModuleFree(luamodule); } return NULL; }
static void _changed_cb(DBusGProxy* proxy, char* service, char* old_owner, char* new_owner, gpointer user_data) { FcitxLog(LOG_LEVEL, "_changed_cb"); FcitxIMClient* client = (FcitxIMClient*) user_data; if (g_str_equal(service, client->servicename)) { gboolean new_owner_good = new_owner && (new_owner[0] != '\0'); if (new_owner_good) { if (client->proxy) { g_object_unref(client->proxy); client->proxy = NULL; } if (client->icproxy) { g_object_unref(client->icproxy); client->icproxy = NULL; } FcitxIMClientCreateIC(client); } } }
void CloudPinyinAddCandidateWord(void* arg) { FcitxCloudPinyin* cloudpinyin = (FcitxCloudPinyin*) arg; FcitxIM* im = FcitxInstanceGetCurrentIM(cloudpinyin->owner); FcitxInputState* input = FcitxInstanceGetInputState(cloudpinyin->owner); if (cloudpinyin->initialized == false) return; /* check whether the current im is pinyin */ if (CHECK_VALID_IM) { /* there is something pending input */ if (FcitxInputStateGetRawInputBufferSize(input) >= cloudpinyin->config.iMinimumPinyinLength) { char* strToFree = NULL, *inputString; strToFree = GetCurrentString(cloudpinyin); inputString = SplitHZAndPY(strToFree); if (inputString) { CloudPinyinCache* cacheEntry = CloudPinyinCacheLookup(cloudpinyin, inputString); FcitxLog(LOGLEVEL, "%s", inputString); if (cacheEntry == NULL) CloudPinyinAddInputRequest(cloudpinyin, inputString); _CloudPinyinAddCandidateWord(cloudpinyin, inputString); } if (strToFree) free(strToFree); } } return; }
boolean LoadQuickPhraseConfig(QuickPhraseState* qpstate) { FcitxConfigFileDesc* configDesc = GetQuickPhraseConfigDesc(); if (configDesc == NULL) return false; FILE *fp; char *file; fp = FcitxXDGGetFileUserWithPrefix("conf", "fcitx-quickphrase.config", "r", &file); FcitxLog(DEBUG, "Load Config File %s", file); free(file); if (!fp) { if (errno == ENOENT) SaveQuickPhraseConfig(qpstate); } FcitxConfigFile *cfile = FcitxConfigParseConfigFileFp(fp, configDesc); QuickPhraseStateConfigBind(qpstate, cfile, configDesc); FcitxConfigBindSync((FcitxGenericConfig*)qpstate); if (fp) fclose(fp); return true; }
static void fcitx_im_context_focus_out(GtkIMContext *context) { FcitxLog(LOG_LEVEL, "fcitx_im_context_focus_out"); FcitxIMContext *fcitxcontext = FCITX_IM_CONTEXT(context); if (!fcitxcontext->has_focus) { return; } g_assert (context == _focus_im_context); g_object_remove_weak_pointer ((GObject *) context, (gpointer *) &_focus_im_context); _focus_im_context = NULL; fcitxcontext->has_focus = false; if (fcitx_client_is_valid(fcitxcontext->client)) { fcitx_client_focus_out(fcitxcontext->client); } fcitxcontext->cursor_pos = 0; if (fcitxcontext->preedit_string != NULL) { g_free(fcitxcontext->preedit_string); fcitxcontext->preedit_string = NULL; g_signal_emit(fcitxcontext, _signal_preedit_changed_id, 0); g_signal_emit(fcitxcontext, _signal_preedit_end_id, 0); } gtk_im_context_focus_out(fcitxcontext->slave); return; }
static void fcitx_im_context_finalize(GObject *obj) { FcitxLog(LOG_LEVEL, "fcitx_im_context_finalize"); FcitxIMContext *context = FCITX_IM_CONTEXT(obj); fcitx_im_context_set_client_window(GTK_IM_CONTEXT(context), NULL); g_object_unref(context->client); context->client = NULL; if (context->slave) { g_object_unref(context->slave); context->slave = NULL; } if (context->preedit_string) g_free(context->preedit_string); context->preedit_string = NULL; if (context->attrlist) pango_attr_list_unref(context->attrlist); context->attrlist = NULL; G_OBJECT_CLASS(parent_class)->finalize (obj); }
void FcitxInitThread(FcitxInstance* inst) { int rc; rc = pthread_mutex_init(&inst->fcitxMutex, NULL); if (rc != 0) FcitxLog(ERROR, _("pthread mutex init failed")); }
void FcitxNotificationItemRegister(FcitxNotificationItem* notificationitem) { if (!notificationitem->serviceName) { FcitxLog(ERROR, "This should not happen, please report bug."); return; } DBusMessage *message = dbus_message_new_method_call(NOTIFICATION_WATCHER_DBUS_ADDR, NOTIFICATION_WATCHER_DBUS_OBJ, NOTIFICATION_WATCHER_DBUS_IFACE, "RegisterStatusNotifierItem"); dbus_message_append_args(message, DBUS_TYPE_STRING, ¬ificationitem->serviceName, DBUS_TYPE_INVALID); DBusPendingCall *call = NULL; dbus_bool_t reply = dbus_connection_send_with_reply(notificationitem->conn, message, &call, DBUS_TIMEOUT_USE_DEFAULT); dbus_message_unref(message); if (reply == TRUE) { dbus_pending_call_set_notify(call, FcitxNotificationItemRegisterSuccess, notificationitem, NULL); dbus_pending_call_unref(call); } }
boolean LoadIMSelectorConfig(IMSelector* imselector) { FcitxConfigFileDesc* configDesc = GetIMSelectorConfig(); if (configDesc == NULL) return false; FILE *fp; char *file; fp = FcitxXDGGetFileUserWithPrefix("conf", "fcitx-imselector.config", "r", &file); FcitxLog(DEBUG, "Load Config File %s", file); free(file); if (!fp) { if (errno == ENOENT) SaveIMSelectorConfig(imselector); } FcitxConfigFile *cfile = FcitxConfigParseConfigFileFp(fp, configDesc); IMSelectorConfigBind(imselector, cfile, configDesc); FcitxConfigBindSync((FcitxGenericConfig*)imselector); if (fp) fclose(fp); return true; }
boolean LoadChttransConfig(FcitxChttrans* transState) { FcitxConfigFileDesc* configDesc = GetChttransConfigDesc(); if (configDesc == NULL) return false; FILE *fp; char *file; fp = FcitxXDGGetFileUserWithPrefix("conf", "fcitx-chttrans.config", "r", &file); FcitxLog(DEBUG, "Load Config File %s", file); free(file); if (!fp) { if (errno == ENOENT) SaveChttransConfig(transState); } FcitxConfigFile *cfile = FcitxConfigParseConfigFileFp(fp, configDesc); FcitxChttransConfigBind(transState, cfile, configDesc); FcitxConfigBindSync((FcitxGenericConfig*)transState); if (fp) fclose(fp); return true; }
FCITX_EXPORT_API void FcitxUIUpdateStatus(FcitxInstance* instance, const char* name) { FcitxLog(DEBUG, "Update Status for %s", name); FcitxUIStatus *status = FcitxUIGetStatusByName(instance, name); if (status != NULL) { if (status->toggleStatus) status->toggleStatus(status->arg); if (UI_FUNC_IS_VALID(UpdateStatus)) instance->ui->ui->UpdateStatus(instance->ui->addonInstance , status); } else { FcitxUIComplexStatus *compstatus = FcitxUIGetComplexStatusByName(instance, name); if (!compstatus) return; if (compstatus->toggleStatus) compstatus->toggleStatus(compstatus->arg); if (UI_FUNC_IS_VALID(UpdateComplexStatus)) instance->ui->ui->UpdateComplexStatus(instance->ui->addonInstance , compstatus); } }
static unsigned char* X11GetWindowProperty(FcitxX11 *x11priv, Window win, Atom prop, Atom *ret_type, int *ret_format, unsigned long *nitems) { unsigned char *buff = NULL; int res; unsigned long bytes_left = 0; if (prop == None) goto fail; res = XGetWindowProperty(x11priv->dpy, win, prop, 0, 0x6400, // 100k / 4 False, AnyPropertyType, ret_type, ret_format, nitems, &bytes_left, &buff); if (res != Success || *ret_type == None || !buff) goto fail; switch (*ret_format) { case 8: case 16: case 32: break; default: goto fail; } if (bytes_left) FcitxLog(WARNING, "Selection is too long."); return buff; fail: if (buff) XFree(buff); *nitems = 0; *ret_format = 0; *ret_type = None; return NULL; }
void _fcitx_im_context_forward_key_cb(DBusGProxy* proxy, guint keyval, guint state, gint type, void* user_data) { FcitxLog(LOG_LEVEL, "_fcitx_im_context_forward_key_cb"); ClutterIMContext* context = CLUTTER_IM_CONTEXT(user_data); const char* signal_name; gboolean consumed = FALSE; FcitxKeyEventType tp = (FcitxKeyEventType) type; ClutterKeyEvent clutter_key_event; clutter_key_event.flags = 0; clutter_key_event.source = NULL; clutter_key_event.keyval = keyval; clutter_key_event.hardware_keycode = 0; clutter_key_event.unicode_value = 0; clutter_key_event.modifier_state = state; clutter_key_event.device = NULL; struct timeval current_time; gettimeofday(¤t_time, NULL); clutter_key_event.time = current_time.tv_sec * 1000 + current_time.tv_usec / 1000; if (tp == FCITX_PRESS_KEY) { clutter_key_event.type = CLUTTER_KEY_PRESS; signal_name = "key-press-event"; } else { clutter_key_event.type = CLUTTER_KEY_RELEASE; clutter_key_event.modifier_state |= CLUTTER_RELEASE_MASK; signal_name = "key-release-event"; } clutter_key_event.modifier_state |= FcitxKeyState_IgnoredMask; clutter_key_event.stage = CLUTTER_STAGE (clutter_actor_get_stage(context->actor)); g_signal_emit_by_name(context->actor, signal_name, &clutter_key_event, &consumed); }
FCITX_EXPORT_API void FcitxUILoad(FcitxInstance* instance) { UT_array* addons = &instance->addons; FcitxAddon *addon; for (addon = (FcitxAddon *) utarray_front(addons); addon != NULL; addon = (FcitxAddon *) utarray_next(addons, addon)) { if (addon->bEnabled && addon->category == AC_UI) { if (FcitxUILoadInternal(instance, addon)) instance->uinormal = addon; if (instance->uinormal != NULL) break; } } instance->ui = instance->uinormal; if (instance->ui == NULL) { FcitxLog(ERROR, "no usable user interface."); return; } if (addon->uifallback) instance->fallbackuiName = strdup(addon->uifallback); }
static void fcitx_im_context_focus_out(ClutterIMContext *context) { FcitxLog(LOG_LEVEL, "fcitx_im_context_focus_out"); FcitxIMContext *fcitxcontext = FCITX_IM_CONTEXT(context); if (!fcitxcontext->has_focus) { return; } fcitxcontext->has_focus = false; if (IsFcitxIMClientValid(fcitxcontext->client)) { FcitxIMClientFocusOut(fcitxcontext->client); } if (fcitxcontext->preedit_string != NULL) g_free(fcitxcontext->preedit_string); fcitxcontext->preedit_string = NULL; fcitxcontext->cursor_pos = 0; g_signal_emit(fcitxcontext, _signal_preedit_changed_id, 0); g_signal_emit(fcitxcontext, _signal_preedit_end_id, 0); return; }
static void fcitx_im_context_set_client_window(GtkIMContext *context, GdkWindow *client_window) { FcitxLog(LOG_LEVEL, "fcitx_im_context_set_client_window"); FcitxIMContext *fcitxcontext = FCITX_IM_CONTEXT(context); set_ic_client_window(fcitxcontext, client_window); }
static void fcitx_im_context_init(FcitxIMContext *context) { FcitxLog(LOG_LEVEL, "fcitx_im_context_init"); context->client = NULL; context->area.x = -1; context->area.y = -1; context->area.width = 0; context->area.height = 0; context->use_preedit = TRUE; context->cursor_pos = 0; context->preedit_string = NULL; context->attrlist = NULL; context->capacity = CAPACITY_SURROUNDING_TEXT; context->slave = gtk_im_context_simple_new(); gtk_im_context_simple_add_table(GTK_IM_CONTEXT_SIMPLE(context->slave), cedilla_compose_seqs, 4, G_N_ELEMENTS(cedilla_compose_seqs) / (4 + 2)); g_signal_connect(context->slave, "commit", G_CALLBACK(_slave_commit_cb), context); g_signal_connect(context->slave, "preedit-start", G_CALLBACK(_slave_preedit_start_cb), context); g_signal_connect(context->slave, "preedit-end", G_CALLBACK(_slave_preedit_end_cb), context); g_signal_connect(context->slave, "preedit-changed", G_CALLBACK(_slave_preedit_changed_cb), context); g_signal_connect(context->slave, "retrieve-surrounding", G_CALLBACK(_slave_retrieve_surrounding_cb), context); g_signal_connect(context->slave, "delete-surrounding", G_CALLBACK(_slave_delete_surrounding_cb), context); context->time = GDK_CURRENT_TIME; context->client = fcitx_client_new(); g_signal_connect(context->client, "connected", G_CALLBACK(_fcitx_im_context_connect_cb), context); g_signal_connect(context->client, "enable-im", G_CALLBACK(_fcitx_im_context_enable_im_cb), context); g_signal_connect(context->client, "close-im", G_CALLBACK(_fcitx_im_context_close_im_cb), context); g_signal_connect(context->client, "forward-key", G_CALLBACK(_fcitx_im_context_forward_key_cb), context); g_signal_connect(context->client, "commit-string", G_CALLBACK(_fcitx_im_context_commit_string_cb), context); g_signal_connect(context->client, "delete-surrounding-text", G_CALLBACK(_fcitx_im_context_delete_surrounding_text_cb), context); g_signal_connect(context->client, "update-formatted-preedit", G_CALLBACK(_fcitx_im_context_update_formatted_preedit_cb), context); }
static void fcitx_im_context_reset(ClutterIMContext *context) { FcitxLog(LOG_LEVEL, "fcitx_im_context_reset"); FcitxIMContext *fcitxcontext = FCITX_IM_CONTEXT(context); if (IsFcitxIMClientValid(fcitxcontext->client)) { FcitxIMClientReset(fcitxcontext->client); } }
static void fcitx_im_context_set_use_preedit(ClutterIMContext *context, gboolean use_preedit) { FcitxLog(LOG_LEVEL, "fcitx_im_context_set_use_preedit"); FcitxIMContext *fcitxcontext = FCITX_IM_CONTEXT(context); fcitxcontext->use_preedit = use_preedit; _fcitx_im_context_set_capacity(fcitxcontext); }
void _fcitx_im_context_forward_key_cb(FcitxClient* im, guint keyval, guint state, gint type, void* user_data) { FcitxLog(LOG_LEVEL, "_fcitx_im_context_forward_key_cb"); FcitxIMContext* context = FCITX_IM_CONTEXT(user_data); FcitxKeyEventType tp = (FcitxKeyEventType) type; GdkEventKey* event = _create_gdk_event(context, keyval, state, tp); event->state |= FcitxKeyState_IgnoredMask; gdk_event_put((GdkEvent *)event); gdk_event_free((GdkEvent *)event); }
void SaveQuickPhraseConfig(QuickPhraseState* qpstate) { FcitxConfigFileDesc* configDesc = GetQuickPhraseConfigDesc(); char *file; FILE *fp = FcitxXDGGetFileUserWithPrefix("conf", "fcitx-quickphrase.config", "w", &file); FcitxLog(DEBUG, "Save Config to %s", file); FcitxConfigSaveConfigFileFp(fp, &qpstate->gconfig, configDesc); free(file); if (fp) fclose(fp); }
void SaveClassicUIConfig(FcitxClassicUI *classicui) { FcitxConfigFileDesc* configDesc = GetClassicUIDesc(); char *file; FILE *fp = FcitxXDGGetFileUserWithPrefix("conf", "fcitx-classic-ui.config", "wt", &file); FcitxLog(DEBUG, "Save Config to %s", file); FcitxConfigSaveConfigFileFp(fp, &classicui->gconfig, configDesc); free(file); if (fp) fclose(fp); }
void SaveChttransConfig(FcitxChttrans* transState) { FcitxConfigFileDesc* configDesc = GetChttransConfigDesc(); char *file; FILE *fp = FcitxXDGGetFileUserWithPrefix("conf", "fcitx-chttrans.config", "w", &file); FcitxLog(DEBUG, "Save Config to %s", file); FcitxConfigSaveConfigFileFp(fp, &transState->gconfig, configDesc); free(file); if (fp) fclose(fp); }
void SaveIMSelectorConfig(IMSelector* imselector) { FcitxConfigFileDesc* configDesc = GetIMSelectorConfig(); char *file; FILE *fp = FcitxXDGGetFileUserWithPrefix("conf", "fcitx-imselector.config", "w", &file); FcitxLog(DEBUG, "Save Config to %s", file); FcitxConfigSaveConfigFileFp(fp, &imselector->gconfig, configDesc); free(file); if (fp) fclose(fp); }