This patch adds supports for XIMStringConversionCallback and
XIMValuesList.

For detail, see: https://bugs.freedesktop.org/show_bug.cgi?id=2832
From 5e976da29a1404725b70a31997004b5e96196de7 Mon Sep 17 00:00:00 2001
From: Choe Hwanjin <choe.hwan...@gmail.com>
Date: Sat, 15 Oct 2011 15:09:41 +0900
Subject: [PATCH] XIM: Implement XIMStringConversionCallback

This patch adds supports for XIMStringConversionCallback and
XIMValuesList.

Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=2832

Signed-off-by: Choe Hwanjin <choe.hwan...@gmail.com>
---
 modules/im/ximcp/imCallbk.c |   92 ++++++++++++++++++++++++++++++++----------
 modules/im/ximcp/imRmAttr.c |   53 +++++++++++++++++++++++++
 src/xlibi18n/XimProto.h     |    3 +
 3 files changed, 126 insertions(+), 22 deletions(-)

diff --git a/modules/im/ximcp/imCallbk.c b/modules/im/ximcp/imCallbk.c
index 6275bbf..ef3d0f2 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,73 @@ _XimStrConversionCallback(Xim im,
     {
 	CARD8	*buf;
 	INT16	 buf_len;
-	int	 p, length_in_bytes, i;
 
-	/* 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);
+	int	 p, length, i;
+	int      compound_text_length;
+	char*    compound_text = NULL;
+
+	if (cbrec.text == NULL) {
+	    length = 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]);
+	    }
+
+	    compound_text = (char*)tp.value;
+	    compound_text_length = strlen(compound_text);
 	}
+
+	buf_len = XIM_HEADER_SIZE +
+		  sz_CARD16 +
+		  sz_CARD16 +
+		  sz_CARD16 + compound_text_length +
+		  XIM_PAD(sz_CARD16 + compound_text_length) +
+		  sz_CARD16 + sz_CARD16 + 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);
-	p += XIM_PAD(2);
-	for (i = 0; i < (int)cbrec.text->length; i++) {
-	    *(CARD32*)&buf[p] = (CARD32)cbrec.text->feedback[i];
+	*(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;
+	p += XIM_PAD(sz_CARD16 + compound_text_length);
+	*(CARD16*)&buf[p] = (CARD16)(sz_CARD32 * length); p += sz_CARD16;
+	p += XIM_PAD(sz_CARD16);
+	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 +402,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;
diff --git a/modules/im/ximcp/imRmAttr.c b/modules/im/ximcp/imRmAttr.c
index c047715..99e7f15 100644
--- a/modules/im/ximcp/imRmAttr.c
+++ b/modules/im/ximcp/imRmAttr.c
@@ -393,6 +393,59 @@ _XimAttributeToValue(
 	    break;
 	}
 
+    case XimType_XIMValuesList:
+	{
+	    unsigned int     i;
+	    unsigned int     alloc_len;
+	    unsigned int     n;
+	    unsigned int     len;
+	    unsigned int     values_len;
+	    XIMValuesList   *values_list;
+	    char           **values;
+	    char            *names;
+	    char            *p;
+	    unsigned char   *tmp;
+
+	    if (value == NULL)
+		return False;
+
+	    n = data[0];
+	    data++;
+
+	    tmp = (unsigned char*)data;
+	    values_len = 0;
+	    for (i = 0; i < n; i++) {
+		len = *((CARD16*)tmp);            /* text length */
+		values_len += len + 1;
+		tmp += sizeof(CARD16) + len + XIM_PAD(sizeof(CARD16) + len);
+	    }
+
+	    alloc_len = sizeof(XIMValuesList) + sizeof(char **) * n + values_len;
+	    p = (char *)Xmalloc(alloc_len);
+	    if (p == NULL)
+		return False;
+
+	    values_list = (XIMValuesList *)p;
+	    values = (char **)(p + sizeof(XIMValuesList));
+	    names = (char*)((char*)values + sizeof(char **) * n);
+
+	    values_list->count_values = n;
+	    values_list->supported_values = values;
+
+	    tmp = (unsigned char*)data;
+	    for (i = 0; i < n; i++) {
+		len = *((CARD16*)tmp);                 /* text length */
+		(void)memcpy(names, (char *)&tmp[sizeof(CARD16)], len);
+		names[len] = '\0';
+		values[i] = names;
+		names += len + 1;
+		tmp += sizeof(CARD16) + len + XIM_PAD(sizeof(CARD16) + len);
+	    }
+
+	    *((XIMValuesList **)value) = values_list;
+	    break;
+	}
+
     default:
 	return False;
     }
diff --git a/src/xlibi18n/XimProto.h b/src/xlibi18n/XimProto.h
index 6b0096d..00fd84e 100644
--- a/src/xlibi18n/XimProto.h
+++ b/src/xlibi18n/XimProto.h
@@ -163,6 +163,9 @@ PERFORMANCE OF THIS SOFTWARE.
 #define XimType_XIMHotKeyTriggers	15
 #define XimType_XIMHotKeyState		16
 #define XimType_XIMStringConversion	17
+#define XimType_XIMPreeditState		18
+#define XimType_XIMResetState		19
+#define XimType_XIMValuesList		20
 #define	XimType_NEST			0x7fff
 
 /*
-- 
1.7.6.3

_______________________________________________
xorg-devel@lists.x.org: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel

Reply via email to