示例#1
0
文件: classicui.c 项目: adaptee/fcitx
boolean MainMenuAction(FcitxUIMenu* menu, int index)
{
    FcitxClassicUI* classicui = (FcitxClassicUI*) menu->priv;
    FcitxInstance* instance = classicui->owner;
    int length = utarray_len(&menu->shell);
    if (index == 0) {
        char* args[] = {
            "xdg-open",
            "http://fcitx-im.org/",
            0
        };
        fcitx_utils_start_process(args);
    } else if (index == length - 1) { /* Exit */
        FcitxInstanceEnd(classicui->owner);
    } else if (index == length - 2) { /* Restart */
        fcitx_utils_launch_restart();
    } else if (index == length - 3) { /* Configuration */
        fcitx_utils_launch_configure_tool();
    } else if (index == length - 4) { /* Configuration */
        FcitxIM* im = FcitxInstanceGetCurrentIM(classicui->owner);
        if (im && im->owner) {
            fcitx_utils_launch_configure_tool_for_addon(im->uniqueName);
        }
        else {
            fcitx_utils_launch_configure_tool();
        }
    } else {
        FcitxMenuItem* item = (FcitxMenuItem*) utarray_eltptr(&menu->shell, index);
        if (item && item->type == MENUTYPE_SIMPLE && item->data) {
            const char* name = item->data;
            FcitxUIUpdateStatus(instance, name);
        }
    }
    return true;
}
示例#2
0
文件: instance.c 项目: vx13/fcitx
void* RunInstance(void* arg)
{
    FcitxInstance* instance = (FcitxInstance*) arg;
    instance->initialized = true;
    int64_t curtime = 0;
    while (1) {
        FcitxAddon** pmodule;
        uint8_t signo = 0;
        while (read(instance->fd, &signo, sizeof(char)) > 0) {
            if (signo == SIGINT || signo == SIGTERM || signo == SIGQUIT)
                FcitxInstanceEnd(instance);
            else if (signo == SIGHUP)
                fcitx_utils_launch_restart();
            else if (signo == SIGUSR1)
                FcitxInstanceReloadConfig(instance);
        }
        do {
            instance->uiflag = UI_NONE;
            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);

            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->uiflag & UI_MOVE)
                FcitxUIMoveInputWindowReal(instance);

            if (instance->uiflag & UI_UPDATE)
                FcitxUIUpdateInputWindowReal(instance);
        } while (instance->uiflag != UI_NONE);

        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) {
            long int min_time = LONG_MAX;
            TimeoutItem* ti;
            for (ti = (TimeoutItem*) utarray_front(&instance->timeout);
                 ti != NULL;
                 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);
    }
    return NULL;
}
示例#3
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);

    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)
                    fcitx_utils_launch_restart();
                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) {
            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);
    }
    return NULL;

error_exit:
    sem_post(&instance->startUpSem);
    FcitxInstanceEnd(instance);
    return NULL;
}
示例#4
0
void FcitxDBusMenuDoEvent(void* arg)
{
    FcitxNotificationItem* notificationitem = (FcitxNotificationItem*) arg;
    FcitxInstance* instance = notificationitem->owner;

    int32_t id = notificationitem->pendingActionId;
    notificationitem->pendingActionId = -1;

    int32_t menu = ACTION_MENU(id);
    int32_t index = ACTION_INDEX(id);
    if (index <= 0)
        return;

    if (menu == 0) {
        if (index <= 8 && index > 0) {
            switch(index) {
                case 1:
                    {
                        char* args[] = {
                            "xdg-open",
                            "http://fcitx-im.org/",
                            0
                        };
                        fcitx_utils_start_process(args);
                    }
                    break;
                case 4:
                    {
                        FcitxIM* im = FcitxInstanceGetCurrentIM(instance);
                        if (im && im->owner) {
                            fcitx_utils_launch_configure_tool_for_addon(im->uniqueName);
                        }
                        else {
                            fcitx_utils_launch_configure_tool();
                        }
                    }
                    break;
                case 5:
                    fcitx_utils_launch_configure_tool();
                    break;
                case 6:
                    fcitx_utils_launch_restart();
                    break;
                case 7:
                    FcitxInstanceEnd(instance);
                    break;
            }
        } else {
            int index = STATUS_INDEX(id);
            const char* name = NULL;
            if (STATUS_ISCOMP(id)) {
                UT_array* uicompstats = FcitxInstanceGetUIComplexStats(instance);
                FcitxUIComplexStatus* compstatus = (FcitxUIComplexStatus*) utarray_eltptr(uicompstats, index);
                if (compstatus) {
                    name = compstatus->name;
                }
            } else {
                UT_array* uistats = FcitxInstanceGetUIStats(instance);
                FcitxUIStatus* status = (FcitxUIStatus*) utarray_eltptr(uistats, index);
                if (status) {
                    name = status->name;
                }
            }
            if (name) {
                FcitxUIUpdateStatus(instance, name);
            }
        }
    } else if (menu > 0) {
        UT_array* uimenus = FcitxInstanceGetUIMenus(instance);
        FcitxUIMenu** menup = (FcitxUIMenu**) utarray_eltptr(uimenus, menu - 1), *menu;
        if (!menup)
            return;
        menu = *menup;
        if (menu->MenuAction) {
            menu->MenuAction(menu, index - 1);
        }
    }
}