Example #1
0
void* ChttransCreate(FcitxInstance* instance)
{
    FcitxChttrans* transState = fcitx_utils_malloc0(sizeof(FcitxChttrans));
    FcitxAddon* transAddon = FcitxAddonsGetAddonByName(FcitxInstanceGetAddons(instance), FCITX_CHTTRANS_NAME);
    transState->owner = instance;
    if (!LoadChttransConfig(transState)) {
        free(transState);
        return NULL;
    }

    FcitxHotkeyHook hk;
    hk.arg = transState;
    hk.hotkey = transState->hkToggle;
    hk.hotkeyhandle = HotkeyToggleChttransState;

    FcitxStringFilterHook shk;
    shk.arg = transState;
    shk.func = ChttransOutputFilter;

    FcitxInstanceRegisterHotkeyFilter(instance, hk);
    FcitxInstanceRegisterOutputFilter(instance, shk);
    FcitxInstanceRegisterCommitFilter(instance, shk);
    FcitxUIRegisterStatus(instance, transState, "chttrans",
                          transState->enabled ? _("Convert to Traditional Chinese") :  _("Convert to Simplified Chinese"),
                          _("Toggle Simp/Trad Chinese Conversion"),
                          ToggleChttransState,
                          GetChttransEnabled);

    FcitxInstanceWatchContext(instance, CONTEXT_IM_LANGUAGE, ChttransLanguageChanged, transState);

    AddFunction(transAddon, ChttransS2T);
    AddFunction(transAddon, ChttransT2S);

    return transState;
}
Example #2
0
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;
}
Example #3
0
void * QuickPhraseCreate(FcitxInstance *instance)
{
    QuickPhraseState *qpstate = fcitx_utils_malloc0(sizeof(QuickPhraseState));
    qpstate->owner = instance;
    qpstate->enabled = false;

    if (!LoadQuickPhraseConfig(&qpstate->config)) {
        free(qpstate);
        return NULL;
    }

    LoadQuickPhrase(qpstate);

    FcitxKeyFilterHook hk;
    hk.arg = qpstate;
    hk.func = QuickPhrasePostFilter;
    FcitxInstanceRegisterPostInputFilter(instance, hk);

    hk.func = QuickPhrasePreFilter;
    FcitxInstanceRegisterPreInputFilter(instance, hk);

    FcitxIMEventHook resethk;
    resethk.arg = qpstate;
    resethk.func = QuickPhraseReset;
    FcitxInstanceRegisterResetInputHook(instance, resethk);

    FcitxInstanceRegisterWatchableContext(instance, CONTEXT_DISABLE_QUICKPHRASE, FCT_Boolean, FCF_ResetOnInputMethodChange);

    FcitxAddon* addon = FcitxAddonsGetAddonByName(
        FcitxInstanceGetAddons(instance),
        FCITX_QUICKPHRASE_NAME);
    FcitxModuleAddFunction(addon, QuickPhraseLaunch);

    return qpstate;
}
Example #4
0
void* LightUICreate(FcitxInstance* instance)
{
    FcitxModuleFunctionArg arg;
    FcitxLightUI* lightui = fcitx_utils_malloc0(sizeof(FcitxLightUI));
    FcitxAddon* lightuiaddon = FcitxAddonsGetAddonByName(FcitxInstanceGetAddons(instance), FCITX_LIGHT_UI_NAME);
    lightui->owner = instance;
    if (!LoadLightUIConfig(lightui))
    {
        free(lightui);
        return NULL;
    }
    lightui->dpy = InvokeFunction(instance, FCITX_X11, GETDISPLAY, arg);
    if (lightui->dpy == NULL)
    {
        free(lightui);
        return NULL;
    }
    lightui->isfallback = FcitxUIIsFallback(instance, lightuiaddon);

    lightui->iScreen = DefaultScreen(lightui->dpy);
    CreateFont(lightui);

    lightui->protocolAtom = XInternAtom (lightui->dpy, "WM_PROTOCOLS", False);
    lightui->killAtom = XInternAtom (lightui->dpy, "WM_DELETE_WINDOW", False);

    /* Main Menu Initial */
    FcitxMenuInit(&lightui->mainMenu);

    FcitxUIMenu **menupp;
    UT_array* uimenus = FcitxInstanceGetUIMenus(instance);
    for (menupp = (FcitxUIMenu **) utarray_front(uimenus);
            menupp != NULL;
            menupp = (FcitxUIMenu **) utarray_next(uimenus, menupp)
        )
    {
        FcitxUIMenu * menup = *menupp;
        if (!menup->isSubMenu)
            FcitxMenuAddMenuItem(&lightui->mainMenu, menup->name, MENUTYPE_SUBMENU, menup);
    }
    FcitxMenuAddMenuItem(&lightui->mainMenu, NULL, MENUTYPE_DIVLINE, NULL);
    FcitxMenuAddMenuItem(&lightui->mainMenu, _("Configure"), MENUTYPE_SIMPLE, NULL);
    FcitxMenuAddMenuItem(&lightui->mainMenu, _("Exit"), MENUTYPE_SIMPLE, NULL);
    lightui->mainMenu.MenuAction = MainMenuAction;
    lightui->mainMenu.priv = lightui;
    lightui->mainMenu.mark = -1;


    lightui->inputWindow = CreateInputWindow(lightui);
    lightui->mainWindow = CreateMainWindow(lightui);
    lightui->trayWindow = CreateTrayWindow(lightui);
    lightui->mainMenuWindow = CreateMainMenuWindow(lightui);

    FcitxIMEventHook resethk;
    resethk.arg = lightui;
    resethk.func = LightUIInputReset;
    FcitxInstanceRegisterResetInputHook(instance, resethk);
    return lightui;
}
Example #5
0
File: punc.c Project: adaptee/fcitx
void* PuncCreate(FcitxInstance* instance)
{
    FcitxPuncState* puncState = fcitx_utils_malloc0(sizeof(FcitxPuncState));
    FcitxAddon* puncaddon = FcitxAddonsGetAddonByName(FcitxInstanceGetAddons(instance), FCITX_PUNC_NAME);
    puncState->owner = instance;
    LoadPuncDict(puncState);
    FcitxKeyFilterHook hk;
    hk.arg = puncState;
    hk.func = ProcessPunc;

    FcitxInstanceRegisterPostInputFilter(instance, hk);

    hk.func = PuncPreFilter;
    FcitxInstanceRegisterPreInputFilter(instance, hk);

    puncState->cLastIsAutoConvert = '\0';
    puncState->bLastIsNumber = false;

    FcitxHotkeyHook hotkey;
    hotkey.hotkey = FcitxInstanceGetGlobalConfig(instance)->hkPunc;
    hotkey.hotkeyhandle = TogglePuncStateWithHotkey;
    hotkey.arg = puncState;
    FcitxInstanceRegisterHotkeyFilter(instance, hotkey);

    FcitxIMEventHook hook;
    hook.arg = puncState;
    hook.func = ResetPunc;

    FcitxInstanceRegisterResetInputHook(instance, hook);

    hook.func = ResetPuncWhichStatus;

    FcitxInstanceRegisterInputUnFocusHook(instance, hook);

    FcitxInstanceWatchContext(instance, CONTEXT_IM_LANGUAGE, PuncLanguageChanged, puncState);

    FcitxProfile* profile = FcitxInstanceGetProfile(instance);
    FcitxUIRegisterStatus(instance, puncState, "punc",
                          profile->bUseWidePunc ? _("Full width punct") :  _("Latin punct"),
                          _("Toggle Full Width Punctuation"), TogglePuncState, GetPuncState);

    puncState->slot = FcitxInstanceAllocDataForIC(instance, PuncWhichAlloc, PuncWhichCopy, PuncWhichFree, puncState);

    FcitxModuleAddFunction(puncaddon, PuncGetPunc);
    FcitxModuleAddFunction(puncaddon, PuncGetPunc2);
    return puncState;
}
Example #6
0
// Creates the IME component
void* FcitxTabletImeCreate(FcitxInstance* instance) {
	// Steal the user data from the event addon, since it's more long lived
	FcitxTablet* ud = FcitxAddonsGetAddonByName(FcitxInstanceGetAddons(instance), FCITX_TABLET_NAME)->addonInstance;
	FcitxInstanceRegisterIM(
				instance,
				ud, //userdata
				"tablet",
				"Tablet",
				"tablet",
				NULL,
				FcitxTabletReset,
				FcitxTabletDoInput,
				FcitxTabletGetCandWords,
				NULL,
				NULL,
				NULL,
				NULL,
				1,
				"zh_CN"
				);
	return ud;
}
Example #7
0
File: xim.c Project: adaptee/fcitx
void* XimCreate(FcitxInstance* instance, int frontendid)
{
    if (ximfrontend != NULL)
        return NULL;
    FcitxXimFrontend *xim = fcitx_utils_new(FcitxXimFrontend);
    if (xim == NULL)
        return NULL;

    ximfrontend = xim;

    char *imname = NULL;
    char *p;

    UT_array *addons = FcitxInstanceGetAddons(instance);
    FcitxAddon *ximaddon = FcitxAddonsGetAddonByName(addons, "fcitx-xim");
    xim->display = FcitxX11GetDisplay(instance);

    if (xim->display == NULL) {
        FcitxLog(FATAL, _("X11 not initialized"));
        free(xim);
        return NULL;
    }

    xim->iScreen = DefaultScreen(xim->display);
    xim->owner = instance;
    xim->frontendid = frontendid;
    xim->xim_window = XCreateWindow(xim->display, DefaultRootWindow(xim->display),
                                    0, 0, 1, 1, 0, 0, InputOnly,
                                    CopyFromParent, 0, NULL);
    if (!xim->xim_window) {
        FcitxLog(FATAL, _("Can't Create imWindow"));
        free(xim);
        return NULL;
    }

    if (!imname) {
        imname = getenv("XMODIFIERS");
        if (imname) {
            if (!strncmp(imname, "@im=", strlen("@im="))) {
                imname += 4;
            } else {
                FcitxLog(WARNING, _("XMODIFIERS Error."));
                imname = DEFAULT_IMNAME;
            }
        } else {
            FcitxLog(WARNING, _("Please set XMODIFIERS."));
            imname = DEFAULT_IMNAME;
        }
    }
    XimQueueInit(xim);

    if (GetXimConfigDesc() == NULL)
        xim->bUseOnTheSpotStyle = false;
    else {
        FcitxConfigFileDesc* configDesc = GetXimConfigDesc();

        FILE *fp;
        char *file;
        fp = FcitxXDGGetFileUserWithPrefix("conf", "fcitx-xim.config", "r", &file);
        FcitxLog(DEBUG, "Load Config File %s", file);
        free(file);
        if (!fp) {
            if (errno == ENOENT) {
                char *file;
                FILE *fp2 = FcitxXDGGetFileUserWithPrefix("conf", "fcitx-xim.config", "w", &file);
                FcitxLog(DEBUG, "Save Config to %s", file);
                FcitxConfigSaveConfigFileFp(fp2, &xim->gconfig, configDesc);
                free(file);
                if (fp2)
                    fclose(fp2);
            }
        }

        FcitxConfigFile *cfile = FcitxConfigParseConfigFileFp(fp, configDesc);

        FcitxXimFrontendConfigBind(xim, cfile, configDesc);
        FcitxConfigBindSync((FcitxGenericConfig*)xim);

        if (fp)
            fclose(fp);
    }

    XIMStyles input_styles;
    if (xim->bUseOnTheSpotStyle) {
        input_styles.count_styles =
            sizeof(OnTheSpot_Styles) / sizeof(XIMStyle) - 1;
        input_styles.supported_styles = OnTheSpot_Styles;
    } else {
        input_styles.count_styles =
            sizeof(OverTheSpot_Styles) / sizeof(XIMStyle) - 1;
        input_styles.supported_styles = OverTheSpot_Styles;
    }

    XIMEncodings encodings = {
        .count_encodings = sizeof(zhEncodings) / sizeof(XIMEncoding) - 1,
        .supported_encodings = zhEncodings
    };

    p = getenv("LC_CTYPE");
    if (!p) {
        p = getenv("LC_ALL");
        if (!p)
            p = getenv("LANG");
    }
    if (p) {
        int p_l = strlen(p);
        if (strlen(LOCALES_STRING) + p_l + 1 < LOCALES_BUFSIZE) {
            strLocale[strlen(LOCALES_STRING)] = ',';
            memcpy(strLocale + strlen(LOCALES_STRING) + 1, p, p_l + 1);
        }
    }

    xim->ims = IMOpenIM(xim->display,
                        IMModifiers, "Xi18n",
                        IMServerWindow, xim->xim_window,
                        IMServerName, imname,
                        IMLocale, strLocale,
                        IMServerTransport, "X/",
                        IMInputStyles, &input_styles,
                        IMEncodingList, &encodings,
                        IMProtocolHandler, XimProtocolHandler,
                        IMFilterEventMask, KeyPressMask | KeyReleaseMask,
                        NULL);

    if (xim->ims == (XIMS) NULL) {
        FcitxLog(ERROR, _("Start XIM error. Another XIM daemon named %s is running?"), imname);
        XimDestroy(xim);
        FcitxInstanceEnd(instance);
        return NULL;
    }

    FcitxModuleAddFunction(ximaddon, XimConsumeQueue);

    return xim;
}

