Compound Text

セレクションや XIM など X アプリケーション間での文字列の通信は
コンパウンドテキスト(compound text)というエンコーディングで行われる。


変換例:
euc-jp:あいうabcあいう
CompoundText:0x1b 0x24 0x28 0x42 0x24 0x22 0x24 0x24 0x24 0x26 0x1b 0x28 0x42 0x61 0x62 0x63 0x1b 0x24 0x28 0x42 0x24 0x22 0x24 0x24 0x24 0x26
0x1b が入っていることに注意。


Xlib の関数 XmbTextListToTextProperty を使って Compound Text に変換する。
http://peppermint.jp/diary/reader.php?year=2002&month=03#2002-03-16

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>
#include <X11/Xatom.h>
#include <X11/keysym.h>
#include <X11/Xlocale.h>

Display			*pDisplay;
Window			iWindow;

int
main (int argc, char *argv[])
{
	XEvent		event;
	XSelectionEvent	eventSelection;
	int			iReturn;

	// ロケールを環境変数の値に設定する
	if (!setlocale(LC_ALL, ""))
	{
		printf ("setlocale() error\n");
		exit (1);
	}
	if (XSupportsLocale() == False)
	{
		printf ("Locale not supported by X\n");
		exit (1);
	}
	
	/* Open the X display */
	pDisplay = XOpenDisplay (NULL);
	if (pDisplay == NULL)
    {
		printf ("Could not open display\n");
		exit (1);
    }
	{
		char* from[1];
		char** to;
		int n;
		int i,j;
		int len;
		XTextProperty prop;
		// eucで「あいうabcあいう」
		char euc[] = {
			0xa4, 0xa2, 0xa4, 0xa4, 0xa4, 0xa6,
			0x61, 0x62, 0x63, 
			0xa4, 0xa2, 0xa4, 0xa4, 0xa4, 0xa6,
			0x00
		};
		// sjisで「あいうabcあいう」
		char sjis[] = {
			0x82, 0xa0, 0x82, 0xa2, 0x82, 0xa4,
			0x61, 0x62, 0x63, 
			0x82, 0xa0, 0x82, 0xa2, 0x82, 0xa4,
			0x00
		};
		
#if 0
		from[0] = sjis;
#else
		from[0] = euc;
#endif
		
		prop.value = NULL;
		
		printf("from:");
		len = strlen(from[0]);
		for(i = 0; i < len; ++i){
			printf("0x%02x ", (unsigned char)from[0][i]);
		}
		printf("\n");
		printf("%s\n", from[0]);
		
		// Compound Text に変換
		iReturn = XmbTextListToTextProperty (pDisplay,
											 from,
											 1,
											 XCompoundTextStyle,
											 &prop);

		if (iReturn == XNoMemory || iReturn == XLocaleNotSupported || iReturn == XConverterNotFound)
		{
			printf ("XmbTextListToTextProperty failed: %d\n",
					iReturn);
			exit(0);
		}else{
			printf ("XmbTextListToTextProperty: %d\n",
					iReturn);
		}
		
		printf ("AtomName:%s\n", XGetAtomName(pDisplay, prop.encoding));
		
		printf("CompoundText:");
		for(i = 0; i < prop.nitems; ++i){
			printf("0x%02x ", (unsigned char)prop.value[i]);
		}
		printf("\n");

		// 現在のロケールのエンコーディングに変換
		iReturn = XmbTextPropertyToTextList(pDisplay,
											&prop,
											&to,
											&n);

		if (iReturn == XNoMemory || iReturn == XLocaleNotSupported || iReturn == XConverterNotFound)
		{
			printf ("XmbTextPropertyToTextList failed: %d\n",
					iReturn);
			exit(0);
		}else{
			printf ("XmbTextPropertyToTextList: %d\n",
					iReturn);
		}
		printf("%d\n", n);
		printf("to:");
		for(i = 0; i < n; ++i){
			len = strlen(to[i]);
			for(j = 0; j < len; ++j){
				printf("0x%02x ", (unsigned char)to[i][j]);
			}
			printf("\n");
		}
		printf("%s\n", to[0]);
	}
	return 0;
}

gdk_utf8_to_compound_text を使って compound text に変換する。

#include <gdk/gdk.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[])
{
	int i;

	gtk_init(&argc, &argv);
	gchar* str = "This is UTF-8 テキスト";
	GdkAtom atom;
	gint format;
	guchar* ctext;
	gint length;

	gdk_utf8_to_compound_text (str, &atom, &format, &ctext, &length);

	printf("length=%d\n", length);
	for (i=0; i<length; i++)
		printf("%02x ", ctext[i]);

	return 0;
}


uim-ximのutf-8
http://anthy.sourceforge.jp/cgi-bin/hikija/hiki.cgi?uim-xim%A4%CEutf-8%B2%BD