static void _xim_preedit_callback_done (XIMS xims, const X11IC *x11ic) { IMPreeditCBStruct pcb; pcb.major_code = XIM_PREEDIT_DONE; pcb.minor_code = 0; pcb.connect_id = x11ic->connect_id; pcb.icid = x11ic->icid; pcb.todo.return_value = 0; IMCallCallback (xims, (XPointer) & pcb); }
void* XimConsumeQueue(void* arg, FcitxModuleFunctionArg args) { FcitxXimFrontend* xim = arg; if (!xim->ims) return NULL; XimQueue* item; size_t len = utarray_len(xim->queue); for (item = (XimQueue*) utarray_front(xim->queue); item != NULL; item = (XimQueue*) utarray_next(xim->queue, item)) { switch(item->type) { case XCT_FORWARD: { IMForwardEvent(xim->ims, item->ptr); } break; case XCT_CALLCALLBACK: { IMCallCallback(xim->ims, item->ptr); IMPreeditCBStruct* pcb = (IMPreeditCBStruct*) item->ptr; if (pcb->major_code == XIM_PREEDIT_DRAW) { XFree(pcb->todo.draw.text->string.multi_byte); free(pcb->todo.draw.text); } } break; case XCT_COMMIT: { IMCommitString(xim->ims, item->ptr); IMCommitStruct* cms = (IMCommitStruct*) item->ptr; XFree(cms->commit_string); } break; case XCT_PREEDIT_START: IMPreeditStart(xim->ims, item->ptr); break; case XCT_PREEDIT_END: IMPreeditEnd(xim->ims, item->ptr); break; } free(item->ptr); } utarray_clear(xim->queue); if (len) FcitxInstanceSetRecheckEvent(xim->owner); return NULL; }
static void _xim_preedit_callback_draw (XIMS xims, X11IC *x11ic, const gchar *preedit_string, IBusAttrList *attr_list) { IMPreeditCBStruct pcb; XIMText text; XTextProperty tp; static XIMFeedback *feedback; static gint feedback_len = 0; guint j, i, len; if (preedit_string == NULL) return; len = g_utf8_strlen (preedit_string, -1); if (len + 1 > feedback_len) { feedback_len = (len + 1 + 63) & ~63; if (feedback) { feedback = g_renew (XIMFeedback, feedback, feedback_len); } else { feedback = g_new (XIMFeedback, feedback_len); } } for (i = 0; i < len; i++) { feedback[i] = 0; } if (attr_list != NULL) { for (i = 0;; i++) { XIMFeedback attr = 0; IBusAttribute *ibus_attr = ibus_attr_list_get (attr_list, i); if (ibus_attr == NULL) { break; } switch (ibus_attr->type) { case IBUS_ATTR_TYPE_UNDERLINE: if (ibus_attr->value == IBUS_ATTR_UNDERLINE_SINGLE) { attr = XIMUnderline; } break; case IBUS_ATTR_TYPE_BACKGROUND: { if (ibus_attr->value != 0xffffff) { attr = XIMReverse; } break; } default: continue; } for (j = ibus_attr->start_index; j < ibus_attr->end_index; j++) { feedback[j] |= attr; } } } for (i = 0; i < len; i++) { if (feedback[i] == 0) { feedback[i] = XIMUnderline; } } feedback[len] = 0; pcb.major_code = XIM_PREEDIT_DRAW; pcb.connect_id = x11ic->connect_id; pcb.icid = x11ic->icid; pcb.todo.draw.caret = len; pcb.todo.draw.chg_first = 0; pcb.todo.draw.chg_length = x11ic->onspot_preedit_length; pcb.todo.draw.text = &text; text.feedback = feedback; if (len > 0) { Xutf8TextListToTextProperty (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), (char **)&preedit_string, 1, XCompoundTextStyle, &tp); text.encoding_is_wchar = 0; text.length = strlen ((char*)tp.value); text.string.multi_byte = (char*)tp.value; IMCallCallback (xims, (XPointer) & pcb); XFree (tp.value); } else { text.encoding_is_wchar = 0; text.length = 0; text.string.multi_byte = ""; IMCallCallback (xims, (XPointer) & pcb); len = 0; } x11ic->onspot_preedit_length = len; }