Exemplo n.º 1
0
Arquivo: vk.c Projeto: areslp/fcitx
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;
}
Exemplo n.º 2
0
FCITX_EXPORT_API
FcitxInstance* FcitxInstanceCreateWithFD(sem_t *sem, int argc, char* argv[], int fd)
{
    FcitxInstance* instance = fcitx_utils_malloc0(sizeof(FcitxInstance));
    FcitxAddonsInit(&instance->addons);
    FcitxInstanceInitIM(instance);
    FcitxFrontendsInit(&instance->frontends);
    InitFcitxModules(&instance->modules);
    InitFcitxModules(&instance->eventmodules);
    utarray_init(&instance->uistats, &stat_icd);
    utarray_init(&instance->uicompstats, &compstat_icd);
    utarray_init(&instance->uimenus, &menup_icd);
    utarray_init(&instance->timeout, &timeout_icd);
    utarray_init(&instance->icdata, &icdata_icd);
    instance->input = FcitxInputStateCreate();
    instance->sem = sem;
    instance->config = fcitx_utils_malloc0(sizeof(FcitxGlobalConfig));
    instance->profile = fcitx_utils_malloc0(sizeof(FcitxProfile));
    instance->globalIMName = strdup("");
    if (fd > 0) {
        fcntl(fd, F_SETFL, O_NONBLOCK);
        instance->fd = fd;
    }

    if (!FcitxGlobalConfigLoad(instance->config))
        goto error_exit;

    FcitxCandidateWordSetPageSize(instance->input->candList, instance->config->iMaxCandWord);

    if (!ProcessOption(instance, argc, argv))
        goto error_exit;

    instance->timeStart = time(NULL);
    instance->globalState = instance->config->defaultIMState;
    instance->totaltime = 0;

    FcitxInitThread(instance);
    if (!FcitxProfileLoad(instance->profile, instance))
        goto error_exit;
    if (FcitxAddonGetConfigDesc() == NULL)
        goto error_exit;
    if (GetIMConfigDesc() == NULL)
        goto error_exit;

    FcitxAddonsLoad(&instance->addons);
    FcitxInstanceFillAddonOwner(instance, NULL);
    FcitxInstanceResolveAddonDependency(instance);
    FcitxInstanceInitBuiltInHotkey(instance);
    FcitxInstanceInitBuiltContext(instance);
    FcitxModuleLoad(instance);
    if (instance->loadingFatalError)
        return instance;
    if (!FcitxInstanceLoadAllIM(instance)) {
        FcitxInstanceEnd(instance);
        return instance;
    }

    FcitxInstanceInitIMMenu(instance);
    FcitxUIRegisterMenu(instance, &instance->imMenu);
    FcitxUIRegisterStatus(instance, instance, "remind",
                           instance->profile->bUseRemind ? _("Use remind") :  _("No remind"),
                          _("Toggle Remind"), ToggleRemindState, GetRemindEnabled);
    FcitxUISetStatusVisable(instance, "remind",  false);

    FcitxUILoad(instance);

    instance->iIMIndex = FcitxInstanceGetIMIndexByName(instance, instance->profile->imName);

    FcitxInstanceSwitchIMByIndex(instance, instance->iIMIndex);

    if (!FcitxInstanceLoadFrontend(instance)) {
        FcitxInstanceEnd(instance);
        return instance;
    }

    /* make in order to use block X, query is not good here */
    pthread_create(&instance->pid, NULL, RunInstance, instance);

    return instance;

error_exit:
    FcitxInstanceEnd(instance);
    return instance;

}
Exemplo n.º 3
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;
}
Exemplo n.º 4
0
void* RunInstance(void* arg)
{
    FcitxInstance* instance = (FcitxInstance*) arg;
    FcitxAddonsInit(&instance->addons);
    FcitxInstanceInitIM(instance);
    FcitxInstanceInitNoPreeditApps(instance);
    FcitxFrontendsInit(&instance->frontends);
    InitFcitxModules(&instance->modules);
    InitFcitxModules(&instance->eventmodules);
    utarray_init(&instance->uistats, &stat_icd);
    utarray_init(&instance->uicompstats, &compstat_icd);
    utarray_init(&instance->uimenus, fcitx_ptr_icd);
    utarray_init(&instance->timeout, &timeout_icd);
    utarray_init(&instance->icdata, &icdata_icd);
    instance->input = FcitxInputStateCreate();
    instance->config = fcitx_utils_malloc0(sizeof(FcitxGlobalConfig));
    instance->profile = fcitx_utils_malloc0(sizeof(FcitxProfile));
    instance->globalIMName = strdup("");
    if (instance->fd >= 0) {
        fcntl(instance->fd, F_SETFL, O_NONBLOCK);
    } else {
        instance->fd = -1;
    }

    if (!FcitxGlobalConfigLoad(instance->config))
        goto error_exit;

    FcitxCandidateWordSetPageSize(instance->input->candList, instance->config->iMaxCandWord);

    int overrideDelay = instance->overrideDelay;

    if (overrideDelay < 0)
        overrideDelay = instance->config->iDelayStart;

    if (overrideDelay > 0)
        sleep(overrideDelay);

    instance->timeStart = time(NULL);
    instance->globalState = instance->config->defaultIMState;
    instance->totaltime = 0;

    FcitxInitThread(instance);
    if (!FcitxProfileLoad(instance->profile, instance))
        goto error_exit;
    if (FcitxAddonGetConfigDesc() == NULL)
        goto error_exit;
    if (GetIMConfigDesc() == NULL)
        goto error_exit;

    FcitxAddonsLoad(&instance->addons);
    FcitxInstanceFillAddonOwner(instance, NULL);
    FcitxInstanceResolveAddonDependency(instance);
    FcitxInstanceInitBuiltInHotkey(instance);
    FcitxInstanceInitBuiltContext(instance);
    FcitxModuleLoad(instance);
    if (instance->loadingFatalError)
        return NULL;
    if (!FcitxInstanceLoadAllIM(instance)) {
        goto error_exit;
    }

    FcitxInstanceInitIMMenu(instance);
    FcitxUIRegisterMenu(instance, &instance->imMenu);
    FcitxUIRegisterStatus(instance, instance, "remind",
                           instance->profile->bUseRemind ? _("Use remind") :  _("No remind"),
                          _("Toggle Remind"), ToggleRemindState, GetRemindEnabled);
    FcitxUISetStatusVisable(instance, "remind",  false);

    FcitxUILoad(instance);

    instance->iIMIndex = FcitxInstanceGetIMIndexByName(instance, instance->profile->imName);
    if (instance->iIMIndex < 0) {
        instance->iIMIndex = 0;
    }

    FcitxInstanceSwitchIMByIndex(instance, instance->iIMIndex);

    if (!FcitxInstanceLoadFrontend(instance)) {
        goto error_exit;
    }

    /* fcitx is running in a standalone thread or not */
    if (instance->sem) {
        sem_post(&instance->notifySem);
        sem_wait(&instance->startUpSem);
    } else {
        instance->initialized = true;
    }

    uint64_t curtime = 0;
    while (1) {
        FcitxAddon** pmodule;
        uint8_t signo = 0;
        if (instance->fd >= 0) {
            while (read(instance->fd, &signo, sizeof(char)) > 0) {
                if (signo == SIGINT || signo == SIGTERM || signo == SIGQUIT || signo == SIGXCPU)
                    FcitxInstanceEnd(instance);
                else if (signo == SIGHUP)
                    FcitxInstanceRestart(instance);
                else if (signo == SIGUSR1)
                    FcitxInstanceReloadConfig(instance);
            }
        }
        do {
            instance->eventflag &= (~FEF_PROCESS_EVENT_MASK);
            for (pmodule = (FcitxAddon**) utarray_front(&instance->eventmodules);
                  pmodule != NULL;
                  pmodule = (FcitxAddon**) utarray_next(&instance->eventmodules, pmodule)) {
                FcitxModule* module = (*pmodule)->module;
                module->ProcessEvent((*pmodule)->addonInstance);
            }
            struct timeval current_time;
            gettimeofday(&current_time, NULL);
            curtime = (current_time.tv_sec * 1000LL) + (current_time.tv_usec / 1000LL);

            unsigned int idx = 0;
            while(idx < utarray_len(&instance->timeout))
            {
                TimeoutItem* ti = (TimeoutItem*) utarray_eltptr(&instance->timeout, idx);
                uint64_t id = ti->idx;
                if (ti->time + ti->milli <= curtime) {
                    ti->callback(ti->arg);
                    ti = (TimeoutItem*) utarray_eltptr(&instance->timeout, idx);
                    /* faster remove */
                    if (ti && ti->idx == id)
                        utarray_remove_quick(&instance->timeout, idx);
                    else {
                        FcitxInstanceRemoveTimeoutById(instance, id);
                        idx = 0;
                    }
                }
                else {
                    idx++;
                }
            }

            if (instance->eventflag & FEF_UI_MOVE)
                FcitxUIMoveInputWindowReal(instance);

            if (instance->eventflag & FEF_UI_UPDATE)
                FcitxUIUpdateInputWindowReal(instance);
        } while ((instance->eventflag & FEF_PROCESS_EVENT_MASK) != FEF_NONE);

        setjmp(FcitxRecover);

        if (instance->destroy || instance->restart) {
            FcitxInstanceRealEnd(instance);
            break;
        }
        
        if (instance->eventflag & FEF_RELOAD_ADDON) {
            instance->eventflag &= ~(FEF_RELOAD_ADDON);
            FcitxInstanceReloadAddon(instance);
        }

        FD_ZERO(&instance->rfds);
        FD_ZERO(&instance->wfds);
        FD_ZERO(&instance->efds);

        instance->maxfd = 0;
        if (instance->fd > 0) {
            instance->maxfd = instance->fd;
            FD_SET(instance->fd, &instance->rfds);
        }
        for (pmodule = (FcitxAddon**) utarray_front(&instance->eventmodules);
              pmodule != NULL;
              pmodule = (FcitxAddon**) utarray_next(&instance->eventmodules, pmodule)) {
            FcitxModule* module = (*pmodule)->module;
            module->SetFD((*pmodule)->addonInstance);
        }
        if (instance->maxfd == 0)
            break;
        struct timeval tval;
        struct timeval* ptval = NULL;
        if (utarray_len(&instance->timeout) != 0) {
            unsigned long int min_time = LONG_MAX;
            TimeoutItem* ti;
            for (ti = (TimeoutItem*)utarray_front(&instance->timeout);ti;
                 ti = (TimeoutItem*)utarray_next(&instance->timeout, ti)) {
                if (ti->time + ti->milli - curtime < min_time) {
                    min_time = ti->time + ti->milli - curtime;
                }
            }
            tval.tv_usec = (min_time % 1000) * 1000;
            tval.tv_sec = min_time / 1000;
            ptval = &tval;
        }
        select(instance->maxfd + 1, &instance->rfds, &instance->wfds,
               &instance->efds, ptval);
    }
    if (instance->restart) {
        fcitx_utils_restart_in_place();
    }

    return NULL;

error_exit:
    sem_post(&instance->startUpSem);
    FcitxInstanceEnd(instance);
    return NULL;
}
Exemplo n.º 5
0
static void* FcitxRimeCreate(FcitxInstance* instance)
{
    FcitxRime* rime = (FcitxRime*) fcitx_utils_malloc0(sizeof(FcitxRime));
    rime->owner = instance;
    rime->api = rime_get_api();
    rime->firstRun = true;
    if (!rime->api) {
        free(rime);
        return NULL;
    }

    FcitxRimeStart(rime, false);

    FcitxIMIFace iface;
    memset(&iface, 0, sizeof(FcitxIMIFace));
    iface.Init = FcitxRimeInit;
    iface.ResetIM = FcitxRimeReset;
    iface.DoInput = FcitxRimeDoInput;
    iface.DoReleaseInput = FcitxRimeDoReleaseInput;
    iface.GetCandWords = FcitxRimeGetCandWords;
    iface.ReloadConfig = FcitxRimeReloadConfig;

    FcitxInstanceRegisterIMv2(
        instance,
        rime,
        "rime",
        _("Rime"),
        "rime",
        iface,
        10,
        "zh"
    );

    FcitxUIRegisterComplexStatus(
        instance,
        rime,
        "rime-enzh",
        "",
        "",
        FcitxRimeToggleEnZh,
        FcitxRimeGetIMIcon);

    FcitxUIRegisterComplexStatus(
        instance,
        rime,
        "rime-deploy",
        _("Deploy"),
        _("Deploy"),
        FcitxRimeToggleDeploy,
        FcitxRimeGetDeployIcon);

    FcitxUIRegisterComplexStatus(
        instance,
        rime,
        "rime-sync",
        _("Synchronize"),
        _("Synchronize"),
        FcitxRimeToggleSync,
        FcitxRimeGetSyncIcon);

    FcitxUISetStatusVisable(instance, "rime-enzh", false);
    FcitxUISetStatusVisable(instance, "rime-sync", false);
    FcitxUISetStatusVisable(instance, "rime-deploy", false);
    FcitxIMEventHook hk;
    hk.arg = rime;
    hk.func = FcitxRimeResetUI;

    FcitxInstanceRegisterResetInputHook(instance, hk);
    
    FcitxMenuInit(&rime->schemamenu);
    rime->schemamenu.name = strdup(_("Schema List"));
    rime->schemamenu.candStatusBind = strdup("rime-enzh");
    rime->schemamenu.MenuAction = FcitxRimeSchemaMenuAction;
    rime->schemamenu.UpdateMenu = FcitxRimeSchemaMenuUpdate;
    rime->schemamenu.priv = rime;
    rime->schemamenu.isSubMenu = false;
    FcitxUIRegisterMenu(rime->owner, &rime->schemamenu);

    return rime;
}
Exemplo n.º 6
0
FCITX_EXPORT_API
FcitxInstance* FcitxInstanceCreate(sem_t *sem, int argc, char* argv[])
{
    FcitxInstance* instance = fcitx_utils_malloc0(sizeof(FcitxInstance));
    FcitxAddonsInit(&instance->addons);
    FcitxInstanceInitIM(instance);
    FcitxFrontendsInit(&instance->frontends);
    InitFcitxModules(&instance->eventmodules);
    utarray_init(&instance->uistats, &stat_icd);
    utarray_init(&instance->uimenus, &menup_icd);
    instance->input = FcitxInputStateCreate();
    instance->sem = sem;
    instance->config = fcitx_utils_malloc0(sizeof(FcitxGlobalConfig));
    instance->profile = fcitx_utils_malloc0(sizeof(FcitxProfile));

    if (!FcitxGlobalConfigLoad(instance->config))
        goto error_exit;

    FcitxCandidateWordSetPageSize(instance->input->candList, instance->config->iMaxCandWord);

    if (!ProcessOption(instance, argc, argv))
        goto error_exit;

    instance->timeStart = time(NULL);
    instance->globalState = instance->config->defaultIMState;
    instance->totaltime = 0;

    FcitxInitThread(instance);
    if (!FcitxProfileLoad(instance->profile, instance))
        goto error_exit;
    if (FcitxAddonGetConfigDesc() == NULL)
        goto error_exit;
    if (GetIMConfigDesc() == NULL)
        goto error_exit;

    FcitxAddonsLoad(&instance->addons);

    /* FIXME: a walkaround for not have instance in function FcitxModuleInvokeFunction */
    FcitxAddon* addon;
    for (addon = (FcitxAddon *) utarray_front(&instance->addons);
            addon != NULL;
            addon = (FcitxAddon *) utarray_next(&instance->addons, addon)) {
        addon->owner = instance;
    }
    FcitxInstanceResolveAddonDependency(instance);
    FcitxInstanceInitBuiltInHotkey(instance);
    FcitxInstanceInitBuiltContext(instance);
    FcitxModuleLoad(instance);
    if (!FcitxInstanceLoadAllIM(instance)) {
        FcitxInstanceEnd(instance);
        return instance;
    }

    FcitxInstanceInitIMMenu(instance);
    FcitxUIRegisterMenu(instance, &instance->imMenu);
    FcitxUIRegisterStatus(instance, instance, "remind", _("Remind"), _("Remind"), ToggleRemindState, GetRemindEnabled);

    FcitxUILoad(instance);

    instance->iIMIndex = FcitxInstanceGetIMIndexByName(instance, instance->profile->imName);

    FcitxInstanceSwitchIM(instance, instance->iIMIndex);
    instance->lastIMIndex = instance->iIMIndex;

    if (!FcitxInstanceLoadFrontend(instance)) {
        FcitxInstanceEnd(instance);
        return instance;
    }

    if (instance->config->bFirstRun) {
        instance->config->bFirstRun = false;
        FcitxGlobalConfigSave(instance->config);

        const char *imname = "fcitx";
        char *strTemp;
        asprintf(&strTemp, "@im=%s", imname);

        if ((getenv("XMODIFIERS") != NULL && CHECK_ENV("XMODIFIERS", strTemp, true)) ||
                (CHECK_ENV("GTK_IM_MODULE", "xim", false) && CHECK_ENV("GTK_IM_MODULE", "fcitx", false))
                || (CHECK_ENV("QT_IM_MODULE", "xim", false) && CHECK_ENV("QT_IM_MODULE", "fcitx", false))) {
            char *msg[12];
            msg[0] = _("Please check your environment varibles.");
            msg[1] = _("You can use tools provided by your distribution.");
            msg[2] = _("Or You may need to set environment varibles below to make fcitx work correctly.");
            msg[3] = "export XMODIFIERS=\"@im=fcitx\"";
            msg[4] = "export QT_IM_MODULE=xim";
            msg[5] = "export GTK_IM_MODULE=xim";
            msg[6] = _("Or (Depends on you install im module or not)");
            msg[7] = "export XMODIFIERS=\"@im=fcitx\"";
            msg[8] = "export QT_IM_MODULE=fcitx";
            msg[9] = "export GTK_IM_MODULE=fcitx";
            msg[10] = _("If you use login manager like gdm or kdm, put those lines in your ~/.xprofile.");
            msg[11] = _("If you use ~/.xinitrc and startx, put those lines in ~/.xinitrc.");

            FcitxUIDisplayMessage(instance, _("Setting Hint"), msg, 12);
        }

        free(strTemp);
    }
    /* make in order to use block X, query is not good here */
    pthread_create(&instance->pid, NULL, RunInstance, instance);

    return instance;

error_exit:
    FcitxInstanceEnd(instance);
    return instance;

}
Exemplo n.º 7
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;
}