void ibus_chewing_engine_property_activate(IBusEngine *engine, const gchar  *prop_name, guint  prop_state){
    IBUS_CHEWING_LOG(3,"[I3] property_activate(-, %s, %u)", prop_name, prop_state);
    Self *self=SELF(engine);
    gboolean needRefresh=TRUE;
    if (strcmp(prop_name,"chewing_chieng_prop")==0){
	/* Toggle Chinese <-> English */
	chewing_set_ChiEngMode(self->context, !chewing_get_ChiEngMode(self->context));
    }else if (strcmp(prop_name,"chewing_alnumSize_prop")==0){
	/* Toggle Full <-> Half */
	chewing_set_ShapeMode(self->context, !chewing_get_ShapeMode(self->context));
    }else if (strcmp(prop_name,"chewing_settings_prop")==0){
#if IBUS_CHECK_VERSION(1, 4, 0)
	if (ibus_property_get_state(self->settings_prop)==PROP_STATE_UNCHECKED)
#else
	if (self->settings_prop->state==PROP_STATE_UNCHECKED)
#endif
	{
	    if (gtk_dialog_run(GTK_DIALOG(self->setting_dialog))==GTK_RESPONSE_OK){
		self_save_config_all(self);
	    }
	    gtk_widget_hide(self->setting_dialog);
#if IBUS_CHECK_VERSION(1, 4, 0)
		ibus_property_set_state(self->settings_prop,PROP_STATE_UNCHECKED);
#else
	    self->settings_prop->state=PROP_STATE_UNCHECKED;
#endif
	}
    }else{
	IBUS_CHEWING_LOG(3,"[I3]  property_activate(-, %s, %u) not recognized",prop_name, prop_state);
	needRefresh=FALSE;
    }
    if (needRefresh)
	self_refresh_property(self,prop_name);
}
void refresh_aux_text(IBusChewingEngine * self)
{
    if (!ibus_chewing_engine_has_capabilite(self, IBUS_CAP_AUXILIARY_TEXT)) {
	return;
    }
    IBUS_CHEWING_LOG(INFO, "refresh_aux_text()");
    gchar *auxStr;
    if (self->auxText != NULL) {
	g_object_unref(self->auxText);
    }

    if (chewing_aux_Length(self->icPreEdit->context) > 0) {
	auxStr = chewing_aux_String(self->icPreEdit->context);
	IBUS_CHEWING_LOG(INFO, "update_aux_text() auxStr=%s", auxStr);
    } else {
	IBUS_CHEWING_LOG(INFO, "update_aux_text() bpmf_check=%x",
			 ibus_chewing_bopomofo_check(self->
						     icPreEdit->context));
	gchar *bpmfStr =
	    ibus_chewing_pre_edit_get_bopomofo_string(self->icPreEdit);
	IBUS_CHEWING_LOG(INFO, "update_aux_text() bpmfStr=%s", bpmfStr);
	self->auxText =
	    g_object_ref_sink(ibus_text_new_from_string(bpmfStr));
	g_free(bpmfStr);
    }
}
IBusText *decorate_pre_edit(IBusChewingPreEdit * icPreEdit,
			    IBusCapabilite capabilite)
{
    gchar *preEdit = ibus_chewing_pre_edit_get_pre_edit(icPreEdit);
    IBusText *iText =
	g_object_ref_sink(ibus_text_new_from_string(preEdit));

    gint chiSymbolCursor = chewing_cursor_Current(icPreEdit->context);
    IBUS_CHEWING_LOG(DEBUG,
		     "decorate_pre_edit() cursor=%d preEdit=%s",
		     chiSymbolCursor, preEdit);


    gint charLen = (gint) g_utf8_strlen(preEdit, -1);
    gint cursorRight = chiSymbolCursor + icPreEdit->bpmfLen;

    IBUS_CHEWING_LOG(DEBUG,
		     "decorate_pre_edit() charLen=%d cursorRight=%d",
		     charLen, cursorRight);

    IntervalType it;
    chewing_interval_Enumerate(icPreEdit->context);
    /* Add double lines on chewing interval that contains cursor */
    /* Add single line on other chewing interval */
    while (chewing_interval_hasNext(icPreEdit->context)) {
	chewing_interval_Get(icPreEdit->context, &it);
	if (it.from <= chiSymbolCursor && chiSymbolCursor <= it.to) {
	    ibus_text_append_attribute(iText,
				       IBUS_ATTR_TYPE_UNDERLINE,
				       IBUS_ATTR_UNDERLINE_DOUBLE,
				       it.from, it.to + 1);

	} else {
	    ibus_text_append_attribute(iText,
				       IBUS_ATTR_TYPE_UNDERLINE,
				       IBUS_ATTR_UNDERLINE_SINGLE,
				       it.from, it.to + 1);
	}

    }

    if (!mkdg_has_flag(capabilite, IBUS_CAP_SURROUNDING_TEXT)
	|| !mkdg_has_flag(capabilite, IBUS_CAP_AUXILIARY_TEXT)) {
	/* Cannot change color when if the client is not capable
	 * of showing surrounding text or auxiliary text
	 */
	return iText;
    }

    /* Show current cursor in red */
    ibus_text_append_attribute(iText, IBUS_ATTR_TYPE_BACKGROUND,
			       0x00ff0000, chiSymbolCursor,
			       chiSymbolCursor + 1);

    return iText;
}
void refresh_outgoing_text(IBusChewingEngine * self)
{
    gchar *outgoingStr =
	ibus_chewing_pre_edit_get_outgoing(self->icPreEdit);
    IBUS_CHEWING_LOG(INFO, "refresh_outgoing_text() outgoingStr=|%s|",
		     outgoingStr);

    if (self->outgoingText) {
	g_object_unref(self->outgoingText);
    }
    self->outgoingText =
	g_object_ref_sink(ibus_text_new_from_string(outgoingStr));
    IBUS_CHEWING_LOG(DEBUG, "refresh_outgoing_text() outgoingText=|%s|",
		     self->outgoingText->text);
}
guint ibus_chewing_lookup_table_update(IBusLookupTable * iTable,
				       IBusChewingProperties * iProperties,
				       ChewingContext * context)
{
    ibus_chewing_lookup_table_resize(iTable, iProperties, context);
    IBusText *iText = NULL;
    guint i;
    gint choicePerPage = chewing_cand_ChoicePerPage(context);
    gint totalChoice = chewing_cand_TotalChoice(context);
    gint currentPage = chewing_cand_CurrentPage(context);
    IBUS_CHEWING_LOG(INFO,
		     "***** ibus_chewing_lookup_table_update(): choicePerPage=%d, totalChoice=%d, currentPage=%d",
		     choicePerPage, totalChoice, currentPage);
    chewing_cand_Enumerate(context);
    for (i = 0; i < choicePerPage; i++) {
	if (chewing_cand_hasNext(context)) {
	    gchar *candidate = chewing_cand_String(context);
	    iText =
		g_object_ref_sink(ibus_text_new_from_string(candidate));
	    ibus_lookup_table_append_candidate(iTable, iText);
	    g_free(candidate);
	    g_object_unref(iText);
	} else {
	    break;
	}
    }
    return i;
}
/*===================================================
 * Mouse events
 */
