Пример #1
0
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;
}
Пример #2
0
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);
    }
}
Пример #3
0
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;
}
Пример #4
0
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;
}
Пример #5
0
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);
}
Пример #6
0
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;
}
Пример #7
0
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();
}
Пример #8
0
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);
}
Пример #9
0
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();
}
Пример #10
0
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;
}
Пример #11
0
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;
}
Пример #12
0
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;
}
Пример #13
0
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);
    }
}
Пример #14
0
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);
}
Пример #15
0
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;
}
Пример #16
0
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);
    }
}
Пример #17
0
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;
}