Bool XimProtocolHandler(XIMS _ims, IMProtocol * call_data)
{
    switch (call_data->major_code) {
    case XIM_OPEN:
        FcitxLog(DEBUG, "XIM_OPEN:\t\ticid=%d\tconnect_id=%d", ((IMForwardEventStruct *) call_data)->icid,
                 ((IMForwardEventStruct *) call_data)->connect_id);
        break;
    case XIM_CLOSE:
        FcitxLog(DEBUG, "XIM_CLOSE:\t\ticid=%d\tconnect_id=%d", ((IMForwardEventStruct *) call_data)->icid,
                 ((IMForwardEventStruct *) call_data)->connect_id);
        break;
    case XIM_CREATE_IC:
        FcitxLog(DEBUG, "XIM_CREATE_IC:\t\ticid=%d\tconnect_id=%d", ((IMForwardEventStruct *) call_data)->icid,
                 ((IMForwardEventStruct *) call_data)->connect_id);
        break;
    case XIM_DESTROY_IC:
        FcitxLog(DEBUG, "XIM_DESTROY_IC:\t\ticid=%d\tconnect_id=%d", ((IMForwardEventStruct *) call_data)->icid,
                 ((IMForwardEventStruct *) call_data)->connect_id);
        break;
    case XIM_SET_IC_VALUES:
        FcitxLog(DEBUG, "XIM_SET_IC_VALUES:\t\ticid=%d\tconnect_id=%d", ((IMForwardEventStruct *) call_data)->icid,
                 ((IMForwardEventStruct *) call_data)->connect_id);
        break;
    case XIM_GET_IC_VALUES:
        FcitxLog(DEBUG, "XIM_GET_IC_VALUES:\ticid=%d\tconnect_id=%d", ((IMForwardEventStruct *) call_data)->icid,
                 ((IMForwardEventStruct *) call_data)->connect_id);
        break;
    case XIM_FORWARD_EVENT:
        FcitxLog(DEBUG, "XIM_FORWARD_EVENT:\ticid=%d\tconnect_id=%d", ((IMForwardEventStruct *) call_data)->icid,
                 ((IMForwardEventStruct *) call_data)->connect_id);
        break;
    case XIM_SET_IC_FOCUS:
        FcitxLog(DEBUG, "XIM_SET_IC_FOCUS:\ticid=%d\tconnect_id=%d", ((IMForwardEventStruct *) call_data)->icid,
                 ((IMForwardEventStruct *) call_data)->connect_id);
        break;
    case XIM_UNSET_IC_FOCUS:
        FcitxLog(DEBUG, "XIM_UNSET_IC_FOCUS:\ticid=%d\tconnect_id=%d", ((IMForwardEventStruct *) call_data)->icid,
                 ((IMForwardEventStruct *) call_data)->connect_id);
        break;
    case XIM_RESET_IC:
        FcitxLog(DEBUG, "XIM_RESET_IC:\t\ticid=%d\tconnect_id=%d", ((IMForwardEventStruct *) call_data)->icid,
                 ((IMForwardEventStruct *) call_data)->connect_id);
        break;
    case XIM_TRIGGER_NOTIFY:
        FcitxLog(DEBUG, "XIM_TRIGGER_NOTIFY:\t\ticid=%d\tconnect_id=%d", ((IMForwardEventStruct *) call_data)->icid,
                 ((IMForwardEventStruct *) call_data)->connect_id);
        break;
    default:
        FcitxLog(DEBUG, "XIM_DEFAULT:\t\ticid=%d\tconnect_id=%d\t%d", ((IMForwardEventStruct *) call_data)->icid,
                 ((IMForwardEventStruct *) call_data)->connect_id, call_data->major_code);
        break;
    }

    switch (call_data->major_code) {
    case XIM_OPEN:
        return XIMOpenHandler(ximfrontend, (IMOpenStruct *) call_data);
    case XIM_CLOSE:
        return XIMCloseHandler(ximfrontend, (IMOpenStruct *) call_data);
    case XIM_CREATE_IC:
        return XIMCreateICHandler(ximfrontend, (IMChangeICStruct *) call_data);
    case XIM_DESTROY_IC:
        return XIMDestroyICHandler(ximfrontend, (IMChangeICStruct *) call_data);
    case XIM_SET_IC_VALUES:
        return XIMSetICValuesHandler(ximfrontend, (IMChangeICStruct *) call_data);
    case XIM_GET_IC_VALUES:
        return XIMGetICValuesHandler(ximfrontend, (IMChangeICStruct *) call_data);
    case XIM_FORWARD_EVENT:
        XIMProcessKey(ximfrontend, (IMForwardEventStruct *) call_data);
        return True;
    case XIM_SET_IC_FOCUS:
        return XIMSetFocusHandler(ximfrontend, (IMChangeFocusStruct *) call_data);
    case XIM_UNSET_IC_FOCUS:
        return XIMUnsetFocusHandler(ximfrontend, (IMChangeICStruct *) call_data);;
    case XIM_RESET_IC:
        return True;
    case XIM_PREEDIT_START_REPLY:
        return 0;
    case XIM_PREEDIT_CARET_REPLY:
        return 0;
    case XIM_SYNC_REPLY:
        return 0;
    default:
        return True;
    }
}