void ibus_chewing_engine_candidate_clicked(IBusEngine *engine, guint index, guint button, guint state){
    IBUS_CHEWING_LOG(2,"***[I2] candidate_clicked(-, %u, %u, %u) ... proceed.", index, button, state);
    IBusChewingEngine *self=IBUS_CHEWING_ENGINE(engine);
    if (ibus_chewing_engine_is_password(self)) return;
    if (index >= chewing_get_candPerPage(self->context) || index <0) {
	IBUS_CHEWING_LOG(3,"[I3]  candidate_clicked() index out of ranged");
	return;
    }
    if (self->inputMode==CHEWING_INPUT_MODE_SELECTING){
	self->_priv->key_last=(guint) self->selKeys[index];
	ibus_chewing_engine_handle_Default(self, self->_priv->key_last, FALSE);
	self_update(self);
    } else {
	IBUS_CHEWING_LOG(3,"[I3] candidate_clicked() ... Wrong mode: %u", self->inputMode);
    }
}
void ibus_chewing_engine_handle_Default(IBusChewingEngine *self, guint keyval, gboolean shiftPressed){
    IBUS_CHEWING_LOG(2,"[I2] handle_Default(-,%u) plainZhuyin=%s inputMode=%d",
	    keyval,(self->chewingFlags & CHEWING_FLAG_PLAIN_ZHUYIN)? "TRUE": "FALSE",self->inputMode);
    ibus_chewing_engine_set_status_flag(self, ENGINE_STATUS_NEED_COMMIT);
#ifdef EASY_SYMBOL_INPUT_WORK_AROUND
    if (self->chewingFlags & CHEWING_FLAG_EASY_SYMBOL_INPUT){
	/* If shift is pressed, turn on the  easySymbolInput, turn off
	 * otherwise
	 */
	chewing_set_easySymbolInput(self->context,(shiftPressed)? 1:0);
    }
#endif
    if (self->chewingFlags & CHEWING_FLAG_FORCE_LOWERCASE_ENGLISH){
	if (isupper(keyval) && !shiftPressed){
	    keyval=tolower(keyval);
	}else if (islower(keyval) && shiftPressed){
	    keyval=toupper(keyval);
	}
    }
    chewing_handle_Default(self->context,keyval);
    if (self->chewingFlags & CHEWING_FLAG_PLAIN_ZHUYIN){
	if (self_is_selectKey(self,self->_priv->key_last) &&
		self->inputMode==CHEWING_INPUT_MODE_SELECTING){
	    chewing_handle_Enter(self->context);
	    self->inputMode= CHEWING_INPUT_MODE_SELECTION_DONE;
	}
    }
}
void ibus_chewing_engine_enable(IBusChewingEngine * self)
{
    IBUS_CHEWING_LOG(MSG, "* enable(): statusFlags=%x",
		     self->_priv->statusFlags);
    ibus_chewing_engine_use_setting(self);
    ibus_chewing_engine_set_status_flag(self, ENGINE_FLAG_ENABLED);
}
Exemplo n.º 9
0
void determine_locale()
{
#ifndef STRING_BUFFER_SIZE
#define STRING_BUFFER_SIZE 100
#endif
    gchar *localePtr = NULL;
    gchar localeStr[STRING_BUFFER_SIZE];
    int i;
    for (i = 0; locale_env_strings[i] != NULL; i++) {
	if (getenv(locale_env_strings[i])) {
	    localePtr = getenv(locale_env_strings[i]);
	    break;
	}
    }
    if (!localePtr) {
	localePtr = "en_US.utf8";
    }
    /* Use UTF8 as charset unconditionally */
    for (i = 0; localePtr[i] != '\0'; i++) {
	if (localePtr[i] == '.')
	    break;
	localeStr[i] = localePtr[i];
    }
    localeStr[i] = '\0';
    g_strlcat(localeStr, ".utf8", STRING_BUFFER_SIZE);
#undef STRING_BUFFER_SIZE
    setlocale(LC_ALL, localeStr);
    IBUS_CHEWING_LOG(INFO, "determine_locale %s", localeStr);
}
Exemplo n.º 10
0
void ibus_chewing_engine_focus_out(IBusChewingEngine * self)
{
    IBUS_CHEWING_LOG(MSG, "* focus_out(): statusFlags=%x",
		     self->_priv->statusFlags);
    ibus_chewing_engine_clear_status_flag(self,
					  ENGINE_FLAG_FOCUS_IN |
					  ENGINE_FLAG_PROPERTIES_REGISTERED);
    ibus_chewing_engine_hide_property_list(self);
    
    if(ibus_chewing_pre_edit_get_property_boolean(self->icPreEdit, "clean-buffer-focus-out")){
	/* Clean the buffer when focus out */
	ibus_chewing_pre_edit_clear(self->icPreEdit);
	refresh_pre_edit_text(self);
	refresh_aux_text(self);
    }

    IBUS_CHEWING_LOG(DEBUG, "focus_out(): return");
}
Exemplo n.º 11
0
void update_aux_text(IBusChewingEngine * self)
{
    IBUS_CHEWING_LOG(DEBUG, "update_aux_text()");
    if (!ibus_chewing_engine_has_capabilite(self, IBUS_CAP_AUXILIARY_TEXT)) {
	return;
    }
    refresh_aux_text(self);
    parent_update_auxiliary_text(IBUS_ENGINE(self), self->auxText, TRUE);
}
Exemplo n.º 12
0
/*============================================
 * Callback routines
 */
