static void fcitx_im_context_focus_out(ClutterIMContext *context) { FcitxLog(LOG_LEVEL, "fcitx_im_context_focus_out"); FcitxIMContext *fcitxcontext = FCITX_IM_CONTEXT(context); if (!fcitxcontext->has_focus) { return; } fcitxcontext->has_focus = false; if (IsFcitxIMClientValid(fcitxcontext->client)) { FcitxIMClientFocusOut(fcitxcontext->client); } if (fcitxcontext->preedit_string != NULL) g_free(fcitxcontext->preedit_string); fcitxcontext->preedit_string = NULL; fcitxcontext->cursor_pos = 0; g_signal_emit(fcitxcontext, _signal_preedit_changed_id, 0); g_signal_emit(fcitxcontext, _signal_preedit_end_id, 0); return; }
static void fcitx_im_context_reset(ClutterIMContext *context) { FcitxLog(LOG_LEVEL, "fcitx_im_context_reset"); FcitxIMContext *fcitxcontext = FCITX_IM_CONTEXT(context); if (IsFcitxIMClientValid(fcitxcontext->client)) { FcitxIMClientReset(fcitxcontext->client); } }
static void _set_cursor_location_internal(FcitxIMContext *fcitxcontext) { ClutterIMContext* context = CLUTTER_IM_CONTEXT(fcitxcontext); ClutterActor *stage = clutter_actor_get_stage (context->actor); Window current_window, root, parent, *childs; unsigned int nchild; XWindowAttributes winattr; Display *xdpy; float fx, fy; gint x, y; if (!stage) return; clutter_actor_get_transformed_position (context->actor, &fx, &fy); x = fx; y = fy; xdpy = clutter_x11_get_default_display (); current_window = clutter_x11_get_stage_window(CLUTTER_STAGE(stage)); if (!xdpy || !current_window) return; while(1) { XGetWindowAttributes (xdpy, current_window, &winattr); x += winattr.x; y += winattr.y; XQueryTree(xdpy, current_window, &root, &parent, &childs, &nchild); current_window = parent; if (root == parent) break; } if (fcitxcontext->area.x != x || fcitxcontext->area.y != y) { fcitxcontext->area.x = x; fcitxcontext->area.y = y; } if (context->actor == NULL || !IsFcitxIMClientValid(fcitxcontext->client)) { return; } ClutterIMRectangle area = fcitxcontext->area; if (area.x == -1 && area.y == -1 && area.width == 0 && area.height == 0) { area.y = 0; area.x = 0; } FcitxIMClientSetCursorLocation(fcitxcontext->client, area.x, area.y + area.height); return; }
void _fcitx_im_context_set_capacity(FcitxIMContext* fcitxcontext) { if (IsFcitxIMClientValid(fcitxcontext->client)) { FcitxCapacityFlags flags = CAPACITY_NONE; if (fcitxcontext->use_preedit) flags |= CAPACITY_PREEDIT; FcitxIMClientSetCapacity(fcitxcontext->client, flags); } }
void fcitx_im_context_hide(ClutterIMContext* context) { FcitxLog(LOG_LEVEL, "fcitx_im_context_focus_out"); FcitxIMContext *fcitxcontext = FCITX_IM_CONTEXT(context); if (IsFcitxIMClientValid(fcitxcontext->client) && IsFcitxIMClientEnabled(fcitxcontext->client)) { FcitxIMClientCloseIC(fcitxcontext->client); } if (fcitxcontext->has_focus) { clutter_im_context_focus_out(context); } }
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_get_preedit_string(ClutterIMContext *context, gchar **str, PangoAttrList **attrs, gint *cursor_pos) { FcitxLog(LOG_LEVEL, "fcitx_im_context_get_preedit_string"); FcitxIMContext *fcitxcontext = FCITX_IM_CONTEXT(context); if (IsFcitxIMClientValid(fcitxcontext->client) && IsFcitxIMClientEnabled(fcitxcontext->client)) { if (str) { if (fcitxcontext->preedit_string) *str = strdup(fcitxcontext->preedit_string); else *str = strdup(""); } if (attrs) { *attrs = pango_attr_list_new(); if (str) { PangoAttribute *pango_attr; pango_attr = pango_attr_underline_new(PANGO_UNDERLINE_SINGLE); pango_attr->start_index = 0; pango_attr->end_index = strlen(*str); pango_attr_list_insert(*attrs, pango_attr); } } if (cursor_pos) *cursor_pos = fcitxcontext->cursor_pos; } else { if (str) { *str = g_strdup(""); } if (attrs) { *attrs = pango_attr_list_new(); } if (cursor_pos) *cursor_pos = 0; } return ; }
static void fcitx_im_context_set_cursor_location(ClutterIMContext *context, ClutterIMRectangle *area) { FcitxLog(LOG_LEVEL, "fcitx_im_context_set_cursor_location %d %d %d %d", area->x, area->y, area->height, area->width); FcitxIMContext *fcitxcontext = FCITX_IM_CONTEXT(context); if (fcitxcontext->area.x == area->x && fcitxcontext->area.y == area->y && fcitxcontext->area.width == area->width && fcitxcontext->area.height == area->height) { return; } fcitxcontext->area = *area; if (IsFcitxIMClientValid(fcitxcontext->client)) { _set_cursor_location_internal(fcitxcontext); } return; }
static gboolean fcitx_im_context_filter_keypress(ClutterIMContext *context, ClutterKeyEvent *event) { FcitxLog(LOG_LEVEL, "fcitx_im_context_filter_keypress"); FcitxIMContext *fcitxcontext = FCITX_IM_CONTEXT(context); if (G_UNLIKELY(event->modifier_state & FcitxKeyState_HandledMask)) return TRUE; if (G_UNLIKELY(event->modifier_state & FcitxKeyState_IgnoredMask)) return FALSE; if (IsFcitxIMClientValid(fcitxcontext->client) && fcitxcontext->has_focus) { if (!IsFcitxIMClientEnabled(fcitxcontext->client)) { if (!FcitxIsHotKey(event->keyval, event->modifier_state, FcitxIMClientGetTriggerKey(fcitxcontext->client))) return FALSE; } fcitxcontext->time = event->time; int ret = FcitxIMClientProcessKeySync(fcitxcontext->client, event->keyval, event->hardware_keycode, event->modifier_state, (event->type == CLUTTER_KEY_PRESS) ? (FCITX_PRESS_KEY) : (FCITX_RELEASE_KEY), event->time); if (ret <= 0) { event->modifier_state |= FcitxKeyState_IgnoredMask; return FALSE; } else { event->modifier_state |= FcitxKeyState_HandledMask; return TRUE; } } else { return FALSE; } return FALSE; }
void _fcitx_fbterm_connect_cb(FcitxIMClient* client, void* user_data) { if (IsFcitxIMClientValid(client)) { FcitxIMClientConnectSignal(client, G_CALLBACK(_fcitx_fbterm_enable_im_cb), G_CALLBACK(_fcitx_fbterm_close_im_cb), G_CALLBACK(_fcitx_fbterm_commit_string_cb), G_CALLBACK(_fcitx_fbterm_forward_key_cb), G_CALLBACK(_fcitx_fbterm_update_client_side_ui_cb), user_data, NULL); CapacityFlags flags = CAPACITY_CLIENT_SIDE_UI; FcitxIMClientSetCapacity(client, flags); if (active) { FcitxIMClientFocusIn(client); FcitxIMClientEnableIC(client); } } }
static void fcitx_im_context_focus_in(ClutterIMContext *context) { FcitxLog(LOG_LEVEL, "fcitx_im_context_focus_in"); FcitxIMContext *fcitxcontext = FCITX_IM_CONTEXT(context); if (fcitxcontext->has_focus) return; fcitxcontext->has_focus = true; if (IsFcitxIMClientValid(fcitxcontext->client)) { FcitxIMClientFocusIn(fcitxcontext->client); } /* 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); return; }