boolean XimDestroy(void* arg)
{
    FcitxXimFrontend* xim = (FcitxXimFrontend*) arg;
    /**
     * Destroy the window BEFORE(!!!!!) CloseIM!!!
     * Work arround for a bug in libX11. See wengxt's commit log:
     * f773dd4f7152a4b4b7f406fe01bff466e0de3dc2
     * [xim, x11] correctly shutdown xim, destroy x11 with error handling
     **/
    if (xim->xim_window) {
        XDestroyWindow(xim->display, xim->xim_window);
    }
    if (xim->ims) {
        IMCloseIM(xim->ims);
        xim->ims = NULL;
    }
    XimQueueDestroy(xim);
    free(xim);
    return true;
}
Example #8
0
void* ClassicUICreate(FcitxInstance* instance)
{
    FcitxAddon* classicuiaddon = FcitxAddonsGetAddonByName(FcitxInstanceGetAddons(instance), FCITX_CLASSIC_UI_NAME);
    FcitxModuleFunctionArg arg;
    FcitxClassicUI* classicui = fcitx_utils_malloc0(sizeof(FcitxClassicUI));
    classicui->owner = instance;
    if (!LoadClassicUIConfig(classicui)) {
        free(classicui);
        return NULL;
    }
    if (GetSkinDesc() == NULL) {
        free(classicui);
        return NULL;
    }
    classicui->dpy = InvokeFunction(instance, FCITX_X11, GETDISPLAY, arg);
    if (classicui->dpy == NULL) {
        free(classicui);
        return NULL;
    }

    if (LoadSkinConfig(&classicui->skin, &classicui->skinType)) {
        free(classicui);
        return NULL;
    }

    classicui->isfallback = FcitxUIIsFallback(instance, classicuiaddon);

    classicui->iScreen = DefaultScreen(classicui->dpy);

    classicui->protocolAtom = XInternAtom(classicui->dpy, "WM_PROTOCOLS", False);
    classicui->killAtom = XInternAtom(classicui->dpy, "WM_DELETE_WINDOW", False);


    InitSkinMenu(classicui);
    FcitxUIRegisterMenu(instance, &classicui->skinMenu);

    /* Main Menu Initial */
    FcitxMenuInit(&classicui->mainMenu);
    FcitxMenuAddMenuItem(&classicui->mainMenu, _("About Fcitx"), MENUTYPE_SIMPLE, NULL);
    FcitxMenuAddMenuItem(&classicui->mainMenu, _("Online Help"), MENUTYPE_SIMPLE, NULL);
    FcitxMenuAddMenuItem(&classicui->mainMenu, NULL, MENUTYPE_DIVLINE, NULL);

    FcitxUIMenu **menupp;
    UT_array* uimenus = FcitxInstanceGetUIMenus(instance);
    for (menupp = (FcitxUIMenu **) utarray_front(uimenus);
            menupp != NULL;
            menupp = (FcitxUIMenu **) utarray_next(uimenus, menupp)
        ) {
        FcitxUIMenu * menup = *menupp;
        if (!menup->isSubMenu)
            FcitxMenuAddMenuItem(&classicui->mainMenu, menup->name, MENUTYPE_SUBMENU, menup);
    }
    FcitxMenuAddMenuItem(&classicui->mainMenu, NULL, MENUTYPE_DIVLINE, NULL);
    FcitxMenuAddMenuItem(&classicui->mainMenu, _("Configure"), MENUTYPE_SIMPLE, NULL);
    FcitxMenuAddMenuItem(&classicui->mainMenu, _("Exit"), MENUTYPE_SIMPLE, NULL);
    classicui->mainMenu.MenuAction = MainMenuAction;
    classicui->mainMenu.priv = classicui;
    classicui->mainMenu.mark = -1;


    classicui->inputWindow = CreateInputWindow(classicui);
    classicui->mainWindow = CreateMainWindow(classicui);
    classicui->trayWindow = CreateTrayWindow(classicui);
    classicui->aboutWindow = CreateAboutWindow(classicui);
    classicui->messageWindow = CreateMessageWindow(classicui);
    classicui->mainMenuWindow = CreateMainMenuWindow(classicui);

    FcitxIMEventHook resethk;
    resethk.arg = classicui;
    resethk.func = ClassicUIInputReset;
    FcitxInstanceRegisterResetInputHook(instance, resethk);

    DisplaySkin(classicui, classicui->skinType);

    /* ensure order ! */
    AddFunction(classicuiaddon, ClassicUILoadImage);
    AddFunction(classicuiaddon, ClassicUIGetKeyBoardFontColor);
    AddFunction(classicuiaddon, ClassicUIGetFont);

    return classicui;
}
Example #9
0
void* DBusCreate(FcitxInstance* instance)
{
    FcitxDBus *dbusmodule = (FcitxDBus*) fcitx_utils_malloc0(sizeof(FcitxDBus));
    FcitxAddon* dbusaddon = FcitxAddonsGetAddonByName(FcitxInstanceGetAddons(instance), FCITX_DBUS_NAME);
    dbusmodule->owner = instance;

    DBusError err;

    if (FcitxInstanceIsTryReplace(instance)) {
        fcitx_utils_launch_tool("fcitx-remote", "-e");
        sleep(1);
    }

    dbus_threads_init_default();

    // first init dbus
    dbus_error_init(&err);

    int retry = 0;
    DBusConnection* conn = NULL;
    char* servicename = NULL;
    asprintf(&servicename, "%s-%d", FCITX_DBUS_SERVICE,
             fcitx_utils_get_display_number());

    /* do session dbus initialize */
    do {
        if (!getenv("DISPLAY") && !getenv("DBUS_SESSION_BUS_ADDRESS")) {
            FcitxLog(WARNING, "Without DISPLAY or DBUS_SESSION_BUS_ADDRESS session bus will not work");
            break;
        }
        /* try to get session dbus */
        while (1) {
            conn = dbus_bus_get(DBUS_BUS_SESSION, &err);
            if (dbus_error_is_set(&err)) {
                FcitxLog(WARNING, "Connection Error (%s)", err.message);
                dbus_error_free(&err);
                dbus_error_init(&err);
            }

            if (NULL == conn && retry < MAX_RETRY_TIMES) {
                retry ++;
                sleep(RETRY_INTERVAL * retry);
            } else {
                break;
            }
        }

        if (NULL == conn) {
            break;
        }

        if (!dbus_connection_add_filter(conn, DBusModuleFilter, dbusmodule, NULL))
            break;

        if (!dbus_connection_set_watch_functions(conn, DBusAddWatch, DBusRemoveWatch,
                NULL, &dbusmodule->watches, NULL)) {
            FcitxLog(WARNING, "Add Watch Function Error");
            dbus_error_free(&err);
            dbus_error_init(&err);
            dbus_connection_unref(conn);
            conn = NULL;
            break;
        }

        /* from here we know dbus connection is successful, now we need to register the service */
        dbus_connection_set_exit_on_disconnect(conn, FALSE);
        dbusmodule->conn = conn;

        boolean request_retry = false;

        int replaceCountdown = FcitxInstanceIsTryReplace(instance) ? 3 : 0;
        FcitxInstanceResetTryReplace(instance);
        do {
            request_retry = false;

            // request a name on the bus
            int ret = dbus_bus_request_name(conn, servicename,
                                            DBUS_NAME_FLAG_DO_NOT_QUEUE,
                                            &err);
            if (dbus_error_is_set(&err)) {
                FcitxLog(WARNING, "Name Error (%s)", err.message);
                goto dbus_init_failed;
            }
            if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) {
                FcitxLog(WARNING, "DBus Service Already Exists");

                if (replaceCountdown > 0) {
                    replaceCountdown --;
                    fcitx_utils_launch_tool("fcitx-remote", "-e");

                    /* sleep for a while and retry */
                    sleep(1);

                    request_retry = true;
                    continue;
                }

                /* if we know fcitx exists, we should exit. */
                dbus_error_free(&err);
                free(servicename);
                free(dbusmodule);

                FcitxInstanceEnd(instance);
                return NULL;
            }
        } while (request_retry);

        dbus_connection_flush(dbusmodule->conn);
    } while(0);

    DBusConnection* privconn = NULL;
    do {
        int noPrivateDBus = fcitx_utils_get_boolean_env("FCITX_NO_PRIVATE_DBUS", false);
        if (noPrivateDBus)
            break;

        char* file;
        FILE* dbusfp = FcitxXDGGetFileWithPrefix("dbus", "daemon.conf", "r", &file);
        if (dbusfp) {
            fclose(dbusfp);
        }
        else {
            free(file);
            file = NULL;
        }

        dbusmodule->daemon = DBusLaunch(file);
        fcitx_utils_free(file);
        if (dbusmodule->daemon.pid == 0)
            break;

        privconn = dbus_connection_open(dbusmodule->daemon.address, &err);

        if (dbus_error_is_set(&err)) {
            FcitxLog(ERROR, "Private dbus daemon connection error (%s)",
                     err.message);
            break;
        }

        dbus_bus_register(privconn, &err);

        if (dbus_error_is_set(&err)) {
            FcitxLog(ERROR, "Private dbus bus register error (%s)", err.message);
            break;
        }

        int ret = dbus_bus_request_name(privconn, servicename,
                                        DBUS_NAME_FLAG_DO_NOT_QUEUE,
                                        &err);

        if (dbus_error_is_set(&err)) {
            FcitxLog(WARNING, "Private Name Error (%s)", err.message);
            break;
        }
        if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) {
            FcitxLog(ERROR, "Private DBus Service Already Exists, fcitx being hacked?");
            break;
        }

        if (!dbus_connection_add_filter(privconn, DBusModuleFilter, dbusmodule, NULL))
            break;

        if (!dbus_connection_set_watch_functions(privconn, DBusAddWatch, DBusRemoveWatch,
                NULL, &dbusmodule->watches, NULL)) {
            FcitxLog(WARNING, "Add Watch Function Error");
            break;
        }

        char* addressFile = NULL;
        char* localMachineId = dbus_get_local_machine_id();
        asprintf(&addressFile, "%s-%d", localMachineId,
                 fcitx_utils_get_display_number());
        dbus_free(localMachineId);

        FILE* fp = FcitxXDGGetFileUserWithPrefix("dbus", addressFile, "w", NULL);
        free(addressFile);
        if (!fp)
            break;

        fprintf(fp, "%s", dbusmodule->daemon.address);
        fwrite("\0", sizeof(char), 1, fp);
        pid_t curPid = getpid();
        fwrite(&dbusmodule->daemon.pid, sizeof(pid_t), 1, fp);
        fwrite(&curPid, sizeof(pid_t), 1, fp);
        fclose(fp);

        dbusmodule->privconn = privconn;

        char* command = fcitx_utils_get_fcitx_path_with_filename("bindir", "/fcitx-dbus-watcher");
        char* pidstring = NULL;
        asprintf(&pidstring, "%d", dbusmodule->daemon.pid);
        char* args[] = {
            command,
            dbusmodule->daemon.address,
            pidstring,
            NULL
        };
        fcitx_utils_start_process(args);
        free(command);
        free(pidstring);

    } while(0);

    if (!dbusmodule->privconn) {
        if (privconn) {
            dbus_connection_unref(privconn);
            DBusKill(&dbusmodule->daemon);
        }
    }

    FcitxModuleAddFunction(dbusaddon, DBusGetConnection);
    FcitxModuleAddFunction(dbusaddon, DBusGetPrivateConnection);
    dbus_error_free(&err);

    dbusmodule->serviceName = servicename;

    return dbusmodule;