gboolean KBType_apply_callback(PropertyContext * ctx, gpointer userData)
{
    GValue *value = &(ctx->value);
    IBUS_CHEWING_LOG(DEBUG, "KBType_apply_callback(%s,%s)", ctx->spec->key,
		     mkdg_g_value_to_string(value));
    ChewingKbType kbType = kbType_id_get_index(g_value_get_string(value));
    IBusChewingPreEdit *icPreEdit = (IBusChewingPreEdit *) ctx->parent;
    chewing_set_KBType(icPreEdit->context, kbType);
    return TRUE;
}
Exemplo n.º 13
0
static void start_component(void)
{
    IBUS_CHEWING_LOG(INFO, "start_component");
    ibus_init();
    bus = ibus_bus_new();
    g_signal_connect(bus, "disconnected", G_CALLBACK(ibus_disconnected_cb),
		     NULL);

    factory = ibus_factory_new(ibus_bus_get_connection(bus));

    ibus_factory_add_engine(factory, "chewing", IBUS_TYPE_CHEWING_ENGINE);

    if (ibus) {
	ibus_bus_request_name(bus, QUOTE_ME(PROJECT_SCHEMA_ID), 0);
    } else {
	IBusComponent *component = NULL;
	if (xml) {
	    component = ibus_component_new_from_file(QUOTE_ME(DATA_DIR)
						     "/ibus/component/chewing.xml");
	} else {
	    component = ibus_component_new(QUOTE_ME(PROJECT_SCHEMA_ID),
					   _("Chewing component"),
					   QUOTE_ME(PRJ_VER), "GPLv2+",
					   _("Peng Huang, Ding-Yi Chen"),
					   "http://code.google.com/p/ibus",
					   QUOTE_ME(LIBEXEC_DIR)
					   "/ibus-engine-chewing --ibus",
					   QUOTE_ME(PROJECT_NAME));
	}
	IBusEngineDesc *engineDesc =
	    ibus_engine_desc_new_varargs("name", "chewing",
					 "longname", _("Chewing"),
					 "description",
					 _("Chinese chewing input method"),
					 "language", "zh_TW",
					 "license", "GPLv2+",
					 "author",
					 _("Peng Huang, Ding-Yi Chen"),
					 "icon",
					 QUOTE_ME(PRJ_DATA_DIR) "/icons/"
					 QUOTE_ME(PROJECT_NAME) ".png",
					 "layout", "us",
					 "setup",
					 QUOTE_ME(LIBEXEC_DIR)
					 "/ibus-setup-chewing",
					 "version", QUOTE_ME(PRJ_VER),
					 "textdomain",
					 QUOTE_ME(PROJECT_NAME),
					 NULL);
	ibus_component_add_engine(component, engineDesc);
	ibus_bus_register_component(bus, component);
    }
    ibus_main();
}
Exemplo n.º 14
0
void ibus_chewing_engine_focus_in(IBusChewingEngine * self)
{
    IBUS_CHEWING_LOG(MSG, "* focus_in(): statusFlags=%x",
		     self->_priv->statusFlags);
    ibus_chewing_engine_use_setting(self);
    ibus_chewing_engine_restore_mode(self);
    ibus_chewing_engine_refresh_property_list(self);
    /* Shouldn't have anything to commit when Focus-in */
    ibus_chewing_pre_edit_clear(self->icPreEdit);
    refresh_pre_edit_text(self);
    refresh_aux_text(self);
#ifdef UNIT_TEST
    refresh_outgoing_text(self);
#else
    commit_text(self);
#endif
    ibus_chewing_engine_set_status_flag(self, ENGINE_FLAG_FOCUS_IN);
    IBUS_CHEWING_LOG(INFO, "focus_in() statusFlags=%x: return",
		     self->_priv->statusFlags);
}
void ibus_chewing_engine_set_content_type(IBusEngine *engine, guint purpose, guint hints){
    IBUS_CHEWING_LOG(5,"[I5] set_content_type(%d, %d)", purpose, hints);

    Self *self=SELF(engine);
    if (purpose == IBUS_INPUT_PURPOSE_PASSWORD ||
	purpose == IBUS_INPUT_PURPOSE_PIN) {
	ibus_chewing_engine_set_status_flag(self, ENGINE_STATUS_IS_PASSWORD);
    } else {
	ibus_chewing_engine_clear_status_flag(self, ENGINE_STATUS_IS_PASSWORD);
    }
}
Exemplo n.º 16
0
gboolean selKeys_apply_callback(PropertyContext * ctx, gpointer userData)
{
    GValue *value = &(ctx->value);
    IBUS_CHEWING_LOG(DEBUG, "selKeys_apply_callback(%s,%s)",
		     ctx->spec->key, mkdg_g_value_to_string(value));
    IBusChewingPreEdit *icPreEdit = (IBusChewingPreEdit *) ctx->parent;
    ibus_chewing_lookup_table_resize(icPreEdit->iTable,
				     icPreEdit->iProperties,
				     icPreEdit->context);
    return TRUE;
}
Exemplo n.º 17
0
void parent_commit_text(IBusEngine * iEngine)
{
    IBusChewingEngine *self = IBUS_CHEWING_ENGINE(iEngine);

    IBUS_CHEWING_LOG(MSG, "* parent_commit_text(-): outgoingText=%s",
		     self->outgoingText->text);
#ifdef UNIT_TEST
    printf("* parent_commit_text(-, %s)\n", self->outgoingText->text);
#else
    ibus_engine_commit_text(iEngine, self->outgoingText);
#endif
}
Exemplo n.º 18
0
/**
 * ibus_chewing_engine_reset:
 * @self: IBusChewingEngine instance.
 *
 * Reset the outgoing and pre_edit buffer and cursor
 * chewing_reset will NOT called here, as it will chnage the KBType and input mode.
 */
