Пример #1
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;
}
Пример #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;

}
Пример #3
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;

}