示例#1
0
文件: classicui.c 项目: adaptee/fcitx
static void ClassicUIRegisterStatus(void *arg, FcitxUIStatus* status)
{
    FcitxClassicUI* classicui = (FcitxClassicUI*) arg;
    FcitxSkin* sc = &classicui->skin;
    status->uipriv[classicui->isfallback] = fcitx_utils_new(FcitxClassicUIStatus);
    char *name;

    fcitx_utils_alloc_cat_str(name, status->name, "_active.png");
    LoadImage(sc, name, false);
    free(name);

    fcitx_utils_alloc_cat_str(name, status->name, "_inactive.png");
    LoadImage(sc, name, false);
    free(name);
}
示例#2
0
文件: lua.c 项目: farseerfc/fcitx
static void* LuaCallCommand(void* arg, FcitxModuleFunctionArg args) {
    LuaModule *luamodule = (LuaModule *)arg;
    UT_array *result = InputCommand(luamodule, (const char *)args.args[0]);
    if (result) {
        FcitxInputState* input = FcitxInstanceGetInputState(GetFcitx(luamodule));
        LuaResultItem *p = NULL;
        while ((p = (LuaResultItem *)utarray_next(result, p))) {
            FcitxCandidateWord candWord;
            if (args.args[1] && args.args[2]) {
                candWord.callback = args.args[1];
                candWord.owner = args.args[2];
            }
            else {
                candWord.callback = LuaGetCandWord;
                candWord.owner = luamodule;
            }
            candWord.priv = p->help ? strdup(p->help) : NULL;
            if (p->help || p->tip) {
                fcitx_utils_alloc_cat_str(candWord.strExtra, p->help,
                                          p->help && p->tip ? " " : "",
                                          p->tip);
            } else {
                candWord.strExtra = NULL;
            }
            candWord.strWord = strdup(p->result);
            candWord.wordType = MSG_TIPS;
            candWord.extraType = MSG_CODE;
            FcitxCandidateWordAppend(FcitxInputStateGetCandidateList(input), &candWord);
        }
        utarray_free(result);
    }
    return NULL;
}
示例#3
0
文件: unicode.c 项目: HenryHu/fcitx
INPUT_RETURN_VALUE UnicodeGetCandWords(UnicodeModule* uni)
{
    FcitxInputState *input = FcitxInstanceGetInputState(uni->owner);
    FcitxInstanceCleanInputWindow(uni->owner);
    FcitxMessagesAddMessageStringsAtLast(FcitxInputStateGetPreedit(input),
                                         MSG_INPUT, uni->buffer);
    FcitxInputStateSetShowCursor(input, true);
    FcitxInputStateSetCursorPos(input, strlen(uni->buffer));

    FcitxCandidateWordList* candList = FcitxInputStateGetCandidateList(input);
    FcitxCandidateWordSetLayoutHint(candList, CLH_Vertical);

    UT_array* result = CharSelectDataFind(uni->charselectdata, uni->buffer);
    utarray_foreach(c, result, uint32_t) {
        char* s = fcitx_utils_malloc0(sizeof(char) * (UTF8_MAX_LENGTH + 1));
        fcitx_ucs4_to_utf8(*c, s);
        FcitxCandidateWord candWord;
        candWord.callback = UnicodeGetCandWord;
        candWord.owner = uni;
        candWord.priv = NULL;
        candWord.extraType = MSG_OTHER;
        candWord.wordType = MSG_CODE;
        candWord.strWord = s;
        char* name = CharSelectDataName(uni->charselectdata, *c);
        fcitx_utils_alloc_cat_str(candWord.strExtra, " ", name);
        free(name);
        FcitxCandidateWordAppend(candList, &candWord);
    }
示例#4
0
文件: xkbdbus.c 项目: HenryHu/fcitx
void FcitxXkbDBusGetLayouts(FcitxXkbDBus* xkbdbus, DBusMessage* message)
{
    DBusMessageIter iter, sub;
    dbus_message_iter_init_append(message, &iter);

    dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(ssss)", &sub);

    FcitxXkbRules* rules = xkbdbus->rules;
    FcitxIsoCodes* isocodes = xkbdbus->isocodes;
    char* lang = NULL;
#define GET_LANG \
    do { \
        char** plang = NULL; \
        plang = (char**) utarray_front(layoutInfo->languages); \
        lang = NULL; \
        if (plang) { \
            FcitxIsoCodes639Entry* entry = FcitxIsoCodesGetEntry(isocodes, *plang); \
            if (entry) { \
                lang = entry->iso_639_1_code; \
            } \
        } \
    } while (0)

    if (rules) {
        FcitxXkbLayoutInfo* layoutInfo;
        for (layoutInfo = (FcitxXkbLayoutInfo*) utarray_front(rules->layoutInfos);
            layoutInfo != NULL;
            layoutInfo = (FcitxXkbLayoutInfo*) utarray_next(rules->layoutInfos, layoutInfo))
        {
            char* description = dgettext("xkeyboard-config",
                                         layoutInfo->description);
            GET_LANG;
            FcitxXkbDBusAppendLayout(&sub, layoutInfo->name, "",
                                     description, lang);
            FcitxXkbVariantInfo* variantInfo;
            for (variantInfo = (FcitxXkbVariantInfo*) utarray_front(layoutInfo->variantInfos);
                variantInfo != NULL;
                variantInfo = (FcitxXkbVariantInfo*) utarray_next(layoutInfo->variantInfos, variantInfo))
            {
                char *description;
                fcitx_utils_alloc_cat_str(
                    description,
                    dgettext("xkeyboard-config", layoutInfo->description),
                    " - ",
                    dgettext("xkeyboard-config", variantInfo->description));
                GET_LANG;
                FcitxXkbDBusAppendLayout(&sub, layoutInfo->name,
                                         variantInfo->name, description, lang);
                free(description);
            }
        }
    }
    else {
        char *description = dgettext("xkeyboard-config", "English (US)");
        FcitxXkbDBusAppendLayout(&sub, "us", "", description, "en");
    }
    dbus_message_iter_close_container(&iter, &sub);
}
示例#5
0
void _fcitx_compose_table_find_compose_file(FcitxComposeTable* table)
{
    bool found = false;
    char* env;
    // check if XCOMPOSEFILE points to a Compose file
    if ((env = getenv("XCOMPOSEFILE")) != NULL) {
        // TODO: check end with
        found = _fcitx_compose_table_process_file(table, env);
    }
    // check if user’s home directory has a file named .XCompose
    if (!found && table->state == FCTS_NoErrors) {
        do {
            char* home = getenv("HOME");
            if (!home) {
                break;
            }
            char* composeFile;
            fcitx_utils_alloc_cat_str(composeFile, home, "/.XCompose");
            found = _fcitx_compose_table_process_file(table, composeFile);
            free(composeFile);
        } while(0);
    }
    // check for the system provided compose files
    if (!found && table->state == FCTS_NoErrors) {
        _fcitx_compose_table_read_locale_mappings(table);
        if (table->state == FCTS_NoErrors) {
            char* item;
            if (!fcitx_dict_lookup_by_str(table->localeToTable, table->locale, (void**) &item)) {
                table->state = FCTS_UnsupportedLocale;
            } else {
                char* composeFile;
                fcitx_utils_alloc_cat_str(composeFile, table->systemComposeDir, "/", item);
                found = _fcitx_compose_table_process_file(table, composeFile);
                free(composeFile);
            }
        }
    }
    if (found && utarray_len(table->composeTable) == 0) {
        table->state = FCTS_EmptyTable;
    }
    if (!found) {
        table->state = FCTS_MissingComposeFile;
    }
}
示例#6
0
文件: utils.c 项目: ascetic85/fcitx
FCITX_EXPORT_API
char* fcitx_utils_get_fcitx_path(const char* type)
{
    char* fcitxdir = getenv("FCITXDIR");
    char* result = NULL;
    if (strcmp(type, "datadir") == 0) {
        if (fcitxdir) {
            fcitx_utils_alloc_cat_str(result, fcitxdir, "/share");
        } else {
            result = strdup(DATADIR);
        }
    }
    else if (strcmp(type, "pkgdatadir") == 0) {
        if (fcitxdir) {
            fcitx_utils_alloc_cat_str(result, fcitxdir, "/share/"PACKAGE);
        } else {
            result = strdup(PKGDATADIR);
        }
    }
    else if (strcmp(type, "bindir") == 0) {
        if (fcitxdir) {
            fcitx_utils_alloc_cat_str(result, fcitxdir, "/bin");
        }
        else
            result = strdup(BINDIR);
    }
    else if (strcmp(type, "libdir") == 0) {
        if (fcitxdir) {
            fcitx_utils_alloc_cat_str(result, fcitxdir, "/lib");
        }
        else
            result = strdup(LIBDIR);
    }
    else if (strcmp(type, "localedir") == 0) {
        if (fcitxdir) {
            fcitx_utils_alloc_cat_str(result, fcitxdir, "/share/locale");
        }
        else
            result = strdup(LOCALEDIR);
    }
    return result;
}
示例#7
0
文件: utils.c 项目: ascetic85/fcitx
FCITX_EXPORT_API
char* fcitx_utils_get_fcitx_path_with_filename(const char* type, const char* filename)
{
    char* path = fcitx_utils_get_fcitx_path(type);
    if (path == NULL)
        return NULL;
    char *result;
    fcitx_utils_alloc_cat_str(result, path, "/", filename);
    free(path);
    return result;
}
示例#8
0
/**
 * Open the dict file, return -1 if failed.
 **/
static int
SpellCustomGetSysDictFile(FcitxSpell *spell, const char *lang)
{
    int fd;
    char *path;
    char *fname;
    path = fcitx_utils_get_fcitx_path("pkgdatadir");
    fcitx_utils_alloc_cat_str(fname, path, "/data/", lang, "_dict.fscd");
    free(path);
    fd = open(fname, O_RDONLY);
    free(fname);
    return fd;
}
示例#9
0
文件: addon.c 项目: rwdxll/fcitx5
void* _fcitx_library_get_symbol(FcitxLibrary* library, const char* addonName, const char* symbolName)
{
    char *p;
    char *escapedAddonName;
    fcitx_utils_alloc_cat_str(escapedAddonName, addonName, "_", symbolName);
    for (p = escapedAddonName;*p;p++) {
        if (*p == '-') {
            *p = '_';
        }
    }
    void *result = fcitx_library_resolve(library, escapedAddonName);
    free(escapedAddonName);
    return result;
}
示例#10
0
文件: addon.c 项目: JackChen007/fcitx
void* FcitxGetSymbol(void* handle, const char* addonName, const char* symbolName)
{
    char *p;
    char *escapedAddonName;
    fcitx_utils_alloc_cat_str(escapedAddonName, addonName, "_", symbolName);
    for (p = escapedAddonName;*p;p++) {
        if (*p == '-') {
            *p = '_';
        }
    }
    void *result = dlsym(handle, escapedAddonName);
    free(escapedAddonName);
    if (!result)
        return dlsym(handle, symbolName);
    return result;
}
示例#11
0
文件: skin.c 项目: areslp/fcitx
void LoadSkinDirectory(FcitxClassicUI* classicui)
{
    UT_array* skinBuf = &classicui->skinBuf;
    utarray_clear(skinBuf);
    int i ;
    DIR *dir;
    struct dirent *drt;
    struct stat fileStat;
    size_t len;
    char **skinPath = FcitxXDGGetPathWithPrefix(&len, "skin");
    for (i = 0; i < len; i++) {
        dir = opendir(skinPath[i]);
        if (dir == NULL)
            continue;

        while ((drt = readdir(dir)) != NULL) {
            if (strcmp(drt->d_name , ".") == 0 ||
                    strcmp(drt->d_name, "..") == 0)
                continue;
            char *pathBuf;
            fcitx_utils_alloc_cat_str(pathBuf, skinPath[i], "/", drt->d_name);
            int statresult = stat(pathBuf, &fileStat);
            free(pathBuf);
            if (statresult == -1)
                continue;
            if (S_ISDIR(fileStat.st_mode)) {
                /* check duplicate name */
                int j = 0;
                for (; j < skinBuf->i; j++) {
                    char **name = (char**) utarray_eltptr(skinBuf, j);
                    if (strcmp(*name, drt->d_name) == 0)
                        break;
                }
                if (j == skinBuf->i) {
                    char *temp = drt->d_name;
                    utarray_push_back(skinBuf, &temp);
                }
            }
        }

        closedir(dir);
    }

    FcitxXDGFreePath(skinPath);

    return;
}
示例#12
0
文件: skin.c 项目: adaptee/fcitx
SkinImage* GetIMIcon(FcitxClassicUI* classicui, FcitxSkin *sc, const char* fallbackIcon, int flag, boolean fallbackToDefault)
{
    FcitxIM* im = FcitxInstanceGetCurrentIM(classicui->owner);
    if (!im)
        return NULL;
    const char *path;
    char *tmpstr = NULL;
    if (im->strIconName[0] == '/') {
        path = im->strIconName;
    } else {
        fcitx_utils_alloc_cat_str(tmpstr, im->strIconName, ".png");
        path = tmpstr;
    }
    SkinImage *imicon = NULL;
    if (strncmp(im->uniqueName, "fcitx-keyboard-",
                strlen("fcitx-keyboard-")) == 0) {
        SkinImage* activeIcon = LoadImage(sc, fallbackIcon, fallbackToDefault);
        char temp[LANGCODE_LENGTH + 1] = { '\0', };
        char* iconText = 0;
        if (*im->langCode) {
            strncpy(temp, im->langCode, LANGCODE_LENGTH);
            iconText = temp;
            iconText[0] = toupper(iconText[0]);
        } else {
            iconText = im->uniqueName + strlen("fcitx-keyboard-");
        }
        imicon = LoadImageWithText(
            classicui, sc, path, iconText,
            cairo_image_surface_get_width(activeIcon->image),
            cairo_image_surface_get_height(activeIcon->image), true);
    }

    if (imicon == NULL)
        imicon = LoadImage(sc, path, flag);
    fcitx_utils_free(tmpstr);
    if (imicon == NULL) {
        imicon = LoadImage(sc, fallbackIcon, fallbackToDefault);
    } else {
        SkinImage* activeIcon = LoadImage(sc, fallbackIcon, fallbackToDefault);
        if (activeIcon) {
            ResizeSurface(&imicon->image,
                          cairo_image_surface_get_width(activeIcon->image),
                          cairo_image_surface_get_height(activeIcon->image));
        }
    }
    return imicon;
}
示例#13
0
char* FcitxNotificationItemGetIconNameString(FcitxNotificationItem* notificationitem)
{
    char* iconName = NULL;
    FcitxIM* im = FcitxInstanceGetCurrentIM(notificationitem->owner);
    const char* icon = "";
    if (im) {
        if (strncmp(im->uniqueName, "fcitx-keyboard-",
                    strlen("fcitx-keyboard-")) != 0) {
            icon = im->strIconName;
        } else {
            return strdup("input-keyboard");
        }
    }
    fcitx_utils_alloc_cat_str(iconName, (icon[0] == '\0' || icon[0] == '/') ?
                              "" : "fcitx-", icon);
    return iconName;
}
示例#14
0
char* FcitxNotificationItemGetIconNameString(FcitxNotificationItem* notificationitem)
{
    char* iconName = NULL;
    FcitxIM* im = FcitxInstanceGetCurrentIM(notificationitem->owner);
    const char* icon = "";
    if (im) {
        if (strncmp(im->uniqueName, "fcitx-keyboard-",
                    strlen("fcitx-keyboard-")) != 0) {
            icon = im->strIconName;
        } else {
            return strdup("input-keyboard");
        }
    }
    boolean result = CheckAddPrefix(&icon);
    fcitx_utils_alloc_cat_str(iconName, result ? "fcitx-" : "", icon);
    return iconName;
}
示例#15
0
void _fcitx_compose_table_read_locale_mappings(FcitxComposeTable* table)
{
    char* mappingsDir;
    fcitx_utils_alloc_cat_str(mappingsDir, table->systemComposeDir, "/compose.dir");
    FILE* mappings = fopen(mappingsDir, "r");

    if (mappings) {
        char* line = NULL;
        size_t bufSize = 0;
        while (getline(&line, &bufSize, mappings) != -1) {
            char* trimLine = fcitx_utils_trim(line);

            if (trimLine[0] != '#' && trimLine[0] != '\0' && fcitx_utils_islower(trimLine[0])) {
                FcitxStringList* list = fcitx_utils_string_split_full(trimLine, FCITX_WHITESPACE, false);
                if (utarray_len(list) >= 2) {
                    char **plocale = utarray_eltptr(list, 1);
                    char **pitem = utarray_eltptr(list, 0);
                    char *locale = *plocale, *item = *pitem;
                    // we steal this string from list
                    *pitem = NULL;

                    size_t itemLen = strlen(item);
                    if (itemLen > 0 && item[itemLen - 1] == ':') {
                        item[itemLen - 1] = '\0';
                    }

                    char* p = locale;
                    while(*p) {
                        *p = fcitx_utils_toupper(*p);
                        p++;
                    }

                    fcitx_dict_insert_by_str(table->localeToTable, locale, item, true);
                }
                fcitx_utils_string_list_free(list);
            }

            free(trimLine);
        }
        free(line);
        fclose(mappings);
    }

    free(mappingsDir);
}
示例#16
0
void _fcitx_compose_table_find_system_compose_dir(FcitxComposeTable* table, int nPossibleLocation, const char* possibleLocation[]) {
    bool found = false;
    for (int i = 0; i < nPossibleLocation; ++i) {
        char* path;
        fcitx_utils_alloc_cat_str(path, possibleLocation[i], "/compose.dir");
        if (fcitx_utils_isreg(path)) {
            table->systemComposeDir = strdup(possibleLocation[i]);
            found = true;
        }

        free(path);

        if (found) {
            break;
        }
    }
    if (!found) {
        // should we ask to report this in the qt bug tracker?
        table->state = FCTS_UnknownSystemComposeDir;
    }
}
示例#17
0
文件: skin.c 项目: areslp/fcitx
/**
@加载皮肤配置文件
*/
int LoadSkinConfig(FcitxSkin* sc, char** skinType)
{
    FILE    *fp;
    boolean    isreload = False;
    int ret = 0;
    if (sc->config.configFile) {
        utarray_done(&sc->skinMainBar.skinPlacement);
        FcitxConfigFree(&sc->config);
        UnloadImage(sc);
    }
    memset(sc, 0, sizeof(FcitxSkin));
    utarray_init(&sc->skinMainBar.skinPlacement, &place_icd);

reload:
    if (!isreload) {
        char *buf;
        fcitx_utils_alloc_cat_str(buf, *skinType, "/fcitx_skin.conf");
        fp = FcitxXDGGetFileWithPrefix("skin", buf, "r", NULL);
        free(buf);
    } else {
        char *path = fcitx_utils_get_fcitx_path_with_filename(
                         "pkgdatadir", "/skin/default/fcitx_skin.conf");
        fp = fopen(path, "r");
        free(path);
    }

    if (fp) {
        FcitxConfigFile *cfile;
        FcitxConfigFileDesc* skinDesc = GetSkinDesc();
        if (sc->config.configFile == NULL) {
            cfile = FcitxConfigParseConfigFileFp(fp, skinDesc);
        } else {
            cfile = sc->config.configFile;
            cfile = FcitxConfigParseIniFp(fp, cfile);
        }
        if (!cfile) {
            fclose(fp);
            fp = NULL;
        } else {
            FcitxSkinConfigBind(sc, cfile, skinDesc);
            FcitxConfigBindSync((FcitxGenericConfig*)sc);
        }
    }

    if (!fp) {
        if (isreload) {
            FcitxLog(FATAL, _("Can not load default skin, is installion correct?"));
            perror("fopen");
            ret = 1;    // 如果安装目录里面也没有配置文件,那就只好告诉用户,无法运行了
        } else {
            perror("fopen");
            FcitxLog(WARNING, _("Can not load skin %s, return to default"), *skinType);
            if (*skinType)
                free(*skinType);
            *skinType = strdup("default");
            isreload = true;
            goto reload;
        }
    }

    if (fp)
        fclose(fp);
    sc->skinType = skinType;

    return ret;

}
示例#18
0
文件: skin.c 项目: areslp/fcitx
SkinImage* LoadImageFromTable(SkinImage** imageTable, const char* skinType, const char* name, int flag)
{
    cairo_surface_t *png = NULL;
    SkinImage *image = NULL;
    char *buf;
    fcitx_utils_alloc_cat_str(buf, "skin/", skinType);
    const char* fallbackChainNoFallback[] = { buf };
    const char* fallbackChainPanel[] = { buf, "skin/default" };
    const char* fallbackChainTray[] = { "imicon" };
    const char* fallbackChainPanelIMIcon[] = { buf, "imicon", "skin/default" };

    HASH_FIND_STR(*imageTable, name, image);
    if (image != NULL) {
        free(buf);
        return image;
    }

    const char** fallbackChain;
    int fallbackSize;
    switch(flag) {
    case 1:
        fallbackChain = fallbackChainPanel;
        fallbackSize = 2;
        break;
    case 2:
        fallbackChain = fallbackChainTray;
        fallbackSize = 1;
        break;
    case 3:
        fallbackChain = fallbackChainPanelIMIcon;
        fallbackSize = 3;
        break;
    case 0:
    default:
        /* fall through */
        fallbackChain = fallbackChainNoFallback;
        fallbackSize = 1;
        break;
    }

    if (strlen(name) > 0 && strcmp(name , "NONE") != 0) {
        int i = 0;
        for (i = 0; i < fallbackSize; i ++) {
            char* filename;
            const char* skintype = fallbackChain[i];

            FILE* fp = FcitxXDGGetFileWithPrefix(skintype, name, "r", &filename);
            if (fp) {
                png = cairo_image_surface_create_from_png(filename);
                if (cairo_surface_status (png)) {
                    png = NULL;
                }
            }

            free(filename);
            if (png)
                break;
        }
    }
    free(buf);

    if (png != NULL) {
        image = fcitx_utils_new(SkinImage);
        image->name = strdup(name);
        image->image = png;
        HASH_ADD_KEYPTR(hh, *imageTable, image->name,
                        strlen(image->name), image);
        return image;
    }
    return NULL;
}
示例#19
0
char* CharSelectDataName(CharSelectData* charselect, uint32_t unicode)
{
    char* result = NULL;
    do {
        if ((unicode >= 0x3400 && unicode <= 0x4DB5)
                || (unicode >= 0x4e00 && unicode <= 0x9fa5)
                || (unicode >= 0x20000 && unicode <= 0x2A6D6)) {
            asprintf(&result, "CJK UNIFIED IDEOGRAPH-%x", unicode);
        } else if (unicode >= 0xac00 && unicode <= 0xd7af) {
            /* compute hangul syllable name as per UAX #15 */
            int SIndex = unicode - SBase;
            int LIndex, VIndex, TIndex;

            if (SIndex < 0 || SIndex >= SCount) {
                result = strdup("");
                break;
            }

            LIndex = SIndex / NCount;
            VIndex = (SIndex % NCount) / TCount;
            TIndex = SIndex % TCount;

            fcitx_utils_alloc_cat_str(result, "HANGUL SYLLABLE ",
                                      JAMO_L_TABLE[LIndex],
                                      JAMO_V_TABLE[VIndex],
                                      JAMO_T_TABLE[TIndex]);
        } else if (unicode >= 0xD800 && unicode <= 0xDB7F)
            result = strdup(_("<Non Private Use High Surrogate>"));
        else if (unicode >= 0xDB80 && unicode <= 0xDBFF)
            result = strdup(_("<Private Use High Surrogate>"));
        else if (unicode >= 0xDC00 && unicode <= 0xDFFF)
            result = strdup(_("<Low Surrogate>"));
        else if (unicode >= 0xE000 && unicode <= 0xF8FF)
            result = strdup(_("<Private Use>"));
        else {

        const char* data = charselect->dataFile;
            const uint32_t offsetBegin = FromLittleEndian32(data+4);
            const uint32_t offsetEnd = FromLittleEndian32(data+8);

            int min = 0;
            int mid;
            int max = ((offsetEnd - offsetBegin) / 8) - 1;

            while (max >= min) {
                mid = (min + max) / 2;
                const uint32_t midUnicode = FromLittleEndian32(data + offsetBegin + mid*8);
                if (unicode > midUnicode)
                    min = mid + 1;
                else if (unicode < midUnicode)
                    max = mid - 1;
                else {
                    uint32_t offset = FromLittleEndian32(data + offsetBegin + mid*8 + 4);
                    result = strdup(charselect->dataFile + offset + 1);
                    break;
                }
            }
        }
    } while(0);

    if (!result) {
        result = strdup(_("<not assigned>"));
    }
    return result;
}
示例#20
0
void FcitxDBusMenuFillProperty(FcitxNotificationItem* notificationitem, int32_t id, FcitxStringHashSet* properties, DBusMessageIter* iter)
{
    FcitxInstance* instance = notificationitem->owner;
    /* append a{sv} */
    DBusMessageIter sub;
    dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, "{sv}", &sub);
    int32_t menu = ACTION_MENU(id);
    int32_t index = ACTION_INDEX(id);

    /* index == 0 means it has a sub menu */
    if (index == 0) {
        const char* value = "submenu";
        FcitxDBusMenuAppendProperty(&sub, properties, "children-display", DBUS_TYPE_STRING, &value);
    }
    if (menu == 0) {
        if (index <= 8 && index > 0) {
            const char* value;
            switch(index) {
                case 1:
                    value = _("Online Help");
                    FcitxDBusMenuAppendProperty(&sub, properties, "label", DBUS_TYPE_STRING, &value);
                    value = "help-contents";
                    FcitxDBusMenuAppendProperty(&sub, properties, "icon-name", DBUS_TYPE_STRING, &value);
                    break;
                case 2:
                case 3:
                case 8:
                    value = "separator";
                    FcitxDBusMenuAppendProperty(&sub, properties, "type", DBUS_TYPE_STRING, &value);
                    break;
                case 4:
                    value = _("Configure Current Input Method");
                    FcitxDBusMenuAppendProperty(&sub, properties, "label", DBUS_TYPE_STRING, &value);
                    break;
                case 5:
                    value = _("Configure");
                    FcitxDBusMenuAppendProperty(&sub, properties, "label", DBUS_TYPE_STRING, &value);
                    /* this icon sucks on KDE, why configure doesn't have "configure" */
#if 0
                    value = "preferences-system";
                    FcitxDBusMenuAppendProperty(&sub, properties, "icon-name", DBUS_TYPE_STRING, &value);
#endif
                    break;
                case 6:
                    value = _("Restart");
                    FcitxDBusMenuAppendProperty(&sub, properties, "label", DBUS_TYPE_STRING, &value);
                    value = "view-refresh";
                    FcitxDBusMenuAppendProperty(&sub, properties, "icon-name", DBUS_TYPE_STRING, &value);
                    break;
                case 7:
                    value = _("Exit");
                    FcitxDBusMenuAppendProperty(&sub, properties, "label", DBUS_TYPE_STRING, &value);
                    value = "application-exit";
                    FcitxDBusMenuAppendProperty(&sub, properties, "icon-name", DBUS_TYPE_STRING, &value);
                    break;
            }
        } else {
            int index = STATUS_INDEX(id);
            const char* name = NULL;
            const char* icon = NULL;
            char* needfree = NULL;
            if (STATUS_ISCOMP(id)) {
                UT_array* uicompstats = FcitxInstanceGetUIComplexStats(instance);
                FcitxUIComplexStatus* compstatus = (FcitxUIComplexStatus*) utarray_eltptr(uicompstats, index);
                if (compstatus) {
                    name = compstatus->shortDescription;
                    icon = compstatus->getIconName(compstatus->arg);

                    if (CheckAddPrefix(&icon)) {
                        fcitx_utils_alloc_cat_str(needfree, "fcitx-", icon);
                        icon = needfree;
                    }
                }
            } else {
                UT_array* uistats = FcitxInstanceGetUIStats(instance);
                FcitxUIStatus* status = (FcitxUIStatus*) utarray_eltptr(uistats, index);
                if (status) {
                    name = status->shortDescription;

                    fcitx_utils_alloc_cat_str(needfree, "fcitx-", status->name,
                                            ((status->getCurrentStatus(status->arg)) ?
                                            "-active" : "-inactive"));
                    icon = needfree;
                }
            }

            if (name) {
                FcitxDBusMenuAppendProperty(&sub, properties, "label", DBUS_TYPE_STRING, &name);
            }
            if (icon) {
                FcitxDBusMenuAppendProperty(&sub, properties, "icon-name", DBUS_TYPE_STRING, &icon);
            }
            fcitx_utils_free(needfree);
        }
    } else {
        UT_array* uimenus = FcitxInstanceGetUIMenus(instance);
        FcitxUIMenu** menupp = (FcitxUIMenu**) utarray_eltptr(uimenus, menu - 1), *menup;
        if (menupp) {
            menup = *menupp;
            if (index == 0) {
                FcitxDBusMenuAppendProperty(&sub, properties, "label", DBUS_TYPE_STRING, &menup->name);
            } else if (index > 0) {
                FcitxMenuItem* item = (FcitxMenuItem*) utarray_eltptr(&menup->shell, index - 1);
                if (item) {
                    FcitxDBusMenuAppendProperty(&sub, properties, "label", DBUS_TYPE_STRING, &item->tipstr);
                    if (menup->mark != -1) {
                        const char* radio = "radio";
                        FcitxDBusMenuAppendProperty(&sub, properties, "toggle-type", DBUS_TYPE_STRING, &radio);
                        int32_t toggleState = 0;
                        if (menup->mark == index - 1) {
                            toggleState = 1;
                        }
                        FcitxDBusMenuAppendProperty(&sub, properties, "toggle-state", DBUS_TYPE_INT32, &toggleState);
                    }
                }
            }
        }
    }
    dbus_message_iter_close_container(iter, &sub);
}
示例#21
0
文件: kkc.c 项目: fcitx/fcitx-kkc
INPUT_RETURN_VALUE FcitxKkcGetCandWords(void* arg)
{
    FcitxKkc *kkc = (FcitxKkc*)arg;
    FcitxInputState* input = FcitxInstanceGetInputState(kkc->owner);
    FcitxCandidateWordList* candList = FcitxInputStateGetCandidateList(input);
    FcitxMessages* clientPreedit = FcitxInputStateGetClientPreedit(input);
    FcitxMessages* preedit = FcitxInputStateGetPreedit(input);
    FcitxInstanceCleanInputWindow(kkc->owner);

    FcitxMessages* message = FcitxInstanceICSupportPreedit(kkc->owner, FcitxInstanceGetCurrentIC(kkc->owner)) ? clientPreedit : preedit;

    FcitxCandidateWordSetChoose(candList, DIGIT_STR_CHOOSE);
    FcitxCandidateWordSetPageSize(candList, kkc->config.pageSize);
    FcitxCandidateWordSetLayoutHint(candList, kkc->config.candidateLayout);
    FcitxInputStateSetShowCursor(input, true);

    KkcSegmentList* segments = kkc_context_get_segments(kkc->context);
    if (kkc_segment_list_get_cursor_pos(segments) >= 0) {
        int i = 0;
        int offset = 0;
        for (i = 0; i < kkc_segment_list_get_size(segments); i ++) {
            KkcSegment* segment = kkc_segment_list_get(segments, i);
            const gchar* str = kkc_segment_get_output(segment);
            FcitxMessageType messageType = MSG_INPUT;
            if (i < kkc_segment_list_get_cursor_pos(segments)) {
                offset += strlen(str);
            }
            if (i == kkc_segment_list_get_cursor_pos(segments)) {
                messageType = (FcitxMessageType) (MSG_HIGHLIGHT | MSG_OTHER);
            }
            FcitxMessagesAddMessageAtLast(message, messageType, "%s", str);
        }

        if (message == clientPreedit) {
            FcitxInputStateSetClientCursorPos(input, offset);
        } else {
            FcitxInputStateSetCursorPos(input, offset);
        }
    } else {
        gchar* str = kkc_context_get_input(kkc->context);
        if (str && str[0]) {
            FcitxMessagesAddMessageAtLast(message, MSG_INPUT, "%s", str);

            if (message == clientPreedit) {
                FcitxInputStateSetClientCursorPos(input, strlen(str));
            } else {
                FcitxInputStateSetCursorPos(input, strlen(str));
            }
        }
        g_free(str);
    }

    KkcCandidateList* kkcCandidates = kkc_context_get_candidates(kkc->context);
    if (kkc_candidate_list_get_page_visible(kkcCandidates)) {
        int i, j;
        guint size = kkc_candidate_list_get_size(kkcCandidates);
        gint cursor_pos = kkc_candidate_list_get_cursor_pos(kkcCandidates);
        guint page_start = kkc_candidate_list_get_page_start(kkcCandidates);
        guint page_size = kkc_candidate_list_get_page_size(kkcCandidates);
        for (i = kkc_candidate_list_get_page_start(kkcCandidates), j = 0; i < size; i ++, j++) {
            FcitxCandidateWord word;
            word.callback = FcitxKkcGetCandWord;
            word.extraType = MSG_OTHER;
            word.owner = kkc;
            int* id = fcitx_utils_new(int);
            *id = j;
            word.priv = id;
            word.strExtra = NULL;
            word.strExtra = MSG_TIPS;
            KkcCandidate* kkcCandidate = kkc_candidate_list_get(kkcCandidates, i);
            if (kkc->config.showAnnotation && kkc_candidate_get_annotation(kkcCandidate)) {
                fcitx_utils_alloc_cat_str(word.strExtra, " [", kkc_candidate_get_annotation(kkcCandidate), "]");
            }
            word.strWord = strdup(kkc_candidate_get_text(kkcCandidate));
            if (i == cursor_pos) {
                word.wordType = MSG_CANDIATE_CURSOR;
            } else {
                word.wordType = MSG_OTHER;
            }

            FcitxCandidateWordAppend(candList, &word);
        }
        FcitxCandidateWordSetFocus(candList, cursor_pos - page_start);

        FcitxCandidateWordSetOverridePaging(candList,
                                            (cursor_pos - page_start) >= page_size,
                                            (size - page_start) / page_size != (cursor_pos - page_start) / page_size,
                                            FcitxKkcPaging,
                                            kkc,
                                            NULL);
    }

    if (kkc_context_has_output(kkc->context)) {
        gchar* str = kkc_context_poll_output(kkc->context);
        FcitxInstanceCommitString(kkc->owner, FcitxInstanceGetCurrentIC(kkc->owner), str);
        g_free(str);
    }

    return IRV_DISPLAY_CANDWORDS;
}
示例#22
0
文件: tabledict.c 项目: ezc/fcitx
boolean LoadTableDict(TableMetaData* tableMetaData)
{
    char            strCode[MAX_CODE_LENGTH + 1];
    char           *strHZ = 0;
    FILE           *fpDict;
    RECORD         *recTemp;
    unsigned int    i = 0;
    uint32_t        iTemp, iTempCount;
    char            cChar = 0, cTemp;
    int8_t          iVersion = 1;
    int             iRecordIndex;
    TableDict      *tableDict;

    //读入码表
    FcitxLog(DEBUG, _("Loading Table Dict"));

    int reload = 0;
    do {
        boolean error = false;
        if (!reload) {
            /**
             * kcm saves a absolute path here but it is then interpreted as
             * a relative path?
             **/
            fpDict = FcitxXDGGetFileWithPrefix("table", tableMetaData->strPath,
                                               "r", NULL);
        } else {
            char *tablepath;
            char *path = fcitx_utils_get_fcitx_path("pkgdatadir");
            fcitx_utils_alloc_cat_str(tablepath, path, "/table/",
                                      tableMetaData->strPath);
            fpDict = fopen(tablepath, "r");
            free(tablepath);
        }
        if (!fpDict)
            return false;

        tableMetaData->tableDict = fcitx_utils_new(TableDict);

        tableDict = tableMetaData->tableDict;
        tableDict->pool = fcitx_memory_pool_create();
#define CHECK_LOAD_TABLE_ERROR(SIZE) if (size < (SIZE)) { error = true; goto table_load_error; }

        //先读取码表的信息
        //判断版本信息
        size_t size;
        size = fcitx_utils_read_uint32(fpDict, &iTemp);
        CHECK_LOAD_TABLE_ERROR(1);

        if (!iTemp) {
            size = fread(&iVersion, sizeof(int8_t), 1, fpDict);
            CHECK_LOAD_TABLE_ERROR(1);
            iVersion = (iVersion < INTERNAL_VERSION);
            size = fcitx_utils_read_uint32(fpDict, &iTemp);
            CHECK_LOAD_TABLE_ERROR(1);
        }

        tableDict->strInputCode = (char*)realloc(tableDict->strInputCode, sizeof(char) * (iTemp + 1));
        size = fread(tableDict->strInputCode, sizeof(char), iTemp + 1, fpDict);
        CHECK_LOAD_TABLE_ERROR(iTemp + 1);
        /*
         * 建立索引,加26是为了为拼音编码预留空间
         */
        size_t tmp_len = strlen(tableDict->strInputCode) + 26;
        tableDict->recordIndex = (RECORD_INDEX*)fcitx_memory_pool_alloc(tableDict->pool, tmp_len * sizeof(RECORD_INDEX));
        for (iTemp = 0; iTemp < tmp_len; iTemp++) {
            tableDict->recordIndex[iTemp].cCode = 0;
            tableDict->recordIndex[iTemp].record = NULL;
        }
        /********************************************************************/

        size = fread(&(tableDict->iCodeLength), sizeof(uint8_t), 1, fpDict);
        CHECK_LOAD_TABLE_ERROR(1);
        UpdateTableMetaData(tableMetaData);

        if (!iVersion) {
            size = fread(&(tableDict->iPYCodeLength), sizeof(uint8_t), 1, fpDict);
            CHECK_LOAD_TABLE_ERROR(1);
        }
        else
            tableDict->iPYCodeLength = tableDict->iCodeLength;

        size = fcitx_utils_read_uint32(fpDict, &iTemp);
        CHECK_LOAD_TABLE_ERROR(1);
        tableDict->strIgnoreChars = (char*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(char) * (iTemp + 1));
        size = fread(tableDict->strIgnoreChars, sizeof(char), iTemp + 1, fpDict);
        CHECK_LOAD_TABLE_ERROR(iTemp + 1);

        size = fread(&(tableDict->bRule), sizeof(unsigned char), 1, fpDict);
        CHECK_LOAD_TABLE_ERROR(1);

        if (tableDict->bRule) { //表示有组词规则
            tableDict->rule = (RULE*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(RULE) * (tableDict->iCodeLength - 1));
            for (i = 0; i < tableDict->iCodeLength - 1; i++) {
                size = fread(&(tableDict->rule[i].iFlag), sizeof(unsigned char), 1, fpDict);
                CHECK_LOAD_TABLE_ERROR(1);
                size = fread(&(tableDict->rule[i].iWords), sizeof(unsigned char), 1, fpDict);
                CHECK_LOAD_TABLE_ERROR(1);
                tableDict->rule[i].rule = (RULE_RULE*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(RULE_RULE) * tableDict->iCodeLength);
                for (iTemp = 0; iTemp < tableDict->iCodeLength; iTemp++) {
                    size = fread(&(tableDict->rule[i].rule[iTemp].iFlag), sizeof(unsigned char), 1, fpDict);
                    CHECK_LOAD_TABLE_ERROR(1);
                    size = fread(&(tableDict->rule[i].rule[iTemp].iWhich), sizeof(unsigned char), 1, fpDict);
                    CHECK_LOAD_TABLE_ERROR(1);
                    size = fread(&(tableDict->rule[i].rule[iTemp].iIndex), sizeof(unsigned char), 1, fpDict);
                    CHECK_LOAD_TABLE_ERROR(1);
                }
            }
        }

        tableDict->recordHead = (RECORD*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(RECORD));
        tableDict->currentRecord = tableDict->recordHead;

        size = fcitx_utils_read_uint32(fpDict, &tableDict->iRecordCount);
        CHECK_LOAD_TABLE_ERROR(1);

        for (i = 0; i < SINGLE_HZ_COUNT; i++) {
            tableDict->tableSingleHZ[i] = (RECORD*)NULL;
            tableDict->tableSingleHZCons[i] = (RECORD*)NULL;
        }

        iRecordIndex = 0;
        size_t bufSize = 0;
        for (i = 0; i < tableDict->iRecordCount; i++) {
            size = fread(strCode, sizeof(int8_t), tableDict->iPYCodeLength + 1, fpDict);
            CHECK_LOAD_TABLE_ERROR(tableDict->iPYCodeLength + 1);
            size = fcitx_utils_read_uint32(fpDict, &iTemp);
            CHECK_LOAD_TABLE_ERROR(1);
            /* we don't actually have such limit, but sometimes, broken table
             * may break this, so we need to give a limitation.
             */
            if (iTemp > UTF8_MAX_LENGTH * 30) {
                error = true;
                goto table_load_error;
            }
            if (iTemp > bufSize) {
                bufSize = iTemp;
                strHZ = realloc(strHZ, bufSize);
            }
            size = fread(strHZ, sizeof(int8_t), iTemp, fpDict);
            CHECK_LOAD_TABLE_ERROR(iTemp);
            recTemp = (RECORD*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(RECORD));
            recTemp->strCode = (char*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(char) * (tableDict->iPYCodeLength + 1));
            memset(recTemp->strCode, 0, sizeof(char) * (tableDict->iPYCodeLength + 1));
            strcpy(recTemp->strCode, strCode);
            recTemp->strHZ = (char*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(char) * iTemp);
            strcpy(recTemp->strHZ, strHZ);

            if (!iVersion) {
                size = fread(&cTemp, sizeof(int8_t), 1, fpDict);
                CHECK_LOAD_TABLE_ERROR(1);
                recTemp->type = cTemp;
            }

            size = fcitx_utils_read_uint32(fpDict, &recTemp->iHit);
            CHECK_LOAD_TABLE_ERROR(1);
            size = fcitx_utils_read_uint32(fpDict, &recTemp->iIndex);
            CHECK_LOAD_TABLE_ERROR(1);
            if (recTemp->iIndex > tableDict->iTableIndex)
                tableDict->iTableIndex = recTemp->iIndex;

            /* 建立索引 */
            if (cChar != recTemp->strCode[0]) {
                cChar = recTemp->strCode[0];
                tableDict->recordIndex[iRecordIndex].cCode = cChar;
                tableDict->recordIndex[iRecordIndex].record = recTemp;
                iRecordIndex++;
            }
            /******************************************************************/
            /** 为单字生成一个表   */
            if (fcitx_utf8_strlen(recTemp->strHZ) == 1 && !IsIgnoreChar(tableDict, strCode[0]))
            {
                RECORD** tableSingleHZ = NULL;
                if (recTemp->type == RECORDTYPE_NORMAL)
                    tableSingleHZ = tableDict->tableSingleHZ;
                else if (recTemp->type == RECORDTYPE_CONSTRUCT)
                    tableSingleHZ = tableDict->tableSingleHZCons;

                if (tableSingleHZ) {
                    iTemp = CalHZIndex(recTemp->strHZ);
                    if (iTemp < SINGLE_HZ_COUNT) {
                        if (tableSingleHZ[iTemp]) {
                            if (strlen(strCode) > strlen(tableDict->tableSingleHZ[iTemp]->strCode))
                                tableSingleHZ[iTemp] = recTemp;
                        } else
                            tableSingleHZ[iTemp] = recTemp;
                    }
                }
            }

            if (recTemp->type == RECORDTYPE_PINYIN)
                tableDict->bHasPinyin = true;

            if (recTemp->type == RECORDTYPE_PROMPT && strlen(recTemp->strCode) == 1)
                tableDict->promptCode[(uint8_t) recTemp->strCode[0]] = recTemp;

            tableDict->currentRecord->next = recTemp;
            recTemp->prev = tableDict->currentRecord;
            tableDict->currentRecord = recTemp;
        }
        if (strHZ) {
            free(strHZ);
            strHZ = NULL;
        }

        tableDict->currentRecord->next = tableDict->recordHead;
        tableDict->recordHead->prev = tableDict->currentRecord;

table_load_error:
        fclose(fpDict);
        if (error) {
            fcitx_memory_pool_destroy(tableDict->pool);
            tableDict->pool = NULL;
            reload++;
        } else {
            break;
        }
    } while(reload < 2);

    if (!tableDict->pool)
        return false;

    FcitxLog(DEBUG, _("Load Table Dict OK"));

    //读取相应的特殊符号表
    fpDict = FcitxXDGGetFileWithPrefix("table", tableMetaData->strSymbolFile, "r", NULL);

    if (fpDict) {
        tableDict->iFH = fcitx_utils_calculate_record_number(fpDict);
        tableDict->fh = (FH*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(FH) * tableDict->iFH);

        char* strBuf = NULL;
        size_t bufLen = 0;
        for (i = 0; i < tableDict->iFH; i++) {
            if (getline(&strBuf, &bufLen, fpDict) == -1)
                break;

            if (!fcitx_utf8_check_string(strBuf))
                break;

            if (fcitx_utf8_strlen(strBuf) > FH_MAX_LENGTH)
                break;

            strcpy(tableDict->fh[i].strFH, strBuf);
        }
        fcitx_utils_free(strBuf);
        tableDict->iFH = i;

        fclose(fpDict);
    }

    tableDict->strNewPhraseCode = (char*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(char) * (tableDict->iCodeLength + 1));
    tableDict->strNewPhraseCode[tableDict->iCodeLength] = '\0';

    tableDict->iAutoPhrase = 0;
    if (tableMetaData->bAutoPhrase) {
        tableDict->autoPhrase = (AUTOPHRASE*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(AUTOPHRASE) * AUTO_PHRASE_COUNT);

        //读取上次保存的自动词组信息
        FcitxLog(DEBUG, _("Loading Autophrase."));

        char *temppath;
        fcitx_utils_alloc_cat_str(temppath, tableMetaData->uniqueName,
                                  "_LastAutoPhrase.tmp");
        fpDict = FcitxXDGGetFileWithPrefix("table", temppath, "r", NULL);
        free(temppath);
        i = 0;
        if (fpDict) {
            size_t size = fcitx_utils_read_int32(fpDict, &tableDict->iAutoPhrase);
            if (size == 1) {
                for (; i < tableDict->iAutoPhrase; i++) {
                    tableDict->autoPhrase[i].strCode = (char*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(char) * (tableDict->iCodeLength + 1));
                    tableDict->autoPhrase[i].strHZ = (char*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(char) * (PHRASE_MAX_LENGTH * UTF8_MAX_LENGTH + 1));
                    size = fread(tableDict->autoPhrase[i].strCode, tableDict->iCodeLength + 1, 1, fpDict);
                    if (size != 1) {
                        tableDict->iAutoPhrase = i;
                        break;
                    }
                    size = fread(tableDict->autoPhrase[i].strHZ, PHRASE_MAX_LENGTH * UTF8_MAX_LENGTH + 1, 1, fpDict);
                    tableDict->autoPhrase[i].strHZ[PHRASE_MAX_LENGTH * UTF8_MAX_LENGTH] = 0;
                    if (size != 1 || !fcitx_utf8_check_string(tableDict->autoPhrase[i].strHZ)) {
                        tableDict->iAutoPhrase = i;
                        break;
                    }
                    size = fcitx_utils_read_uint32(fpDict, &iTempCount);
                    if (size != 1) {
                        tableDict->iAutoPhrase = i;
                        break;
                    }

                    tableDict->autoPhrase[i].iSelected = iTempCount;
                    if (i == AUTO_PHRASE_COUNT - 1)
                        tableDict->autoPhrase[i].next = &tableDict->autoPhrase[0];
                    else
                        tableDict->autoPhrase[i].next = &tableDict->autoPhrase[i + 1];
                }
            }
            fclose(fpDict);
        }

        for (; i < AUTO_PHRASE_COUNT; i++) {
            tableDict->autoPhrase[i].strCode = (char*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(char) * (tableDict->iCodeLength + 1));
            tableDict->autoPhrase[i].strHZ = (char*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(char) * (PHRASE_MAX_LENGTH * UTF8_MAX_LENGTH + 1));
            tableDict->autoPhrase[i].iSelected = 0;
            if (i == AUTO_PHRASE_COUNT - 1)
                tableDict->autoPhrase[i].next = &tableDict->autoPhrase[0];
            else
                tableDict->autoPhrase[i].next = &tableDict->autoPhrase[i + 1];
        }

        if (i == AUTO_PHRASE_COUNT)
            tableDict->insertPoint = &tableDict->autoPhrase[0];
        else
            tableDict->insertPoint = &tableDict->autoPhrase[i - 1];

        FcitxLog(DEBUG, _("Load Autophrase OK"));
    } else
        tableDict->autoPhrase = (AUTOPHRASE *) NULL;

    return true;
}
示例#23
0
文件: tabledict.c 项目: ezc/fcitx
void SaveTableDict(TableMetaData *tableMetaData)
{
    RECORD         *recTemp;
    char           *pstr, *tempfile;
    FILE           *fpDict;
    uint32_t    iTemp;
    unsigned int    i;
    int             fd;
    int8_t          cTemp;
    TableDict      *tableDict = tableMetaData->tableDict;

    if (!tableDict->iTableChanged)
        return;

    // make ~/.config/fcitx/table/ dir
    FcitxXDGGetFileUserWithPrefix("table", "", "w", NULL);
    FcitxXDGGetFileUserWithPrefix("table", TABLE_TEMP_FILE, NULL, &tempfile);
    fd = mkstemp(tempfile);
    fpDict = NULL;

    if (fd > 0)
        fpDict = fdopen(fd, "w");

    if (!fpDict) {
        FcitxLog(ERROR, _("Save dict error"));
        free(tempfile);
        return;
    }

    // write version number
    fcitx_utils_write_uint32(fpDict, 0);
    fwrite(&iInternalVersion, sizeof(char), 1, fpDict);

    iTemp = strlen(tableDict->strInputCode);
    fcitx_utils_write_uint32(fpDict, iTemp);
    fwrite(tableDict->strInputCode, sizeof(char), iTemp + 1, fpDict);
    fwrite(&(tableDict->iCodeLength), sizeof(char), 1, fpDict);
    fwrite(&(tableDict->iPYCodeLength), sizeof(char), 1, fpDict);
    iTemp = strlen(tableDict->strIgnoreChars);
    fcitx_utils_write_uint32(fpDict, iTemp);
    fwrite(tableDict->strIgnoreChars, sizeof(char), iTemp + 1, fpDict);

    fwrite(&(tableDict->bRule), sizeof(unsigned char), 1, fpDict);
    if (tableDict->bRule) { // table contains rule
        for (i = 0; i < tableDict->iCodeLength - 1; i++) {
            fwrite(&(tableDict->rule[i].iFlag), sizeof(unsigned char), 1, fpDict);
            fwrite(&(tableDict->rule[i].iWords), sizeof(unsigned char), 1, fpDict);
            for (iTemp = 0; iTemp < tableDict->iCodeLength; iTemp++) {
                fwrite(&(tableDict->rule[i].rule[iTemp].iFlag), sizeof(unsigned char), 1, fpDict);
                fwrite(&(tableDict->rule[i].rule[iTemp].iWhich), sizeof(unsigned char), 1, fpDict);
                fwrite(&(tableDict->rule[i].rule[iTemp].iIndex), sizeof(unsigned char), 1, fpDict);
            }
        }
    }

    fcitx_utils_write_uint32(fpDict, tableDict->iRecordCount);
    recTemp = tableDict->recordHead->next;
    while (recTemp != tableDict->recordHead) {
        fwrite(recTemp->strCode, sizeof(char), tableDict->iPYCodeLength + 1, fpDict);

        iTemp = strlen(recTemp->strHZ) + 1;
        fcitx_utils_write_uint32(fpDict, iTemp);
        fwrite(recTemp->strHZ, sizeof(char), iTemp, fpDict);

        cTemp = recTemp->type;
        fwrite(&cTemp, sizeof(int8_t), 1, fpDict);
        fcitx_utils_write_uint32(fpDict, recTemp->iHit);
        fcitx_utils_write_uint32(fpDict, recTemp->iIndex);
        recTemp = recTemp->next;
    }

    fclose(fpDict);
    fpDict = FcitxXDGGetFileUserWithPrefix("table", tableMetaData->strPath, NULL, &pstr);
    if (access(pstr, 0))
        unlink(pstr);
    rename(tempfile, pstr);
    free(pstr);
    free(tempfile);

    FcitxLog(DEBUG, _("Rename OK"));

    tableDict->iTableChanged = 0;

    if (tableDict->autoPhrase) {
        // Save auto phrase
        // make ~/.config/fcitx/table/ dir
        FcitxXDGGetFileUserWithPrefix("table", "", "w", NULL);
        FcitxXDGGetFileUserWithPrefix("table", TABLE_TEMP_FILE, NULL, &tempfile);
        fd = mkstemp(tempfile);
        fpDict = NULL;

        if (fd > 0)
            fpDict = fdopen(fd, "w");

        if (fpDict) {
            fcitx_utils_write_uint32(fpDict, tableDict->iAutoPhrase);
            for (i = 0; i < tableDict->iAutoPhrase; i++) {
                fwrite(tableDict->autoPhrase[i].strCode, tableDict->iCodeLength + 1, 1, fpDict);
                fwrite(tableDict->autoPhrase[i].strHZ, PHRASE_MAX_LENGTH * UTF8_MAX_LENGTH + 1, 1, fpDict);
                fcitx_utils_write_int32(
                    fpDict, tableDict->autoPhrase[i].iSelected);
            }
            fclose(fpDict);
        }

        char *strPath;
        fcitx_utils_alloc_cat_str(strPath, tableMetaData->uniqueName,
                                  "_LastAutoPhrase.tmp");
        fpDict = FcitxXDGGetFileUserWithPrefix("table", strPath, NULL, &pstr);
        free(strPath);
        if (access(pstr, F_OK))
            unlink(pstr);
        rename(tempfile, pstr);
        free(pstr);
        free(tempfile);
    }
}
示例#24
0
void test_string()
{
    const char *test = TEST_STR;

    FcitxStringList* list = fcitx_utils_string_split(test, ",");
    assert(utarray_len(list) == 4);
    assert(fcitx_utils_string_list_contains(list, "a"));
    assert(fcitx_utils_string_list_contains(list, "b"));
    assert(fcitx_utils_string_list_contains(list, "c"));
    assert(fcitx_utils_string_list_contains(list, "d"));
    assert(!fcitx_utils_string_list_contains(list, "e"));
    char* join = fcitx_utils_string_list_join(list, ',');
    assert(strcmp(join, test) == 0);
    fcitx_utils_string_list_append_split(list, TEST_STR, "\n");
    fcitx_utils_string_list_printf_append(list, "%s", TEST_STR);
    char *join2 = fcitx_utils_string_list_join(list, ',');
    assert(strcmp(join2, TEST_STR","TEST_STR","TEST_STR) == 0);

    char* cat = NULL;
    fcitx_utils_alloc_cat_str(cat, join, ",e");
    assert(strcmp(cat, TEST_STR",e") == 0);
    fcitx_utils_set_cat_str(cat, join, ",e,", join);
    assert(strcmp(cat, TEST_STR",e,"TEST_STR) == 0);
    join = fcitx_utils_set_str(join, join2);
    assert(strcmp(join, join2) == 0);

    free(cat);
    free(join);
    free(join2);
    fcitx_utils_string_list_free(list);
    
    list = fcitx_utils_string_split_full("a   b", " ", false);
    assert(utarray_len(list) == 2);
    fcitx_utils_string_list_free(list);

    char localcat[20];
    const char *array[] = {"a", ",b", ",c", ",d"};
    fcitx_utils_cat_str_simple(localcat, 4, array);
    assert(strcmp(localcat, test) == 0);

    char localcat2[6];
    fcitx_utils_cat_str_simple_with_len(localcat2, 4, 4, array);
    assert(strcmp(localcat2, "a,b") == 0);

    fcitx_utils_cat_str_simple_with_len(localcat2, 5, 4, array);
    assert(strcmp(localcat2, "a,b,") == 0);

    fcitx_utils_cat_str_simple_with_len(localcat2, 6, 4, array);
    assert(strcmp(localcat2, "a,b,c") == 0);

    const char *orig = "\r78\"1\n\\\e\\3\f\a\v\'cc\td\b";
    char *escape = fcitx_utils_set_escape_str(NULL, orig);
    assert(strcmp(escape,
                  "\\r78\\\"1\\n\\\\\\e\\\\3\\f\\a\\v\\\'cc\\td\\b") == 0);
    char *back = fcitx_utils_set_unescape_str(NULL, escape);
    assert(strcmp(orig, back) == 0);
    fcitx_utils_unescape_str_inplace(escape);
    assert(strcmp(orig, escape) == 0);
    free(escape);
    free(back);
    
    
    char* replace_result = fcitx_utils_string_replace("abcabc", "a", "b", true);
    assert(strcmp(replace_result, "bbcbbc") == 0);
    free(replace_result);
    
#define REPEAT 2049
    char largeReplace[3 * REPEAT + 1];
    char largeReplaceCorrect[REPEAT + 1];
    char largeReplaceCorrect2[4 * REPEAT + 1];
    int i = 0, j = 0, k = 0;
    for (int n = 0; n < REPEAT; n ++) {
        largeReplace[i++] = 'a';
        largeReplace[i++] = 'b';
        largeReplace[i++] = 'c';
        
        largeReplaceCorrect[j++] = 'e';
        
        largeReplaceCorrect2[k++] = 'a';
        largeReplaceCorrect2[k++] = 'b';
        largeReplaceCorrect2[k++] = 'c';
        largeReplaceCorrect2[k++] = 'd';
    }
    
    largeReplace[i] = '\0';
    largeReplaceCorrect[j] = '\0';
    largeReplaceCorrect2[k] = '\0';
    
    replace_result = fcitx_utils_string_replace(largeReplace, "abc", "e", true);
    assert(strcmp(replace_result, largeReplaceCorrect) == 0);
    char* replace_result2 = fcitx_utils_string_replace(replace_result, "e", "abcd", true);
    free(replace_result);
    assert(strcmp(replace_result2, largeReplaceCorrect2) == 0);
    free(replace_result2);
    
    assert(fcitx_utils_string_replace(largeReplace, "de", "bcd", true) == NULL);
    
}
示例#25
0
文件: addon.c 项目: JackChen007/fcitx
FcitxAddon* FcitxAddonsLoadInternal(UT_array* addons, boolean reloadIM)
{
    char **addonPath;
    size_t len;
    size_t start;
    if (!reloadIM)
        utarray_clear(addons);

    start = utarray_len(addons);

    FcitxStringHashSet* sset = FcitxXDGGetFiles("addon", NULL, ".conf");
    addonPath = FcitxXDGGetPathWithPrefix(&len, "addon");
    char *paths[len];
    HASH_FOREACH(string, sset, FcitxStringHashSet) {
        // FIXME: if it will cause realloc, then it's evil for fcitx 4.2 series
        if (reloadIM && addons->i == addons->n) {
            break;
        }
        
        int i;
        for (i = len - 1; i >= 0; i--) {
            fcitx_utils_alloc_cat_str(paths[i], addonPath[len - i - 1],
                                      "/", string->name);
            FcitxLog(DEBUG, "Load Addon Config File:%s", paths[i]);
        }
        FcitxConfigFile* cfile = FcitxConfigParseMultiConfigFile(paths, len, FcitxAddonGetConfigDesc());
        if (cfile) {
            utarray_extend_back(addons);
            FcitxAddon *a = (FcitxAddon*) utarray_back(addons);
            utarray_init(&a->functionList, fcitx_ptr_icd);
            FcitxAddonConfigBind(a, cfile, FcitxAddonGetConfigDesc());
            FcitxConfigBindSync((FcitxGenericConfig*)a);
            FcitxLog(DEBUG, _("Addon Config %s is %s"), string->name, (a->bEnabled) ? "Enabled" : "Disabled");
            boolean error = false;
            if (reloadIM) {
                if (a->category !=  AC_INPUTMETHOD)
                    error = true;
            }
            /* if loaded, don't touch the old one */
            if (FcitxAddonsGetAddonByNameInternal(addons, a->name, true) != a)
                error = true;

            if (error)
                utarray_pop_back(addons);
            else
                FcitxLog(INFO, _("Load Addon Config File:%s"), string->name);
        }

        for (i = len - 1;i >= 0;i--) {
            free(paths[i]);
        }
    }
    FcitxXDGFreePath(addonPath);

    fcitx_utils_free_string_hash_set(sset);

    size_t to = utarray_len(addons);
    utarray_sort_range(addons, AddonPriorityCmp, start, to);

    return (FcitxAddon*)utarray_eltptr(addons, start);
}