void ibus_chewing_engine_reset(IBusChewingEngine * self)
{
    IBUS_CHEWING_LOG(MSG, "* reset");

    /* Always clean buffer */
    ibus_chewing_pre_edit_clear(self->icPreEdit);
#ifndef UNIT_TEST
    IBusEngine *engine = IBUS_ENGINE(self);
    ibus_engine_hide_auxiliary_text(engine);
    ibus_engine_hide_lookup_table(engine);
    ibus_engine_update_preedit_text(engine,
				    SELF_GET_CLASS(self)->emptyText, 0,
				    FALSE);
#endif
}
Exemplo n.º 19
0
void update_lookup_table(IBusChewingEngine * self)
{
    IBUS_CHEWING_LOG(DEBUG, "update_lookup_table() CurrentPage=%d",
		     chewing_cand_CurrentPage(self->icPreEdit->context));

    gboolean isShow =
	ibus_chewing_pre_edit_has_flag(self->icPreEdit, FLAG_TABLE_SHOW);

    if (isShow) {
#ifndef UNIT_TEST
	ibus_engine_update_lookup_table(IBUS_ENGINE(self),
					self->icPreEdit->iTable, isShow);
	ibus_engine_show_lookup_table(IBUS_ENGINE(self));
#endif
    } else {
#ifndef UNIT_TEST
	ibus_engine_update_lookup_table(IBUS_ENGINE(self),
					self->icPreEdit->iTable, isShow);
	ibus_engine_hide_lookup_table(IBUS_ENGINE(self));
#endif
    }
}
Exemplo n.º 20
0
void ibus_chewing_engine_disable(IBusChewingEngine * self)
{
    IBUS_CHEWING_LOG(MSG, "* disable(): statusFlags=%x",
		     self->_priv->statusFlags);
    ibus_chewing_engine_clear_status_flag(self, ENGINE_FLAG_ENABLED);
}
gboolean ibus_chewing_engine_process_key_event(IBusEngine *engine,
	guint keysym,  guint keycode, guint modifiers){
    gboolean result=TRUE;

    IBusChewingEngine *self=IBUS_CHEWING_ENGINE(engine);
    if (ibus_chewing_engine_is_password(self)) return FALSE;
    guint kSym=ibus_chewing_engine_keycode_to_keysym(self,keysym, keycode, modifiers);

    if (modifiers & IBUS_RELEASE_MASK){
	if (!keysym_KP_to_normal(kSym) && (kSym==IBUS_Shift_L || kSym==IBUS_Shift_R) && self->_priv->key_last==kSym){
	    /* When Chi->Eng with incomplete character */
	    if (chewing_get_ChiEngMode(self->context) && !chewing_zuin_Check(self->context)){
	        /* chewing_zuin_Check==0 means incomplete character */
	        /* Send a space to finish the character */
	        chewing_handle_Space(self->context);
	     }
             chewing_set_ChiEngMode(self->context, ! chewing_get_ChiEngMode(self->context));
	     self_refresh_property(self,"chewing_chieng_prop");
	     return self_update(self);
	}
	/* Skip release event */
	return TRUE;
    }

    IBUS_CHEWING_LOG(2,"***[I2] process_key_event(-, %x(%s), %x, %x) orig keysym=%x... proceed.",kSym, keyName_get(kSym), keycode, modifiers,keysym);
    guint state= modifiers & (IBUS_SHIFT_MASK | IBUS_CONTROL_MASK | IBUS_MOD1_MASK);
    self->_priv->key_last=kSym;
    if (state==0){
	guint kSym_tmp=keysym_KP_to_normal(kSym);
	if (kSym_tmp){
	    IBUS_CHEWING_LOG(3,"***[I3] process_key_event(): %x is from keypad.", kSym_tmp);
	    /* Is keypad key */
	    if ((self->chewingFlags & CHEWING_FLAG_NUMPAD_ALWAYS_NUMBER) && chewing_get_ChiEngMode(self->context)){
		chewing_set_ChiEngMode(self->context, 0);
		self_handle_Default(self,kSym_tmp,FALSE);
		chewing_set_ChiEngMode(self->context,CHINESE_MODE);
	    }else{
		/* Convert kp numbers to normal */
		self_handle_Default(self,kSym_tmp,FALSE);
	    }
	}else{
	    switch (kSym){
		case IBUS_Return:
		case IBUS_KP_Enter:
		    ibus_chewing_engine_set_status_flag(self,ENGINE_STATUS_NEED_COMMIT);
		    chewing_handle_Enter(self->context);
		    break;
		case IBUS_Escape:
		    if (self->inputMode==CHEWING_INPUT_MODE_BYPASS)
			return FALSE;
		    chewing_handle_Esc(self->context);
		    break;
		case IBUS_BackSpace:
		    if (self->inputMode==CHEWING_INPUT_MODE_BYPASS)
			return FALSE;
		    chewing_handle_Backspace(self->context);
		    break;
		case IBUS_Delete:
		case IBUS_KP_Delete:
		    if (self->inputMode==CHEWING_INPUT_MODE_BYPASS)
			return FALSE;
		    chewing_handle_Del(self->context);
		    break;
		case IBUS_space:
		case IBUS_KP_Space:
		    if (self->chewingFlags & CHEWING_FLAG_PLAIN_ZHUYIN) {
			if (chewing_cand_TotalChoice(self->context) == 0) {
			    chewing_handle_Space(self->context);
			}
		    } else {
			/**
			 * Fix for space in Temporary English mode.
			 */
			chewing_handle_Space(self->context);
			ibus_chewing_engine_set_status_flag(self,ENGINE_STATUS_NEED_COMMIT);
		    }
		    if (self->inputMode==CHEWING_INPUT_MODE_SELECTION_DONE ||
			    self->inputMode==CHEWING_INPUT_MODE_BYPASS ||
			    self->inputMode==CHEWING_INPUT_MODE_EDITING )
			ibus_chewing_engine_set_status_flag(self,ENGINE_STATUS_NEED_COMMIT);
		    break;
		case IBUS_Page_Up:
		case IBUS_KP_Page_Up:
		    if (self->inputMode==CHEWING_INPUT_MODE_BYPASS)
			return FALSE;
		    IBUS_ENGINE_GET_CLASS(engine)->page_up(engine);
		    break;
		case IBUS_Page_Down:
		case IBUS_KP_Page_Down:
		    if (self->inputMode==CHEWING_INPUT_MODE_BYPASS)
			return FALSE;
		    IBUS_ENGINE_GET_CLASS(engine)->page_down(engine);
		    break;
		case IBUS_Up:
		case IBUS_KP_Up:
		    if (self->inputMode==CHEWING_INPUT_MODE_BYPASS)
			return FALSE;
		    IBUS_ENGINE_GET_CLASS(engine)->cursor_up(engine);
		    break;
		case IBUS_Down:
		case IBUS_KP_Down:
		    if (self->inputMode==CHEWING_INPUT_MODE_BYPASS)
			return FALSE;
		    IBUS_ENGINE_GET_CLASS(engine)->cursor_down(engine);
		    break;
		case IBUS_Left:
		case IBUS_KP_Left:
		    if (self->inputMode==CHEWING_INPUT_MODE_BYPASS)
			return FALSE;
		    chewing_handle_Left(self->context);
		    break;
		case IBUS_Right:
		case IBUS_KP_Right:
		    if (self->inputMode==CHEWING_INPUT_MODE_BYPASS)
			return FALSE;
		    chewing_handle_Right(self->context);
		    break;
		case IBUS_Home:
		case IBUS_KP_Home:
		    if (self->inputMode==CHEWING_INPUT_MODE_BYPASS)
			return FALSE;
		    chewing_handle_Home(self->context);
		    break;
		case IBUS_End:
		case IBUS_KP_End:
		    if (self->inputMode==CHEWING_INPUT_MODE_BYPASS)
			return FALSE;
		    chewing_handle_End(self->context);
		    break;
		case IBUS_Tab:
		    if (self->inputMode==CHEWING_INPUT_MODE_BYPASS)
			return FALSE;
		    chewing_handle_Tab(self->context);
		    break;
		case IBUS_Caps_Lock:
		    /* When Chi->Eng with incomplete character */
		    if (chewing_get_ChiEngMode(self->context) && !chewing_zuin_Check(self->context)){
			/* chewing_zuin_Check==0 means incomplete character */
			/* Send a space to finish the character */
			chewing_handle_Space(self->context);
		    }
		    chewing_handle_Capslock(self->context);
		    self_refresh_property(self,"chewing_chieng_prop");
		    break;
		case IBUS_Shift_L:
		case IBUS_Shift_R:
		    /* Some QT application will sneak these through */
		    return FALSE;
		case IBUS_Alt_L:
		case IBUS_Alt_R:
		    /* Some QT application will sneak these through */
		    return FALSE;
		case IBUS_Control_L:
		case IBUS_Control_R:
		    /* Some QT application will sneak these through */
		    return FALSE;
		default:
		    self_handle_Default(self,kSym,FALSE);
		    break;
	    }
	}
    }else if (state==IBUS_SHIFT_MASK){
	switch(kSym){
	    case IBUS_Return:
	    case IBUS_KP_Enter:
		/* Same with Shift Enter and Shift KP_Enter */
		ibus_chewing_engine_set_status_flag(self,ENGINE_STATUS_NEED_COMMIT);
		chewing_handle_Enter(self->context);
		break;
	    case IBUS_Left:
		if (self->inputMode==CHEWING_INPUT_MODE_BYPASS)
		    return FALSE;
		chewing_handle_ShiftLeft(self->context);
		break;
	    case IBUS_Right:
		if (self->inputMode==CHEWING_INPUT_MODE_BYPASS)
		    return FALSE;
		chewing_handle_ShiftRight(self->context);
		break;
	    case IBUS_Up:
	    case IBUS_KP_Up:
	    case IBUS_Down:
	    case IBUS_KP_Down:
	    case IBUS_Page_Up:
	    case IBUS_KP_Page_Up:
	    case IBUS_Page_Down:
	    case IBUS_KP_Page_Down:
	    case IBUS_Home:
	    case IBUS_End:
		if (self->_priv->statusFlags & ENGINE_STATUS_NEED_COMMIT)
		    self_force_commit(self);
		return FALSE;
	    case IBUS_space:
	    case IBUS_KP_Space:
		chewing_handle_ShiftSpace(self->context);
		chewing_set_ShapeMode(self->context, !chewing_get_ShapeMode(self->context));
		self_refresh_property(self,"chewing_alnumSize_prop");
		break;
	    default:
		if (kSym>127 || kSym<0){
		    /* Special keys, must let it through */
		    return FALSE;
		}
		self_handle_Default(self,kSym,TRUE);
		break;
	}
    }else if (state==IBUS_CONTROL_MASK){
	if (kSym>=IBUS_0 && kSym<=IBUS_9){
	    chewing_handle_CtrlNum(self->context,kSym);
//	}else if (kSym==IBUS_v || kSym==IBUS_V){
//	    chewing_handle_Right(self->context);
	}else{
	    result=FALSE;
	}

    }else{
	result=FALSE;
    }
    if (!result){
	return FALSE;
    }
    return self_update(self);
}