chiark / gitweb /
*** empty log message ***
[sympathy.git] / src / utf8.c
1 /*
2  * utf8.c:
3  *
4  * Copyright (c) 2008 James McKenzie <james@fishsoup.dhs.org>,
5  * All rights reserved.
6  *
7  */
8
9 static char rcsid[] = "$Id$";
10
11 /*
12  * $Log$
13  * Revision 1.6  2008/02/26 23:23:17  james
14  * *** empty log message ***
15  *
16  * Revision 1.5  2008/02/24 00:42:53  james
17  * *** empty log message ***
18  *
19  * Revision 1.4  2008/02/23 13:05:58  staffcvs
20  * *** empty log message ***
21  *
22  * Revision 1.3  2008/02/23 11:48:37  james
23  * *** empty log message ***
24  *
25  * Revision 1.2  2008/02/22 23:39:27  james
26  * *** empty log message ***
27  *
28  * Revision 1.1  2008/02/22 19:12:05  james
29  * *** empty log message ***
30  *
31  */
32
33 #include "project.h"
34
35
36 void
37 utf8_flush (Context * c)
38 {
39   UTF8 *u = c->u;
40   int i;
41
42   switch (u->utf_ptr)
43     {
44     case 1:
45       log_f (c->l, "<invalid utf-8 sequence: \\%03o>", u->utf_buf[0]);
46       break;
47     case 2:
48       log_f (c->l, "<invalid utf-8 sequence: \\%03o \\%03o>",
49              u->utf_buf[0], u->utf_buf[1]);
50       break;
51     case 3:
52       log_f (c->l, "<invalid utf-8 sequence: \\%03o \\%03o \\%03o>",
53              u->utf_buf[0], u->utf_buf[1], u->utf_buf[2]);
54       break;
55     case 4:
56       log_f (c->l,
57              "<invalid utf-8 sequence: \\%03o \\%03o \\%03o \\%03o>",
58              u->utf_buf[0], u->utf_buf[1], u->utf_buf[2], u->utf_buf[3]);
59       break;
60     }
61
62   for (i = 0; i < u->utf_ptr; ++i)
63     vt102_parse_char (c, u->utf_buf[i]);
64
65   u->utf_ptr = 0;
66   u->in_utf8 = 0;
67 }
68
69 void
70 utf8_parse (Context * c, uint32_t ch)
71 {
72   UTF8 *u = c->u;
73
74   if (ch == SYM_CHAR_RESET)
75     {
76       u->in_utf8 = 0;
77       vt102_parse_char (c, ch);
78       return;
79     }
80
81   if (!u->in_utf8)
82     {
83       /*FIXME: for the moment we bodge utf8 support - need to do */
84       /* L->R and R->L and double width characters */
85       if (ch == 0xb9)
86         {                       /*CSI, not a valid utf8 start char */
87           vt102_parse_char (c, ch);
88         }
89       else if ((ch & 0xe0) == 0xc0)
90         {                       /*Start of two byte unicode sequence */
91           u->in_utf8 = 1;
92           u->utf_ptr = 0;
93           u->utf_buf[u->utf_ptr++] = ch;
94           u->ch = (ch & 0x1f) << 6;
95           u->sh = 0;
96         }
97       else if ((ch & 0xf0) == 0xe0)
98         {                       /*Start of three byte unicode sequence */
99           u->in_utf8 = 2;
100           u->utf_ptr = 0;
101           u->utf_buf[u->utf_ptr++] = ch;
102           u->ch = (ch & 0x0f) << 12;
103           u->sh = 6;
104         }
105       else if ((ch & 0xf8) == 0xf0)
106         {
107           u->in_utf8 = 3;
108           u->utf_ptr = 0;
109           u->utf_buf[u->utf_ptr++] = ch;
110           u->ch = (ch & 0x07) << 18;
111           u->sh = 12;
112         }
113       else
114         {
115           vt102_parse_char (c, ch);
116         }
117     }
118   else
119     {
120       if ((ch & 0xc0) != 0x80)
121         {
122           utf8_flush (c);
123           vt102_parse_char (c, ch);
124         }
125       else
126         {
127           u->utf_buf[u->utf_ptr++] = ch;
128           u->ch |= (ch & 0x3f) << u->sh;
129           u->sh -= 6;
130           u->in_utf8--;
131
132           if (!u->in_utf8)
133             vt102_parse_char (c, u->ch);
134         }
135     }
136 }
137
138
139
140 UTF8 *
141 utf8_new (void)
142 {
143   UTF8 *ret;
144
145   ret = (UTF8 *) malloc (sizeof (UTF8));
146
147   ret->in_utf8 = 0;
148
149 }
150
151
152
153 void
154 utf8_emit (TTY * t, int ch)
155 {
156   uint8_t buf[4];
157
158   if (ch < 0x80)
159     {
160       buf[0] = ch;
161       t->xmit (t, buf, 1);
162     }
163   else if (ch < 0x800)
164     {
165       buf[0] = 0xc0 | (ch >> 6);
166       buf[1] = 0x80 | (ch & 0x3f);
167
168       t->xmit (t, buf, 2);
169     }
170   else if (ch < 0x10000)
171     {
172       buf[0] = 0xe0 | (ch >> 12);
173       buf[1] = 0x80 | ((ch >> 6) & 0x3f);
174       buf[2] = 0x80 | (ch & 0x3f);
175       t->xmit (t, buf, 3);
176     }
177   else if (ch < 0x1fffff)
178     {
179       buf[0] = 0xf0 | (ch >> 18);
180       buf[1] = 0x80 | ((ch >> 12) & 0x3f);
181       buf[2] = 0x80 | ((ch >> 6) & 0x3f);
182       buf[3] = 0x80 | (ch & 0x3f);
183       t->xmit (t, buf, 4);
184     }
185 }
186