X-Git-Url: http://git.maemo.org/git/?p=mim;a=blobdiff_plain;f=src%2Fui%2Fmim-immodule.c;h=2d377116bfe137552c64f72f7c91b3a805d99950;hp=b2ef13eb616e2708882393789bc67e23f24cd18a;hb=c5e63466f92675fa671e15514ca41ec9c07fdecb;hpb=cf2341863df87e85c38f8cac1bd154d1b7ccf89d;ds=sidebyside diff --git a/src/ui/mim-immodule.c b/src/ui/mim-immodule.c index b2ef13e..2d37711 100644 --- a/src/ui/mim-immodule.c +++ b/src/ui/mim-immodule.c @@ -13,501 +13,114 @@ #include "im-extra-intl.h" - GType type_mim = 0; -enum { MIM_MAX_COMPOSE_LEN = 3 }; - -typedef struct -{ - guint keys[MIM_MAX_COMPOSE_LEN + 1]; /* 0-terminated */ - gchar *normal; - gchar *initial; - gchar *final; - gboolean is_terminator; /* true if a preceding possible final form - should be final */ -} -ComposeSequence; - -/* like GtkIMContextSimple */ -static guint compose_buffer[MIM_MAX_COMPOSE_LEN + 1]; -static int n_compose = 0; -static ComposeSequence *preceding_possible_final_form = NULL; - -static ComposeSequence mim_compose_seqs[] = -{ - { { GDK_a, 0, 0, 0, }, "אַ", NULL, NULL, FALSE, }, - { { GDK_A, 0, 0, 0, }, "א", NULL, NULL, FALSE, }, - { { GDK_b, 0, 0, 0, }, "ב", NULL, NULL, FALSE, }, - { { GDK_B, 0, 0, 0, }, "בֿ", NULL, NULL, FALSE, }, - { { GDK_c, 0, 0, 0, }, "צ", NULL, "ץ", FALSE, }, - { { GDK_C, 0, 0, 0, }, "ץ", NULL, NULL, FALSE, }, - { { GDK_g, 0, 0, 0, }, "ג", NULL, NULL, FALSE, }, - { { GDK_d, 0, 0, 0, }, "ד", NULL, NULL, FALSE, }, - { { GDK_h, 0, 0, 0, }, "ה", NULL, NULL, FALSE, }, - { { GDK_i, 0, 0, 0, }, "י", "אי", NULL, FALSE, }, - { { GDK_I, 0, 0, 0, }, "יִ", "איִ", NULL, FALSE, }, - { { GDK_v, 0, 0, 0, }, "װ", NULL, NULL, FALSE, }, - { { GDK_z, 0, 0, 0, }, "ז", NULL, NULL, FALSE, }, - { { GDK_H, 0, 0, 0, }, "ח", NULL, NULL, FALSE, }, - { { GDK_t, 0, 0, 0, }, "ט", NULL, NULL, FALSE, }, - { { GDK_T, 0, 0, 0, }, "תּ", NULL, NULL, FALSE, }, - { { GDK_y, 0, 0, 0, }, "י", NULL, NULL, FALSE, }, - { { GDK_x, 0, 0, 0, }, "כ", NULL, "ך", FALSE, }, - { { GDK_X, 0, 0, 0, }, "ך", NULL, NULL, FALSE, }, - { { GDK_l, 0, 0, 0, }, "ל", NULL, NULL, FALSE, }, - { { GDK_m, 0, 0, 0, }, "מ", NULL, "ם", FALSE, }, - { { GDK_M, 0, 0, 0, }, "ם", NULL, NULL, FALSE, }, - { { GDK_n, 0, 0, 0, }, "נ", NULL, "ן", FALSE, }, - { { GDK_N, 0, 0, 0, }, "ן", NULL, NULL, FALSE, }, - { { GDK_s, 0, 0, 0, }, "ס", NULL, NULL, FALSE, }, - { { GDK_S, 0, 0, 0, }, "ת", NULL, NULL, FALSE, }, - { { GDK_e, 0, 0, 0, }, "ע", NULL, NULL, FALSE, }, - { { GDK_E, 0, 0, 0, }, "ײ", "אײ", NULL, FALSE, }, - { { GDK_o, 0, 0, 0, }, "אָ", NULL, NULL, FALSE, }, - { { GDK_O, 0, 0, 0, }, "ױ", "אױ", NULL, FALSE, }, - { { GDK_u, 0, 0, 0, }, "ו", "או", NULL, FALSE, }, - { { GDK_U, 0, 0, 0, }, "וּ", "אוּ", NULL, FALSE, }, - { { GDK_p, 0, 0, 0, }, "פּ", NULL, NULL, FALSE, }, - { { GDK_P, 0, 0, 0, }, "פ", NULL, NULL, FALSE, }, - { { GDK_w, 0, 0, 0, }, "ש", NULL, NULL, FALSE, }, - { { GDK_W, 0, 0, 0, }, "שׂ", NULL, NULL, FALSE, }, - { { GDK_f, 0, 0, 0, }, "פֿ", NULL, "ף", FALSE, }, - { { GDK_F, 0, 0, 0, }, "ף", NULL, NULL, FALSE, }, - { { GDK_k, 0, 0, 0, }, "ק", NULL, NULL, FALSE, }, - { { GDK_K, 0, 0, 0, }, "כּ", NULL, NULL, FALSE, }, - { { GDK_r, 0, 0, 0, }, "ר", NULL, NULL, FALSE, }, - { { GDK_Y, 0, 0, 0, }, "ײַ", "אײַ", NULL, FALSE, }, - { { GDK_minus, 0, 0, 0, }, "־", NULL, NULL, TRUE, }, - { { GDK_apostrophe, 0, 0, 0, }, "'", NULL, NULL, TRUE, }, - { { GDK_comma, 0, 0, 0, }, ",", NULL, NULL, TRUE, }, - { { GDK_s, GDK_h, 0, 0, }, "ש", NULL, NULL, FALSE, }, - { { GDK_t, GDK_s, 0, 0, }, "צ", NULL, "ץ", FALSE, }, - { { GDK_t, GDK_z, 0, 0, }, "צ", NULL, "ץ", FALSE, }, - { { GDK_z, GDK_h, 0, 0, }, "זש", NULL, NULL, FALSE, }, - { { GDK_a, GDK_y, 0, 0, }, "ײַ", "אײַ", NULL, FALSE, }, - { { GDK_o, GDK_y, 0, 0, }, "ױ", "אױ", NULL, FALSE, }, - { { GDK_o, GDK_i, 0, 0, }, "ױ", "אױ", NULL, FALSE, }, - { { GDK_d, GDK_j, 0, 0, }, "דזש", NULL, NULL, FALSE, }, - { { GDK_e, GDK_y, 0, 0, }, "ײ", "אײ", NULL, FALSE, }, - { { GDK_apostrophe, GDK_apostrophe, 0, 0, }, "“", NULL, NULL, TRUE, }, - { { GDK_comma, GDK_comma, 0, 0, }, "„", NULL, NULL, TRUE, }, - { { GDK_k, GDK_h, 0, 0, }, "כ", NULL, "ך", FALSE, }, - { { GDK_c, GDK_h, 0, 0, }, "כ", NULL, "ך", FALSE, }, - { { GDK_u, GDK_v, 0, 0, }, "וּװ", "אוּװ", NULL, FALSE, }, - { { GDK_u, GDK_u, 0, 0, }, "וּו", "אוּו", NULL, FALSE, }, - { { GDK_u, GDK_i, 0, 0, }, "ויִ", "אויִ", NULL, FALSE, }, - { { GDK_u, GDK_y, 0, 0, }, "וּי", "אוּי", NULL, FALSE, }, - { { GDK_v, GDK_u, 0, 0, }, "װוּ", NULL, NULL, FALSE, }, - { { GDK_y, GDK_i, 0, 0, }, "ייִ", NULL, NULL, FALSE, }, - { { GDK_i, GDK_i, 0, 0, }, "יִיִ", "איִיִ", NULL, FALSE, }, - { { GDK_i, GDK_y, 0, 0, }, "יִי", "איִי", NULL, FALSE, }, - { { GDK_E, GDK_i, 0, 0, }, "ײיִ", "אײיִ", NULL, FALSE, }, - { { GDK_i, GDK_e, 0, 0, }, "יִע", "איִע", NULL, FALSE, }, - { { GDK_i, GDK_a, 0, 0, }, "יִאַ", "איִאַ", NULL, FALSE, }, - { { GDK_i, GDK_o, 0, 0, }, "יִאָ", "איִאָ", NULL, FALSE, }, - { { GDK_t, GDK_s, GDK_h, 0, }, "טש", NULL, NULL, FALSE, }, -}; - - -static const guint16 mim_compose_ignore[] = -{ - GDK_Shift_L, - GDK_Shift_R, - GDK_Control_L, - GDK_Control_R, - GDK_Caps_Lock, - GDK_Shift_Lock, - GDK_Meta_L, - GDK_Meta_R, - GDK_Alt_L, - GDK_Alt_R, - GDK_Super_L, - GDK_Super_R, - GDK_Hyper_L, - GDK_Hyper_R, - GDK_Mode_switch, -}; - - -static void -clear_compose_buffer () -{ - memset (compose_buffer, 0, sizeof (compose_buffer)); - n_compose = 0; -} - - -/* handles null case */ -static void -commit_preceding_possible_final_form (GtkIMContext *context, - gboolean is_final) -{ - if (preceding_possible_final_form != NULL) - { - if (is_final) - g_signal_emit_by_name (context, "commit", - preceding_possible_final_form->final); - else - g_signal_emit_by_name (context, "commit", - preceding_possible_final_form->normal); - - preceding_possible_final_form = NULL; - } -} - -/* returns the composed string iff keys exactly matches the compose - * sequence keys */ -static ComposeSequence * -find_complete_compose_sequence (guint *keys) -{ - gint i, j; - - for (i = 0; i < G_N_ELEMENTS (mim_compose_seqs); i++) - for (j = 0; j <= MIM_MAX_COMPOSE_LEN; j++) - { - if (keys[j] != mim_compose_seqs[i].keys[j]) - break; - else if (keys[j] == 0 && keys[j] == mim_compose_seqs[i].keys[j]) - return mim_compose_seqs + i; - } - - return NULL; -} - - -/* returns the composed string iff keys is a substring thang of the compose - * sequence keys */ -static ComposeSequence * -find_incomplete_compose_sequence (guint *keys) -{ - gint i, j; - - for (i = 0; i < G_N_ELEMENTS (mim_compose_seqs); i++) - for (j = 0; j <= MIM_MAX_COMPOSE_LEN; j++) - { - if (keys[j] == 0 && mim_compose_seqs[i].keys[j] != 0) - return mim_compose_seqs + i; - else if (keys[j] != mim_compose_seqs[i].keys[j]) - break; - } - - return NULL; -} - - -static gchar * -get_appropriate_string (ComposeSequence *comp_seq, gboolean is_initial) -{ - if (comp_seq == NULL) - return NULL; - else if (is_initial && comp_seq->initial != NULL) - return comp_seq->initial; - else - return comp_seq->normal; -} - - -/* is this a character that could appear in a mim word */ -static gboolean -is_mim_word_character (gunichar uc) -{ - return (((uc >= 0x0590 && uc <= 0x5ff) || (uc >= 0xfb1d && uc <= 0xfb4f)) - && g_unichar_isdefined (uc) && ! g_unichar_ispunct (uc)); - -} - - static gboolean -at_initial_position (GtkIMContext *context) +mim_filter_keypress(GtkIMContext *context, + GdkEventKey *event) { - gchar *text; - gchar *prevp; - gint cursor_index; - gunichar uc; - - if (! gtk_im_context_get_surrounding (context, &text, &cursor_index)) - return FALSE; - - prevp = g_utf8_find_prev_char (text, text + cursor_index); - if (prevp == NULL) - return TRUE; - - uc = g_utf8_get_char_validated (prevp, text + cursor_index - prevp); - g_return_val_if_fail (uc != (gunichar)(-1) && uc != (gunichar)(-2), - FALSE); + if (event->type == GDK_KEY_RELEASE) + return FALSE; - if (is_mim_word_character (uc)) - return FALSE; - else return TRUE; } - -static void -mim_get_preedit_string (GtkIMContext *context, - gchar **str, - PangoAttrList **attrs, - gint *cursor_pos) -{ - ComposeSequence *comp_seq; - gboolean is_initial; - gchar *string; - gint len; - - is_initial = at_initial_position (context) - && preceding_possible_final_form == NULL; - - comp_seq = find_complete_compose_sequence (compose_buffer); - if (comp_seq == NULL) - string = ""; - else - string = get_appropriate_string (comp_seq, is_initial); - - if (preceding_possible_final_form != NULL) - *str = g_strdup_printf ("%s%s", preceding_possible_final_form->normal, - string); - else - *str = g_strdup (string); - - len = strlen (*str); - - if (attrs) - { - *attrs = pango_attr_list_new (); - - if (len != 0) - { - PangoAttribute *attr; - attr = pango_attr_underline_new (PANGO_UNDERLINE_SINGLE); - attr->start_index = 0; - attr->end_index = len; - pango_attr_list_insert (*attrs, attr); - } - } - - if (cursor_pos) - *cursor_pos = len; -} - - static void -mim_reset (GtkIMContext *context) +mim_set_client_window(GtkIMContext *context, + GdkWindow *window) { - clear_compose_buffer (); - preceding_possible_final_form = NULL; - g_signal_emit_by_name (context, "preedit-changed"); -} - - -static gboolean -no_sequence_matches (GtkIMContext *context, GdkEventKey *event) -{ - gunichar uc; - gchar buf[7]; - - uc = gdk_keyval_to_unicode (event->keyval); - if (uc != 0) - { - buf[g_unichar_to_utf8 (uc, buf)] = '\0'; - g_signal_emit_by_name (context, "commit", buf); - g_signal_emit_by_name (context, "preedit-changed"); - - return TRUE; + if (window == NULL) { + /*TODO: create new client window */ + //mim_mui_create_window(); } - else - return FALSE; } - -static gboolean -mim_filter_keypress (GtkIMContext *context, - GdkEventKey *event) -{ - ComposeSequence *comp_seq; - gboolean is_initial; - gint i; - - if (event->type == GDK_KEY_RELEASE) - return FALSE; - - /* don't filter key events with accelerator modifiers held down */ - if (event->state - & (gtk_accelerator_get_default_mod_mask () & ~GDK_SHIFT_MASK)) - return FALSE; - - for (i = 0; i < G_N_ELEMENTS (mim_compose_ignore); i++) - if (event->keyval == mim_compose_ignore[i]) - return FALSE; - - is_initial = at_initial_position (context) - && preceding_possible_final_form == NULL; - - /* '|' commits what we have */ - if (event->keyval == GDK_bar && (n_compose > 0 - || preceding_possible_final_form != NULL)) - { - commit_preceding_possible_final_form (context, FALSE); /* non-final */ - - comp_seq = find_complete_compose_sequence (compose_buffer); - if (comp_seq != NULL) - { - g_signal_emit_by_name (context, "commit", - get_appropriate_string (comp_seq, is_initial)); - clear_compose_buffer (); - } - - g_signal_emit_by_name (context, "preedit-changed"); - return TRUE; - } - - compose_buffer[n_compose] = event->keyval; - n_compose++; - - if (find_incomplete_compose_sequence (compose_buffer) != NULL) - { - g_signal_emit_by_name (context, "preedit-changed"); - return TRUE; - } - - comp_seq = find_complete_compose_sequence (compose_buffer); - if (comp_seq != NULL) - { - if (comp_seq->final != NULL) /* has a final form, don't commit yet */ - { - commit_preceding_possible_final_form (context, - comp_seq->is_terminator); - clear_compose_buffer (); - preceding_possible_final_form = comp_seq; - g_signal_emit_by_name (context, "preedit-changed"); - return TRUE; - } - else - { - commit_preceding_possible_final_form (context, - comp_seq->is_terminator); - g_signal_emit_by_name (context, "commit", - get_appropriate_string (comp_seq, is_initial)); - clear_compose_buffer (); - g_signal_emit_by_name (context, "preedit-changed"); - return TRUE; - } - } - - /* if we reach this point, the sequence *with the key just pressed* - * cannot be a complete or incomplete match, so: commit the old sequence, - * then reprocess this key */ - - n_compose--; - compose_buffer[n_compose] = 0; - - if (n_compose > 0) - { - comp_seq = find_complete_compose_sequence (compose_buffer); - commit_preceding_possible_final_form (context, comp_seq->is_terminator); - if (comp_seq->final != NULL) - { - clear_compose_buffer (); - preceding_possible_final_form = comp_seq; - } - else - { - g_signal_emit_by_name (context, "commit", - get_appropriate_string (comp_seq, is_initial)); - clear_compose_buffer (); - g_signal_emit_by_name (context, "preedit-changed"); - } - - return mim_filter_keypress (context, event); - } - else - commit_preceding_possible_final_form (context, TRUE); - - return no_sequence_matches (context, event); -} - - static void -mim_class_init (GtkIMContextClass *clazz) +mim_reset(GtkIMContext *context) { - clazz->filter_keypress = mim_filter_keypress; - clazz->get_preedit_string = mim_get_preedit_string; - clazz->reset = mim_reset; } static void -mim_init (GtkIMContext *im_context) +mim_class_init(GtkIMContextClass *clazz) { + clazz->filter_keypress = mim_filter_keypress; + clazz->reset = mim_reset; + clazz->set_client_window = mim_set_client_window; } - static void -mim_register_type (GTypeModule *module) +mim_init(GtkIMContext *im_context) { - static const GTypeInfo object_info = - { - sizeof (GtkIMContextClass), - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) mim_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (GtkIMContext), - 0, - (GInstanceInitFunc) mim_init, - }; - - type_mim = - g_type_module_register_type (module, - GTK_TYPE_IM_CONTEXT, - "GtkIMContextYiddishNoah", - &object_info, 0); } - -static const GtkIMContextInfo mim_info = +static void +mim_register_type(GTypeModule *module) { - "mim", /* ID */ - N_("MiM"), /* Human readable name */ - GETTEXT_PACKAGE, /* Translation domain */ - LOCALEDIR, /* Dir for bindtextdomain */ - "zh_CN", /* Languages for which this module is the default */ + static const GTypeInfo object_info = + { + sizeof(GtkIMContextClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) mim_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof(GtkIMContext), + 0, + (GInstanceInitFunc) mim_init, + }; + + type_mim = g_type_module_register_type(module, + GTK_TYPE_IM_CONTEXT, + "GtkIMContextYiddishNoah", + &object_info, + 0); +} + +static const +GtkIMContextInfo mim_info = +{ + "mim", /* ID */ + N_("MiM"), /* Human readable name */ + GETTEXT_PACKAGE, /* Translation domain */ + LOCALEDIR, /* Dir for bindtextdomain */ + "zh_CN", /* Languages for which this module is the default */ }; - -static const GtkIMContextInfo *info_list[] = +static const +GtkIMContextInfo *info_list[] = { - &mim_info, + &mim_info, }; - void -im_module_init (GTypeModule *module) +im_module_init(GTypeModule *module) { - mim_register_type (module); + g_debug("mim-immodule imported!"); + mim_register_type(module); + /*TODO: Mask off the accelerators, except the CTRL (need for CTRL + * ^SPACE) */ } void -im_module_exit () +im_module_exit() { + g_debug("mim-immodule released!"); } -void -im_module_list (const GtkIMContextInfo ***contexts, gint *n_contexts) +void +im_module_list(const GtkIMContextInfo ***contexts, + gint *n_contexts) { - *contexts = info_list; - *n_contexts = G_N_ELEMENTS (info_list); + *contexts = info_list; + *n_contexts = G_N_ELEMENTS(info_list); } - GtkIMContext * -im_module_create (const gchar *context_id) +im_module_create(const gchar *context_id) { - if (strcmp (context_id, "mim-n") == 0) - return GTK_IM_CONTEXT (g_object_new (type_mim, NULL)); - else - return NULL; + if (strcmp(context_id, "mim") == 0) + return GTK_IM_CONTEXT(g_object_new(type_mim, NULL)); + else + return NULL; } - -