2 * vim:ts=4:sw=4:expandtab
4 * i3 - an improved dynamic tiling window manager
5 * © 2009-2011 Michael Stapelberg and contributors (see also: LICENSE)
16 static iconv_t utf8_conversion_descriptor = (iconv_t)-1;
17 static iconv_t ucs2_conversion_descriptor = (iconv_t)-1;
20 * Converts the given string to UTF-8 from UCS-2 big endian. The return value
21 * must be freed after use.
24 char *convert_ucs2_to_utf8(xcb_char2b_t *text, size_t num_glyphs) {
25 /* Allocate the output buffer (UTF-8 is at most 4 bytes per glyph) */
26 size_t buffer_size = num_glyphs * 4 * sizeof(char) + 1;
27 char *buffer = scalloc(buffer_size * sizeof(char));
29 /* We need to use an additional pointer, because iconv() modifies it */
30 char *output = buffer;
31 size_t output_size = buffer_size - 1;
33 if (utf8_conversion_descriptor == (iconv_t)-1) {
34 /* Get a new conversion descriptor */
35 utf8_conversion_descriptor = iconv_open("UTF-8", "UCS-2BE");
36 if (utf8_conversion_descriptor == (iconv_t)-1)
37 err(EXIT_FAILURE, "Error opening the conversion context");
40 /* Reset the existing conversion descriptor */
41 iconv(utf8_conversion_descriptor, NULL, NULL, NULL, NULL);
44 /* Do the conversion */
45 size_t input_len = num_glyphs * sizeof(xcb_char2b_t);
46 size_t rc = iconv(utf8_conversion_descriptor, (char**)&text,
47 &input_len, &output, &output_size);
48 if (rc == (size_t)-1) {
49 perror("Converting to UTF-8 failed");
58 * Converts the given string to UCS-2 big endian for use with
59 * xcb_image_text_16(). The amount of real glyphs is stored in real_strlen,
60 * a buffer containing the UCS-2 encoded string (16 bit per glyph) is
61 * returned. It has to be freed when done.
64 xcb_char2b_t *convert_utf8_to_ucs2(char *input, int *real_strlen) {
65 /* Calculate the input buffer size (UTF-8 is strlen-safe) */
66 size_t input_size = strlen(input);
68 /* Calculate the output buffer size and allocate the buffer */
69 size_t buffer_size = input_size * sizeof(xcb_char2b_t);
70 xcb_char2b_t *buffer = smalloc(buffer_size);
72 /* We need to use an additional pointer, because iconv() modifies it */
73 size_t output_size = buffer_size;
74 xcb_char2b_t *output = buffer;
76 if (ucs2_conversion_descriptor == (iconv_t)-1) {
77 /* Get a new conversion descriptor */
78 ucs2_conversion_descriptor = iconv_open("UCS-2BE", "UTF-8");
79 if (ucs2_conversion_descriptor == (iconv_t)-1)
80 err(EXIT_FAILURE, "Error opening the conversion context");
83 /* Reset the existing conversion descriptor */
84 iconv(ucs2_conversion_descriptor, NULL, NULL, NULL, NULL);
87 /* Do the conversion */
88 size_t rc = iconv(ucs2_conversion_descriptor, (char**)&input,
89 &input_size, (char**)&output, &output_size);
90 if (rc == (size_t)-1) {
91 perror("Converting to UCS-2 failed");
93 if (real_strlen != NULL)
98 /* Return the resulting string's length */
99 if (real_strlen != NULL)
100 *real_strlen = (buffer_size - output_size) / sizeof(xcb_char2b_t);