static void fcitx_im_context_set_use_preedit(ClutterIMContext *context, gboolean use_preedit) { FcitxLog(LOG_LEVEL, "fcitx_im_context_set_use_preedit"); FcitxIMContext *fcitxcontext = FCITX_IM_CONTEXT(context); fcitxcontext->use_preedit = use_preedit; _fcitx_im_context_set_capacity(fcitxcontext); }
static void fcitx_im_context_set_use_preedit(GtkIMContext *context, gboolean use_preedit) { FcitxLog(LOG_LEVEL, "fcitx_im_context_set_use_preedit"); FcitxIMContext *fcitxcontext = FCITX_IM_CONTEXT(context); fcitxcontext->use_preedit = use_preedit; _fcitx_im_context_set_capacity(fcitxcontext, FALSE); gtk_im_context_set_use_preedit(fcitxcontext->slave, use_preedit); }
static void _request_surrounding_text (FcitxIMContext *context) { if (context && fcitx_client_is_valid(context->client)) { gboolean return_value; FcitxLog(LOG_LEVEL, "requesting surrounding text"); g_signal_emit (context, _signal_retrieve_surrounding_id, 0, &return_value); if (return_value) { context->capacity |= CAPACITY_SURROUNDING_TEXT; _fcitx_im_context_set_capacity (context, FALSE); } else { context->capacity &= ~CAPACITY_SURROUNDING_TEXT; _fcitx_im_context_set_capacity (context, FALSE); } } }
void _fcitx_im_context_connect_cb(FcitxIMClient* client, void* user_data) { FcitxIMContext* context = FCITX_IM_CONTEXT(user_data); if (IsFcitxIMClientValid(client)) { FcitxIMClientConnectSignal(client, G_CALLBACK(_fcitx_im_context_enable_im_cb), G_CALLBACK(_fcitx_im_context_close_im_cb), G_CALLBACK(_fcitx_im_context_commit_string_cb), G_CALLBACK(_fcitx_im_context_forward_key_cb), G_CALLBACK(_fcitx_im_context_update_preedit_cb), context, NULL); _fcitx_im_context_set_capacity(context); } }
static void fcitx_im_context_focus_in(GtkIMContext *context) { FcitxLog(LOG_LEVEL, "fcitx_im_context_focus_in"); FcitxIMContext *fcitxcontext = FCITX_IM_CONTEXT(context); if (fcitxcontext->has_focus) return; _fcitx_im_context_set_capacity(fcitxcontext, FALSE); fcitxcontext->has_focus = true; if (_focus_im_context != NULL) { g_assert (_focus_im_context != context); gtk_im_context_focus_out (_focus_im_context); g_assert (_focus_im_context == NULL); } if (fcitx_client_is_valid(fcitxcontext->client)) { fcitx_client_focus_in(fcitxcontext->client); } gtk_im_context_focus_in(fcitxcontext->slave); /* set_cursor_location_internal() will get origin from X server, * it blocks UI. So delay it to idle callback. */ g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, (GSourceFunc) _set_cursor_location_internal, g_object_ref(fcitxcontext), (GDestroyNotify) g_object_unref); _request_surrounding_text (fcitxcontext); g_object_add_weak_pointer ((GObject *) context, (gpointer *) &_focus_im_context); _focus_im_context = context; return; }
/* Copy from gdk */ static GdkEventKey * _create_gdk_event(FcitxIMContext *fcitxcontext, guint keyval, guint state, FcitxKeyEventType type ) { gunichar c = 0; gchar buf[8]; GdkEventKey *event = (GdkEventKey *)gdk_event_new((type == FCITX_RELEASE_KEY) ? GDK_KEY_RELEASE : GDK_KEY_PRESS); if (fcitxcontext && fcitxcontext->client_window) event->window = g_object_ref(fcitxcontext->client_window); /* The time is copied the latest value from the previous * GdkKeyEvent in filter_keypress(). * * We understand the best way would be to pass the all time value * to Fcitx functions process_key_event() and Fcitx DBus functions * ProcessKeyEvent() in IM clients and IM engines so that the * _create_gdk_event() could get the correct time values. * However it would causes to change many functions and the time value * would not provide the useful meanings for each Fcitx engines but just * pass the original value to ForwardKeyEvent(). * We use the saved value at the moment. * * Another idea might be to have the time implementation in X servers * but some Xorg uses clock_gettime() and others use gettimeofday() * and the values would be different in each implementation and * locale/remote X server. So probably that idea would not work. */ if (fcitxcontext) { event->time = fcitxcontext->time; } else { event->time = GDK_CURRENT_TIME; } event->send_event = FALSE; event->state = state; event->keyval = keyval; event->string = NULL; event->length = 0; event->hardware_keycode = 0; if (event->window) { #ifndef NEW_GDK_WINDOW_GET_DISPLAY GdkDisplay *display = gdk_display_get_default(); #else GdkDisplay *display = gdk_window_get_display(event->window); #endif GdkKeymap *keymap = gdk_keymap_get_for_display(display); GdkKeymapKey *keys; gint n_keys = 0; if (gdk_keymap_get_entries_for_keyval(keymap, keyval, &keys, &n_keys)) { if (n_keys) event->hardware_keycode = keys[0].keycode; g_free(keys); } } event->group = 0; event->is_modifier = _key_is_modifier(keyval); #ifdef DEPRECATED_GDK_KEYSYMS if (keyval != GDK_VoidSymbol) #else if (keyval != GDK_KEY_VoidSymbol) #endif c = gdk_keyval_to_unicode(keyval); if (c) { gsize bytes_written; gint len; /* Apply the control key - Taken from Xlib */ if (event->state & GDK_CONTROL_MASK) { if ((c >= '@' && c < '\177') || c == ' ') c &= 0x1F; else if (c == '2') { event->string = g_memdup("\0\0", 2); event->length = 1; buf[0] = '\0'; goto out; } else if (c >= '3' && c <= '7') c -= ('3' - '\033'); else if (c == '8') c = '\177'; else if (c == '/') c = '_' & 0x1F; } len = g_unichar_to_utf8(c, buf); buf[len] = '\0'; event->string = g_locale_from_utf8(buf, len, NULL, &bytes_written, NULL); if (event->string) event->length = bytes_written; #ifdef DEPRECATED_GDK_KEYSYMS } else if (keyval == GDK_Escape) { #else } else if (keyval == GDK_KEY_Escape) { #endif event->length = 1; event->string = g_strdup("\033"); } #ifdef DEPRECATED_GDK_KEYSYMS else if (keyval == GDK_Return || keyval == GDK_KP_Enter) { #else else if (keyval == GDK_KEY_Return || keyval == GDK_KEY_KP_Enter) { #endif event->length = 1; event->string = g_strdup("\r"); } if (!event->string) { event->length = 0; event->string = g_strdup(""); } out: return event; } static gboolean _key_is_modifier(guint keyval) { /* See gdkkeys-x11.c:_gdk_keymap_key_is_modifier() for how this * really should be implemented */ switch (keyval) { #ifdef DEPRECATED_GDK_KEYSYMS case GDK_Shift_L: case GDK_Shift_R: case GDK_Control_L: case GDK_Control_R: case GDK_Caps_Lock: case GDK_Shift_Lock: case GDK_Meta_L: case GDK_Meta_R: case GDK_Alt_L: case GDK_Alt_R: case GDK_Super_L: case GDK_Super_R: case GDK_Hyper_L: case GDK_Hyper_R: case GDK_ISO_Lock: case GDK_ISO_Level2_Latch: case GDK_ISO_Level3_Shift: case GDK_ISO_Level3_Latch: case GDK_ISO_Level3_Lock: case GDK_ISO_Group_Shift: case GDK_ISO_Group_Latch: case GDK_ISO_Group_Lock: return TRUE; #else case GDK_KEY_Shift_L: case GDK_KEY_Shift_R: case GDK_KEY_Control_L: case GDK_KEY_Control_R: case GDK_KEY_Caps_Lock: case GDK_KEY_Shift_Lock: case GDK_KEY_Meta_L: case GDK_KEY_Meta_R: case GDK_KEY_Alt_L: case GDK_KEY_Alt_R: case GDK_KEY_Super_L: case GDK_KEY_Super_R: case GDK_KEY_Hyper_L: case GDK_KEY_Hyper_R: case GDK_KEY_ISO_Lock: case GDK_KEY_ISO_Level2_Latch: case GDK_KEY_ISO_Level3_Shift: case GDK_KEY_ISO_Level3_Latch: case GDK_KEY_ISO_Level3_Lock: case GDK_KEY_ISO_Level5_Shift: case GDK_KEY_ISO_Level5_Latch: case GDK_KEY_ISO_Level5_Lock: case GDK_KEY_ISO_Group_Shift: case GDK_KEY_ISO_Group_Latch: case GDK_KEY_ISO_Group_Lock: return TRUE; #endif default: return FALSE; } } void _fcitx_im_context_connect_cb(FcitxClient* im, void* user_data) { FcitxIMContext* context = FCITX_IM_CONTEXT(user_data); _fcitx_im_context_set_capacity(context, TRUE); /* set_cursor_location_internal() will get origin from X server, * it blocks UI. So delay it to idle callback. */ g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, (GSourceFunc) _set_cursor_location_internal, g_object_ref(context), (GDestroyNotify) g_object_unref); }