Add .gitignore, COPYING and INSTALL.
[gwm.git] / utf8.c
blobf2e66542ab41244ac295b8b78f595b25f71cc7fd
1 /*
2 * utf8.c
4 * Part of gwm, the Gratuitous Window Manager,
5 * by Gary Wong, <gtw@gnu.org>.
7 * Copyright (C) 2009 Gary Wong
9 * This program is free software: you can redistribute it and/or modify
10 * it under the terms of version 3 of the GNU General Public License as
11 * published by the Free Software Foundation.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 * $Id$
24 #include <config.h>
26 #if HAVE_ICONV_H
27 #include <iconv.h>
28 #endif
29 #include <string.h>
30 #include <xcb/xcb.h>
32 #include "gwm.h"
34 #include "utf8.h"
36 #if HAVE_ICONV
37 iconv_t iso2022;
38 int tried_iso2022;
39 #endif
41 extern char *to_utf8( enum gwm_encoding encoding, const char *in,
42 size_t len ) {
44 size_t outlen;
45 char *out, *outp;
47 if( len < 0 )
48 len = strlen( in );
50 #if HAVE_ICONV
51 outlen = len << ( encoding == ENCODING_COMPOUND ? 2 : 1 );
52 #else
53 outlen = len << 1;
54 #endif
56 outp = out = xmalloc( outlen + 1 );
58 #if HAVE_ICONV
59 if( encoding == ENCODING_COMPOUND ) {
60 if( !tried_iso2022 ) {
61 iso2022 = iconv_open( "UTF-8", "ISO-2022-JP-2" );
62 tried_iso2022 = TRUE;
65 if( iso2022 != (iconv_t) -1 ) {
66 static const char resetseq[ 3 ] = "\x1B\x2D\x41";
67 const char *inp;
68 size_t resetlen = 3;
70 /* Reset the decoder to the Compound Text initial state
71 (G1 = ASCII, G3 = ISO 8859-1). */
72 inp = resetseq;
73 iconv( iso2022, NULL, NULL, NULL, NULL );
74 /* Bah. Several old implementations of iconv() declared
75 the inbuf parameter as (const char **), but SUS says
76 it's simply (char **). We cast the thing to (void *),
77 which will keep them both happy. */
78 iconv( iso2022, (void *) &inp, &resetlen, &outp, &outlen );
80 iconv( iso2022, (void *) &in, &len, &outp, &outlen );
82 *outp++ = 0;
84 return xrealloc( out, outp - out );
87 #endif
89 for( ; len; len-- )
90 if( *in & 0x80 ) {
91 *outp++ = 0xC0 | ( *in >> 6 );
92 *outp++ = 0x80 | ( *in & 0x3F );
93 } else
94 *outp++ = *in++;
96 *outp++ = 0;
98 return xrealloc( out, outp - out );
101 extern void cleanup_utf8( void ) {
103 #if HAVE_ICONV
104 if( tried_iso2022 && iso2022 != (iconv_t) -1 )
105 iconv_close( iso2022 );
106 #endif