dbus_init_failed:
    dbus_error_free(&err);
    fcitx_utils_free(servicename);
    if (conn)
        dbus_connection_unref(conn);
    DBusKill(&dbusmodule->daemon);
    fcitx_utils_free(dbusmodule);
    return NULL;
}
Example #10
0
File: xim.c Project: areslp/fcitx
void* XimCreate(FcitxInstance* instance, int frontendid)
{
    if (ximfrontend != NULL)
        return NULL;
    FcitxXimFrontend* xim = fcitx_utils_malloc0(sizeof(FcitxXimFrontend));
    if (xim == NULL)
        return NULL;

    ximfrontend = xim;

    XIMStyles *input_styles;
    XIMEncodings *encodings;
    char *imname = NULL;
    char *p;

    xim->display = InvokeVaArgs(instance, FCITX_X11, GETDISPLAY);

    if (xim->display == NULL) {
        FcitxLog(FATAL, _("X11 not initialized"));
        free(xim);
        return NULL;
    }

    FcitxAddon* ximaddon = FcitxAddonsGetAddonByName(FcitxInstanceGetAddons(instance), "fcitx-xim");
    xim->x11addon = FcitxAddonsGetAddonByName(FcitxInstanceGetAddons(instance), "fcitx-x11");
    xim->iScreen = DefaultScreen(xim->display);
    xim->owner = instance;
    xim->frontendid = frontendid;

    xim->ximWindow = XCreateSimpleWindow(xim->display, DefaultRootWindow(xim->display), 0, 0, 1, 1, 1, 0, 0);
    if (xim->ximWindow == (Window) NULL) {
        FcitxLog(FATAL, _("Can't Create imWindow"));
        free(xim);
        return NULL;
    }

    if (!imname) {
        imname = getenv("XMODIFIERS");
        if (imname) {
            if (strstr(imname, "@im="))
                imname += 4;
            else {
                FcitxLog(WARNING, _("XMODIFIERS Error."));
                imname = DEFAULT_IMNAME;
            }
        } else {
            FcitxLog(WARNING, _("Please set XMODIFIERS."));
            imname = DEFAULT_IMNAME;
        }
    }
    XimQueueInit(xim);

    if (GetXimConfigDesc() == NULL)
        xim->bUseOnTheSpotStyle = false;
    else {
        FcitxConfigFileDesc* configDesc = GetXimConfigDesc();

        FILE *fp;
        char *file;
        fp = FcitxXDGGetFileUserWithPrefix("conf", "fcitx-xim.config", "r", &file);
        FcitxLog(DEBUG, "Load Config File %s", file);
        free(file);
        if (!fp) {
            if (errno == ENOENT) {
                char *file;
                FILE *fp2 = FcitxXDGGetFileUserWithPrefix("conf", "fcitx-xim.config", "w", &file);
                FcitxLog(DEBUG, "Save Config to %s", file);
                FcitxConfigSaveConfigFileFp(fp2, &xim->gconfig, configDesc);
                free(file);
                if (fp2)
                    fclose(fp2);
            }
        }

        FcitxConfigFile *cfile = FcitxConfigParseConfigFileFp(fp, configDesc);

        FcitxXimFrontendConfigBind(xim, cfile, configDesc);
        FcitxConfigBindSync((FcitxGenericConfig*)xim);

        if (fp)
            fclose(fp);
    }

    input_styles = (XIMStyles *) malloc(sizeof(XIMStyles));
    if (xim->bUseOnTheSpotStyle) {
        input_styles->count_styles = sizeof(OnTheSpot_Styles) / sizeof(XIMStyle) - 1;
        input_styles->supported_styles = OnTheSpot_Styles;
    } else {
        input_styles->count_styles = sizeof(OverTheSpot_Styles) / sizeof(XIMStyle) - 1;
        input_styles->supported_styles = OverTheSpot_Styles;
    }

    encodings = (XIMEncodings *) malloc(sizeof(XIMEncodings));
    encodings->count_encodings = sizeof(zhEncodings) / sizeof(XIMEncoding) - 1;
    encodings->supported_encodings = zhEncodings;

    p = getenv("LC_CTYPE");
    if (!p) {
        p = getenv("LC_ALL");
        if (!p)
            p = getenv("LANG");
    }
    if (p) {
        if (!strcasestr(strLocale, p)) {
            strcat(strLocale, ",");
            strcat(strLocale, p);
        }
    }

    xim->ims = IMOpenIM(xim->display,
                        IMModifiers, "Xi18n",
                        IMServerWindow, xim->ximWindow,
                        IMServerName, imname,
                        IMLocale, strLocale,
                        IMServerTransport, "X/",
                        IMInputStyles, input_styles,
                        IMEncodingList, encodings,
                        IMProtocolHandler, XimProtocolHandler,
                        IMFilterEventMask, KeyPressMask | KeyReleaseMask,
                        NULL);

    free(input_styles);
    free(encodings);

    if (xim->ims == (XIMS) NULL) {
        FcitxLog(ERROR, _("Start XIM error. Another XIM daemon named %s is running?"), imname);
        free(xim);
        FcitxInstanceEnd(instance);
        return NULL;
    }

    FcitxModuleAddFunction(ximaddon, XimConsumeQueue);

    return xim;
}
Example #11
0
/**
 * @brief initialize the extra input method
 *
 * @param arg
 * @return successful or not
 **/
