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 gchar * format_m17n_value (MPlist *plist) { if (mplist_key (plist) == Msymbol) return g_strdup (msymbol_name ((MSymbol) mplist_value (plist))); if (mplist_key (plist) == Mtext) return g_strdup (mtext_data ((MText *) mplist_value (plist), NULL, NULL, NULL, NULL)); if (mplist_key (plist) == Minteger) return g_strdup_printf ("%d", (gint) (long) mplist_value (plist)); return NULL; }
static void on_get_surrounding_text (MInputContext *context, MSymbol command) { g_debug (G_STRLOC ": %s", G_STRFUNC); NimfM17n *m17n = context->arg; if (!NIMF_IS_M17N (m17n) || !nimf_service_im_target) return; gchar *text; gint cursor_pos, nchars, nbytes; MText *mt, *surround = NULL; int len, pos; nimf_engine_get_surrounding (NIMF_ENGINE (m17n), nimf_service_im_target, &text, &cursor_pos); if (text == NULL) return; nchars = g_utf8_strlen (text, -1); nbytes = strlen (text); mt = mconv_decode_buffer (Mcoding_utf_8, (const unsigned char *) text, nbytes); g_free (text); len = (long) mplist_value (m17n->ic->plist); if (len < 0) { pos = cursor_pos + len; if (pos < 0) pos = 0; surround = mtext_duplicate (mt, pos, cursor_pos); } else if (len > 0) { pos = cursor_pos + len; if (pos > nchars) pos = nchars; surround = mtext_duplicate (mt, cursor_pos, pos); } if (!surround) surround = mtext (); m17n_object_unref (mt); mplist_set (m17n->ic->plist, Mtext, surround); m17n_object_unref (surround); }
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 void on_delete_surrounding_text (MInputContext *context, MSymbol command) { g_debug (G_STRLOC ": %s", G_STRFUNC); NimfM17n *m17n = context->arg; if (!NIMF_IS_M17N (m17n) || !nimf_service_im_target) return; int len = (long) mplist_value (m17n->ic->plist); if (len < 0) nimf_engine_emit_delete_surrounding (NIMF_ENGINE (m17n), nimf_service_im_target, len, -len); else nimf_engine_emit_delete_surrounding (NIMF_ENGINE (m17n), nimf_service_im_target, 0, len); }
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 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; }
MPlist * fini (MPlist *args) { MInputContext *ic = mplist_value (args); TableContext *context = get_context (ic); if (context) { if (context->db) sqlite3_close (context->db); mconv_free_converter (context->converter); if (context->mem) munmap (context->mem, context->memlen); if (context->fp) { fclose (context->fp); context->fp = NULL; } free (context->file); free (context); } return NULL; }
MPlist * init (MPlist *args) { MInputContext *ic = mplist_value (args); TableContext *context; fflush (stderr); if (! initialized++) { init_phrase_dict (); Mtable = msymbol (" table"); Mibus = msymbol ("ibus"); Mscim = msymbol ("scim"); } context = calloc (sizeof (TableContext), 1); context->ic = ic; context->converter = mconv_buffer_converter (Mcoding_utf_8, NULL, 0); if (context) mplist_push (ic->plist, Mtable, context); 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); } }
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 void ibus_m17n_engine_callback (MInputContext *context, MSymbol command) { IBusM17NEngine *m17n = NULL; m17n = context->arg; g_return_if_fail (m17n != NULL); /* the callback may be called in minput_create_ic, in the time * m17n->context has not be assigned, so need assign it. */ if (m17n->context == NULL) { m17n->context = context; } if (command == Minput_preedit_start) { ibus_engine_hide_preedit_text ((IBusEngine *)m17n); } else if (command == Minput_preedit_draw) { ibus_m17n_engine_update_preedit (m17n); } else if (command == Minput_preedit_done) { ibus_engine_hide_preedit_text ((IBusEngine *)m17n); } else if (command == Minput_status_start) { ibus_engine_hide_preedit_text ((IBusEngine *)m17n); } else if (command == Minput_status_draw) { gchar *status; status = ibus_m17n_mtext_to_utf8 (m17n->context->status); if (status && strlen (status)) { IBusText *text; text = ibus_text_new_from_string (status); ibus_property_set_label (m17n->status_prop, text); ibus_property_set_visible (m17n->status_prop, TRUE); } else { ibus_property_set_label (m17n->status_prop, NULL); ibus_property_set_visible (m17n->status_prop, FALSE); } ibus_engine_update_property ((IBusEngine *)m17n, m17n->status_prop); g_free (status); } else if (command == Minput_status_done) { } else if (command == Minput_candidates_start) { ibus_engine_hide_lookup_table ((IBusEngine *) m17n); ibus_engine_hide_auxiliary_text ((IBusEngine *) m17n); } else if (command == Minput_candidates_draw) { ibus_m17n_engine_update_lookup_table (m17n); } else if (command == Minput_candidates_done) { ibus_engine_hide_lookup_table ((IBusEngine *) m17n); ibus_engine_hide_auxiliary_text ((IBusEngine *) m17n); } else if (command == Minput_set_spot) { } else if (command == Minput_toggle) { } else if (command == Minput_reset) { } /* ibus_engine_get_surrounding_text is only available in the current git master (1.3.99+) */ #ifdef HAVE_IBUS_ENGINE_GET_SURROUNDING_TEXT else if (command == Minput_get_surrounding_text && (((IBusEngine *) m17n)->client_capabilities & IBUS_CAP_SURROUNDING_TEXT) != 0) { IBusText *text; guint cursor_pos, nchars, nbytes; MText *mt, *surround; int len, pos; ibus_engine_get_surrounding_text ((IBusEngine *) m17n, &text, &cursor_pos); nchars = ibus_text_get_length (text); nbytes = g_utf8_offset_to_pointer (text->text, nchars) - text->text; mt = mconv_decode_buffer (Mcoding_utf_8, text->text, nbytes); g_object_unref (text); len = (long) mplist_value (m17n->context->plist); if (len < 0) { pos = cursor_pos + len; if (pos < 0) pos = 0; surround = mtext_duplicate (mt, pos, cursor_pos); } else if (len > 0) { pos = cursor_pos + len; if (pos > nchars) pos = nchars; surround = mtext_duplicate (mt, cursor_pos, pos); } else { surround = mtext (); } m17n_object_unref (mt); mplist_set (m17n->context->plist, Mtext, surround); m17n_object_unref (surround); } #endif /* !HAVE_IBUS_ENGINE_GET_SURROUNDING_TEXT */ else if (command == Minput_delete_surrounding_text && (((IBusEngine *) m17n)->client_capabilities & IBUS_CAP_SURROUNDING_TEXT) != 0) { int len; len = (long) mplist_value (m17n->context->plist); if (len < 0) ibus_engine_delete_surrounding_text ((IBusEngine *) m17n, len, -len); else if (len > 0) ibus_engine_delete_surrounding_text ((IBusEngine *) m17n, 0, len); } }
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; }