MPlist * open (MPlist *args) { MInputContext *ic; TableContext *context; MSymbol type; int i; ic = mplist_value (args); context = get_context (ic); args = mplist_next (args); type = (MSymbol) mplist_value (args); args = mplist_next (args); for (i = 0; i < DIM(table_descriptions); i++) if (strcmp (table_descriptions[i].name, msymbol_name (type)) == 0) { context->desc = &table_descriptions[i]; break; } if (context->desc) (*context->desc->open) (context, args); return NULL; }
static void insert_m17n_items (GtkListStore *store, MSymbol language, MSymbol name) { MPlist *plist; plist = minput_get_variable (language, name, Mnil); for (; plist && mplist_key (plist) == Mplist; plist = mplist_next (plist)) { GtkTreeIter iter; MSymbol key; MPlist *p, *mvalue; gchar *description, *value; p = mplist_value (plist); key = mplist_value (p); /* name */ p = mplist_next (p); /* description */ description = ibus_m17n_mtext_to_utf8 ((MText *) mplist_value (p)); p = mplist_next (p); /* status */ mvalue = mplist_next (p); value = format_m17n_value (mvalue); gtk_list_store_append (store, &iter); gtk_list_store_set (store, &iter, COLUMN_KEY, msymbol_name (key), COLUMN_DESCRIPTION, description, COLUMN_VALUE, value, -1); g_free (description); g_free (value); } }
static MPlist * open_ibus (TableContext *context, MPlist *args) { MText *mt; int rc; char *file = NULL; unsigned char buf[256]; mt = (MText *) mplist_value (args); rc = mtext_to_utf8 (context, mt, buf, sizeof (buf)); if (rc < 0) return NULL; file = strdup ((const char *)buf); args = mplist_next (args); if (mplist_key (args) == Minteger) context->xlen = (long) mplist_value (args); else context->xlen = XLEN; args = mplist_next (args); if (mplist_key (args) == Minteger) context->max_candidates = (long) mplist_value (args); else context->max_candidates = MAX_CANDIDATES; if (context->db && context->file && strcmp (context->file, file) != 0) { sqlite3_close (context->db); context->db = NULL; free (context->file); } context->file = file; if (!context->db) { rc = sqlite3_open_v2 (file, &context->db, SQLITE_OPEN_READONLY, NULL); if (rc) { sqlite3_close (context->db); context->db = NULL; free (context->file); context->file = NULL; } rc = get_ime_attr_int (context, "max_key_length", &context->mlen); if (rc < 0) context->mlen = MLEN; } return NULL; }
static TableContext * get_context (MInputContext *ic) { MPlist *plist = ic->plist; TableContext *context; for (; plist && mplist_key (plist) != Mnil; plist = mplist_next (plist)) { if (mplist_key (plist) != Mtable) continue; context = mplist_value (plist); if (context->ic == ic) return context; } return NULL; }
static uim_lisp init_m17nlib() { MPlist *imlist, *elm; M17N_INIT(); nr_input_methods = 0; nr_input_contexts = 0; im_array = NULL; ic_array = NULL; imlist = mdatabase_list(msymbol("input-method"), Mnil, Mnil, Mnil); if (!imlist) { /* maybe user forgot to install m17n-db */ return uim_scm_f(); } for (elm = imlist; mplist_key(elm) != Mnil; elm = mplist_next(elm)) { MDatabase *mdb; MSymbol *tag, lang, imname; uim_bool is_complete_im; mdb = mplist_value(elm); tag = mdatabase_tag(mdb); lang = tag[1]; imname = tag[2]; is_complete_im = (lang != Mnil && imname != Mnil); /* [uim-ja 30] */ if (is_complete_im) { /* pass NULL as IM to enable lazy instantiation */ pushback_input_method(NULL, msymbol_name(lang), msymbol_name(imname)); } } #if 0 register_callbacks(); #endif m17n_object_unref(imlist); converter = mconv_buffer_converter(msymbol("utf8"), NULL, 0); if (!converter) return uim_scm_f(); m17nlib_ok = 1; return uim_scm_t(); }
static MPlist * paginate (MPlist *candidates) { MPlist *p = candidates, *pl = mplist (), *plist = mplist (); int i; for (i = 0; mplist_key (p) == Mtext; p = mplist_next (p), i++) { mplist_add (pl, Mtext, mplist_value (p)); if (i % 10 == 9) { mplist_add (plist, Mplist, pl); m17n_object_unref (pl); pl = mplist (); } } if (mplist_key (pl) != Mnil) mplist_add (plist, Mplist, pl); m17n_object_unref (pl); return plist; }
int main() { MPlist *imlist, *elm; MSymbol utf8 = msymbol("utf8"); M17N_INIT(); imlist = mdatabase_list(msymbol("input-method"), Mnil, Mnil, Mnil); for (elm = imlist; elm && mplist_key(elm) != Mnil; elm = mplist_next(elm)) { MDatabase *mdb = (MDatabase *) mplist_value(elm); MSymbol *tag = mdatabase_tag(mdb); if (tag[1] != Mnil) { MInputMethod *im = minput_open_im(tag[1], tag[2], NULL); if (im) { std::cout << msymbol_name (im->language); std::cout << "-"; std::cout << msymbol_name (im->name); std::cout << "\n"; } } } M17N_FINI(); }
static void nimf_m17n_update_candidate (NimfEngine *engine, NimfServiceIC *target) { g_debug (G_STRLOC ": %s", G_STRFUNC); NimfM17n *m17n = NIMF_M17N (engine); nimf_candidatable_clear (m17n->candidatable, target); MPlist *page; m17n->current_page = m17n->ic->candidate_index / 10 + 1; m17n->n_pages = 0; for (page = m17n->ic->candidate_list; page && mplist_key (page) != Mnil; page = mplist_next (page)) { MSymbol type = mplist_key (page); m17n->n_pages++; if (m17n->current_page != m17n->n_pages) continue; if (type == Mplist) { MPlist *items; for (items = mplist_value (page); items && mplist_key (items) != Mnil; items = mplist_next (items)) { gchar *item; item = nimf_m17n_mtext_to_utf8 (m17n, mplist_value (items)); nimf_candidatable_append (m17n->candidatable, item, NULL); g_free (item); } } else if (type == Mtext) { gchar *items; gint i, len; items = nimf_m17n_mtext_to_utf8 (m17n, (MText *) mplist_value (page)); len = g_utf8_strlen (items, -1); for (i = 0; i < len; i++) { gchar item[4]; gchar *p = g_utf8_offset_to_pointer (items, i); g_utf8_strncpy (item, p, 1); nimf_candidatable_append (m17n->candidatable, item, NULL); } g_free (items); } } nimf_candidatable_select_item_by_index_in_page (m17n->candidatable, m17n->ic->candidate_index % 10); nimf_candidatable_set_page_values (m17n->candidatable, target, m17n->current_page, m17n->n_pages, 10); }
MPlist * lookup (MPlist *args) { MInputContext *ic; MPlist *actions = NULL, *candidates, *plist; MSymbol init_state; MSymbol select_state; TableContext *context; MText *mt; ic = mplist_value (args); context = get_context (ic); args = mplist_next (args); init_state = (MSymbol) mplist_value (args); args = mplist_next (args); select_state = (MSymbol) mplist_value (args); if (context->desc) candidates = (*context->desc->lookup) (context, args); else candidates = mplist (); if (mplist_length (candidates) == 0) { m17n_object_unref (candidates); return NULL; } #if 0 /* FIXME: if only one candidate is matching, we should insert it and commit immediately. However, this feature is disabled for now since users would type extra characters after the match. For example, with mr-inscript-typing-booster, an Indic word "Epgyepgne" is only one candidate when a user type "Epgyepgn", but the user will likely to type "e" after commit. */ if (mplist_length (candidates) == 1) { actions = mplist (); add_action (actions, msymbol ("delete"), Msymbol, msymbol ("@<")); add_action (actions, msymbol ("insert"), Mtext, mplist_value (candidates)); add_action (actions, msymbol ("commit"), Mnil, NULL); m17n_object_unref (candidates); return actions; } #endif actions = mplist (); mt = mtext_dup (ic->preedit); mplist_push (candidates, Mtext, mt); m17n_object_unref (mt); plist = paginate (candidates); m17n_object_unref (candidates); add_action (actions, msymbol ("delete"), Msymbol, msymbol ("@<")); mplist_add (actions, Mplist, plist); m17n_object_unref (plist); add_action (actions, msymbol ("select"), Minteger, (void *)1); add_action (actions, msymbol ("show"), Mnil, NULL); add_action (actions, msymbol ("shift"), Msymbol, select_state); return actions; }
static MPlist * open_scim (TableContext *context, MPlist *args) { MText *mt; int rc; char *file = NULL; unsigned char buf[BUFSIZE]; mt = (MText *) mplist_value (args); rc = mtext_to_utf8 (context, mt, buf, sizeof (buf)); if (rc < 0) return NULL; file = strdup ((const char *)buf); args = mplist_next (args); if (mplist_key (args) == Minteger) context->xlen = (long) mplist_value (args); else context->xlen = XLEN; args = mplist_next (args); if (mplist_key (args) == Minteger) context->max_candidates = (long) mplist_value (args); else context->max_candidates = MAX_CANDIDATES; if (context->mem && context->file && strcmp (context->file, file) != 0) { munmap (context->mem, context->memlen); context->mem = NULL; free (context->file); if (context->fp) { fclose (context->fp); context->fp = NULL; } } if (!context->fp) context->fp = fopen (file, "rb"); if (!context->mem) { while (1) { if (!fgets ((char *)buf, sizeof buf, context->fp)) break; if (strncmp ("###", (const char *)buf, 3) == 0) continue; if (strncmp ("MAX_KEY_LENGTH", (const char *)buf, 14) == 0) { char *p = strrchr ((char *)buf, '\n'); if (!*p) continue; *p-- = '\0'; while (*p >= '0' && *p <= '9') p--; context->mlen = strtoul (p + 1, NULL, 10); continue; } if (strncmp ("BEGIN_TABLE", (const char *)buf, 11) == 0) { long start_pos, end_pos; if (fread (buf, 4, 1, context->fp) != 1) break; context->content_size = scim_bytestouint32 (buf); start_pos = ftell (context->fp); if (fseek (context->fp, 0, SEEK_END) < 0) break; end_pos = ftell (context->fp); if (context->content_size >= end_pos - start_pos) break; context->mem = mmap (0, end_pos, PROT_READ, MAP_PRIVATE, fileno (context->fp), 0); if (context->mem) { context->memlen = end_pos; context->content = (unsigned char *)context->mem + start_pos; context->file = file; } break; } } } if (!context->mem) { free (file); return NULL; } if (!context->offsets) { int offset; if (!context->mlen) context->mlen = MLEN; context->offsets = calloc (sizeof (TableOffsetArray), context->mlen); for (offset = 0; offset < context->content_size;) { int klen = context->content[offset] & 0x3F; int plen = context->content[offset + 1]; TableOffsetArray *array; assert (klen > 0); if (klen > context->mlen) continue; array = &context->offsets[klen - 1]; if (array->cap < array->len + 1) { if (array->cap == 0) { array->cap = 1; array->data = calloc (sizeof (int), array->cap); if (!array->data) return NULL; } else { array->cap *= 2; array->data = realloc (array->data, sizeof (int) * array->cap); if (!array->data) return NULL; memset (array->data + array->len, 0, array->cap - array->len); } } *(array->data + array->len++) = offset; offset += 4 + klen + plen; } } return NULL; }
static void ibus_m17n_engine_update_lookup_table (IBusM17NEngine *m17n) { ibus_lookup_table_clear (m17n->table); if (m17n->context->candidate_list && m17n->context->candidate_show) { IBusText *text; MPlist *group; group = m17n->context->candidate_list; gint i = 0; gint page = 1; IBusM17NEngineClass *klass = (IBusM17NEngineClass *) G_OBJECT_GET_CLASS (m17n); while (1) { gint len; if (mplist_key (group) == Mtext) len = mtext_len ((MText *) mplist_value (group)); else len = mplist_length ((MPlist *) mplist_value (group)); if (i + len > m17n->context->candidate_index) break; i += len; group = mplist_next (group); page ++; } if (mplist_key (group) == Mtext) { MText *mt; gunichar *buf; glong nchars, i; mt = (MText *) mplist_value (group); ibus_lookup_table_set_page_size (m17n->table, mtext_len (mt)); buf = ibus_m17n_mtext_to_ucs4 (mt, &nchars); for (i = 0; i < nchars; i++) { ibus_lookup_table_append_candidate (m17n->table, ibus_text_new_from_unichar (buf[i])); } g_free (buf); } else { MPlist *p; p = (MPlist *) mplist_value (group); ibus_lookup_table_set_page_size (m17n->table, mplist_length (p)); for (; mplist_key (p) != Mnil; p = mplist_next (p)) { MText *mtext; gchar *buf; mtext = (MText *) mplist_value (p); buf = ibus_m17n_mtext_to_utf8 (mtext); if (buf) { ibus_lookup_table_append_candidate (m17n->table, ibus_text_new_from_string (buf)); g_free (buf); } } } ibus_lookup_table_set_cursor_pos (m17n->table, m17n->context->candidate_index - i); ibus_lookup_table_set_orientation (m17n->table, klass->lookup_table_orientation); text = ibus_text_new_from_printf ("( %d / %d )", page, mplist_length (m17n->context->candidate_list)); ibus_engine_update_lookup_table ((IBusEngine *)m17n, m17n->table, TRUE); ibus_engine_update_auxiliary_text ((IBusEngine *)m17n, text, TRUE); } else { ibus_engine_hide_lookup_table ((IBusEngine *)m17n); ibus_engine_hide_auxiliary_text ((IBusEngine *)m17n); } }