diff --git a/modules/im/ximcp/imCallbk.c b/modules/im/ximcp/imCallbk.c index 867746c..d3d4941 100644 --- a/modules/im/ximcp/imCallbk.c +++ b/modules/im/ximcp/imCallbk.c @@ -296,7 +296,7 @@ _XimStrConversionCallback(Xim im, /* invoke the callback */ if (cb && cb->callback) { - int p = XIM_HEADER_SIZE; + int p = 0; cbrec.position = (XIMStringConversionPosition) *(CARD32*)&proto[p]; p += sz_CARD32; cbrec.direction = (XIMCaretDirection) @@ -305,6 +305,7 @@ _XimStrConversionCallback(Xim im, *(CARD32*)&proto[p]; p += sz_CARD32; cbrec.factor = (unsigned short) *(CARD32*)&proto[p]; + cbrec.text = NULL; (*cb->callback)((XIC)ic, cb->client_data, (XPointer)&cbrec); } @@ -325,34 +326,71 @@ _XimStrConversionCallback(Xim im, { CARD8 *buf; INT16 buf_len; - int p, length_in_bytes, i; + int p, length, length_in_bytes, i; + int compound_text_length; + char* compound_text = NULL; + + if (cbrec.text == NULL) { + length = 0; + length_in_bytes = 0; + compound_text_length = 0; + } else { + XTextProperty tp; + + /* convert text encoding to COMPOUND_TEXT */ + length = cbrec.text->length; + if (cbrec.text->encoding_is_wchar) { + size_t size; + wchar_t *list[1]; + /* text may not be null-terminated */ + size = length * sizeof(wchar_t); + list[0] = (wchar_t*)Xmalloc(size + sizeof(wchar_t)); + memcpy(list[0], cbrec.text->string.wcs, size); + list[0][length] = L'\0'; + XwcTextListToTextProperty(im->core.display, list, 1, + XCompoundTextStyle, &tp); + Xfree(list[0]); + } else { + size_t size; + char *list[1]; + /* text may not be null-terminated */ + size = length; + list[0] = (char*)Xmalloc(size + 1); + memcpy(list[0], cbrec.text->string.mbs, size); + list[0][length] = '\0'; + XmbTextListToTextProperty(im->core.display, list, 1, + XCompoundTextStyle, &tp); + Xfree(list[0]); + } - /* Assumption: - * `cbrec.text->length' means the string length in characters - */ - { - length_in_bytes = (cbrec.text->encoding_is_wchar)? - sizeof(wchar_t) * cbrec.text->length: /* wchar */ - strlen(cbrec.text->string.mbs); /* mb */ - buf_len = XIM_HEADER_SIZE + - sz_CARD16 + - 2 + length_in_bytes + - XIM_PAD(2 + length_in_bytes) + - 2 + 2 + sz_CARD32 * cbrec.text->length; - buf = (CARD8*)Xmalloc(buf_len); + compound_text = tp.value; + compound_text_length = strlen(compound_text); } + + buf_len = XIM_HEADER_SIZE + + sz_CARD16 + + sz_CARD16 + compound_text_length + + XIM_PAD(sz_CARD16 + compound_text_length) + + 2 + 2 + sz_CARD32 * length; + buf = (CARD8*)Xmalloc(buf_len); _XimSetHeader((XPointer)buf, XIM_STR_CONVERSION_REPLY, 0, &buf_len); buf_len -= XIM_HEADER_SIZE; /* added by _XimSetHeader (HACK) */ p = XIM_HEADER_SIZE; *(CARD16*)&buf[p] = (CARD16)im->private.proto.imid; p += sz_CARD16; *(CARD16*)&buf[p] = (CARD16)ic->private.proto.icid; p += sz_CARD16; - *(CARD16*)&buf[p] = (CARD16)cbrec.text->length; p += sz_CARD16; - memcpy(&buf[p],&cbrec.text->string.mbs,length_in_bytes); - p += length_in_bytes; - *(CARD16*)&buf[p] = (CARD16)(sz_CARD32*cbrec.text->length); + *(CARD16*)&buf[p] = (CARD16)compound_text_length; p += sz_CARD16; + if (compound_text != NULL) { + memcpy(&buf[p], compound_text, compound_text_length); + } + p += compound_text_length; + *(CARD16*)&buf[p] = (CARD16)(sz_CARD32 * length); p += XIM_PAD(2); - for (i = 0; i < (int)cbrec.text->length; i++) { - *(CARD32*)&buf[p] = (CARD32)cbrec.text->feedback[i]; + for (i = 0; i < length; i++) { + if (cbrec.text->feedback == NULL) { + *(CARD32*)&buf[p] = 0; + } else { + *(CARD32*)&buf[p] = (CARD32)cbrec.text->feedback[i]; + } p += sz_CARD32; } @@ -362,6 +400,14 @@ _XimStrConversionCallback(Xim im, _XimFlushData(im); Xfree(buf); + if (cbrec.text != NULL) { + if (cbrec.text->encoding_is_wchar) + free(cbrec.text->string.wcs); + else + free(cbrec.text->string.mbs); + free(cbrec.text->feedback); + free(cbrec.text); + } } return XimCbSuccess;