__EXPORT_API
void* FcitxLibpinyinCreate (FcitxInstance* instance)
{
    FcitxLibpinyinAddonInstance* libpinyinaddon = (FcitxLibpinyinAddonInstance*) fcitx_utils_malloc0(sizeof(FcitxLibpinyinAddonInstance));
    bindtextdomain("fcitx-libpinyin", LOCALEDIR);
    libpinyinaddon->owner = instance;
    FcitxAddon* addon = FcitxAddonsGetAddonByName(FcitxInstanceGetAddons(instance), "fcitx-libpinyin");

    if (!LoadLibpinyinConfig(&libpinyinaddon->config))
    {
        free(libpinyinaddon);
        return NULL;
    }

    libpinyinaddon->pinyin = FcitxLibpinyinNew(libpinyinaddon, LPT_Pinyin);
    libpinyinaddon->shuangpin = FcitxLibpinyinNew(libpinyinaddon, LPT_Shuangpin);
    libpinyinaddon->zhuyin = FcitxLibpinyinNew(libpinyinaddon, LPT_Zhuyin);

    ConfigLibpinyin(libpinyinaddon);

    FcitxInstanceRegisterIM(instance,
                    libpinyinaddon->pinyin,
                    "pinyin-libpinyin",
                    _("Pinyin (LibPinyin)"),
                    "pinyin",
                    FcitxLibpinyinInit,
                    FcitxLibpinyinReset,
                    FcitxLibpinyinDoInput,
                    FcitxLibpinyinGetCandWords,
                    NULL,
                    FcitxLibpinyinSave,
                    ReloadConfigFcitxLibpinyin,
                    NULL,
                    5,
                    libpinyinaddon->config.bTraditionalDataForPinyin ? "zh_TW" : "zh_CN"
                   );

    FcitxInstanceRegisterIM(instance,
                    libpinyinaddon->shuangpin,
                    "shuangpin-libpinyin",
                    _("Shuangpin (LibPinyin)"),
                    "shuangpin",
                    FcitxLibpinyinInit,
                    FcitxLibpinyinReset,
                    FcitxLibpinyinDoInput,
                    FcitxLibpinyinGetCandWords,
                    NULL,
                    FcitxLibpinyinSave,
                    ReloadConfigFcitxLibpinyin,
                    NULL,
                    5,
                    libpinyinaddon->config.bTraditionalDataForPinyin ? "zh_TW" : "zh_CN"
                   );

    FcitxInstanceRegisterIM(instance,
                    libpinyinaddon->zhuyin,
                    "zhuyin-libpinyin",
                    _("Bopomofo (LibPinyin)"),
                    "bopomofo",
                    FcitxLibpinyinInit,
                    FcitxLibpinyinReset,
                    FcitxLibpinyinDoInput,
                    FcitxLibpinyinGetCandWords,
                    NULL,
                    FcitxLibpinyinSave,
                    ReloadConfigFcitxLibpinyin,
                    NULL,
                    5,
                    libpinyinaddon->config.bSimplifiedDataForZhuyin ? "zh_CN" : "zh_TW"
                   );

    FcitxModuleAddFunction(addon, LibpinyinSavePinyinWord);

    return libpinyinaddon;
}
Example #12
0
void* ClassicUICreate(FcitxInstance* instance)
{
    FcitxAddon* classicuiaddon = FcitxAddonsGetAddonByName(FcitxInstanceGetAddons(instance), FCITX_CLASSIC_UI_NAME);
    FcitxClassicUI* classicui = fcitx_utils_malloc0(sizeof(FcitxClassicUI));
    classicui->owner = instance;
    if (!LoadClassicUIConfig(classicui)) {
        free(classicui);
        return NULL;
    }
    if (GetSkinDesc() == NULL) {
        free(classicui);
        return NULL;
    }
    classicui->dpy = FcitxX11GetDisplay(instance);
    if (classicui->dpy == NULL) {
        free(classicui);
        return NULL;
    }

    FcitxX11GetDPI(instance, &classicui->dpi, NULL);
    if (classicui->dpi <= 0)
        classicui->dpi = 96;

    if (LoadSkinConfig(&classicui->skin, &classicui->skinType)) {
        free(classicui);
        return NULL;
    }

    classicui->isfallback = FcitxUIIsFallback(instance, classicuiaddon);

    classicui->iScreen = DefaultScreen(classicui->dpy);

    classicui->protocolAtom = XInternAtom(classicui->dpy, "WM_PROTOCOLS", False);
    classicui->killAtom = XInternAtom(classicui->dpy, "WM_DELETE_WINDOW", False);


    InitSkinMenu(classicui);
    FcitxUIRegisterMenu(instance, &classicui->skinMenu);
    /* Main Menu Initial */
    FcitxMenuInit(&classicui->mainMenu);
    classicui->mainMenu.UpdateMenu = UpdateMainMenu;
    classicui->mainMenu.MenuAction = MainMenuAction;
    classicui->mainMenu.priv = classicui;
    classicui->mainMenu.mark = -1;


    classicui->inputWindow = CreateInputWindow(classicui);
    classicui->mainWindow = CreateMainWindow(classicui);
    classicui->trayWindow = CreateTrayWindow(classicui);
    classicui->messageWindow = CreateMessageWindow(classicui);
    classicui->mainMenuWindow = CreateMainMenuWindow(classicui);

    FcitxIMEventHook resethk;
    resethk.arg = classicui;
    resethk.func = ClassicUIInputReset;
    FcitxInstanceRegisterResetInputHook(instance, resethk);

    DisplaySkin(classicui, classicui->skinType);

    /* ensure order ! */
    FcitxModuleAddFunction(classicuiaddon, ClassicUILoadImage);
    FcitxModuleAddFunction(classicuiaddon, ClassicUIGetKeyBoardFontColor);
    FcitxModuleAddFunction(classicuiaddon, ClassicUIGetFont);

    return classicui;
}