1 /* GDK - The GIMP Drawing Kit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
18 */
19
20 /*
21 * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
22 * file for a list of people on the GTK+ Team.
23 */
24
25 /*
26 * GTK+ DirectFB backend
27 * Copyright (C) 2001-2002 convergence integrated media GmbH
28 * Copyright (C) 2002-2004 convergence GmbH
29 * Written by Denis Oliver Kropp <dok@convergence.de> and
30 * Sven Neumann <sven@convergence.de>
31 */
32
33 #include "config.h"
34
35 #include <string.h>
36 #include <locale.h>
37
38 #include "gdkdirectfb.h"
39
40 /*
41 *--------------------------------------------------------------
42 * gdk_set_locale
43 *
44 * Arguments:
45 *
46 * Results:
47 *
48 * Side effects:
49 *
50 *--------------------------------------------------------------
51 */
52
53 gchar*
gdk_set_locale(void)54 gdk_set_locale (void)
55 {
56 if (!setlocale (LC_ALL,""))
57 g_warning ("locale not supported by C library");
58
59 return setlocale (LC_ALL, NULL);
60 }
61 /*
62 * gdk_wcstombs
63 *
64 * Returns a multi-byte string converted from the specified array
65 * of wide characters. The string is newly allocated. The array of
66 * wide characters must be null-terminated. If the conversion is
67 * failed, it returns NULL.
68 *
69 * On Win32, we always use UTF-8.
70 */
71 gchar *
gdk_wcstombs(const GdkWChar * src)72 gdk_wcstombs (const GdkWChar *src)
73 {
74 gint len;
75 const GdkWChar *wcp;
76 guchar *mbstr, *bp;
77
78 wcp = src;
79 len = 0;
80 while (*wcp)
81 {
82 const GdkWChar c = *wcp++;
83
84 if (c < 0x80)
85 len += 1;
86 else if (c < 0x800)
87 len += 2;
88 else if (c < 0x10000)
89 len += 3;
90 else if (c < 0x200000)
91 len += 4;
92 else if (c < 0x4000000)
93 len += 5;
94 else
95 len += 6;
96 }
97
98 mbstr = g_malloc (len + 1);
99
100 wcp = src;
101 bp = mbstr;
102 while (*wcp)
103 {
104 int first;
105 GdkWChar c = *wcp++;
106
107 if (c < 0x80)
108 {
109 first = 0;
110 len = 1;
111 }
112 else if (c < 0x800)
113 {
114 first = 0xc0;
115 len = 2;
116 }
117 else if (c < 0x10000)
118 {
119 first = 0xe0;
120 len = 3;
121 }
122 else if (c < 0x200000)
123 {
124 first = 0xf0;
125 len = 4;
126 }
127 else if (c < 0x4000000)
128 {
129 first = 0xf8;
130 len = 5;
131 }
132 else
133 {
134 first = 0xfc;
135 len = 6;
136 }
137
138 /* Woo-hoo! */
139 switch (len)
140 {
141 case 6: bp[5] = (c & 0x3f) | 0x80; c >>= 6; /* Fall through */
142 case 5: bp[4] = (c & 0x3f) | 0x80; c >>= 6; /* Fall through */
143 case 4: bp[3] = (c & 0x3f) | 0x80; c >>= 6; /* Fall through */
144 case 3: bp[2] = (c & 0x3f) | 0x80; c >>= 6; /* Fall through */
145 case 2: bp[1] = (c & 0x3f) | 0x80; c >>= 6; /* Fall through */
146 case 1: bp[0] = c | first;
147 }
148
149 bp += len;
150 }
151
152 *bp = 0;
153
154 return (gchar*)mbstr;
155 }
156
157
158 /*
159 * gdk_mbstowcs
160 *
161 * Converts the specified string into GDK wide characters, and,
162 * returns the number of wide characters written. The string 'src'
163 * must be null-terminated. If the conversion is failed, it returns
164 * -1.
165 *
166 * On Win32, the string is assumed to be in UTF-8. Also note that
167 * GdkWChar is 32 bits, while wchar_t, and the wide characters the
168 * Windows API uses, are 16 bits!
169 */
170
171 /* First a helper function for not zero-terminated strings */
172 gint
gdk_nmbstowcs(GdkWChar * dest,const gchar * src,gint src_len,gint dest_max)173 gdk_nmbstowcs (GdkWChar *dest,
174 const gchar *src,
175 gint src_len,
176 gint dest_max)
177 {
178 guchar *cp, *end;
179 gint n;
180
181 cp = (guchar *) src;
182 end = cp + src_len;
183 n = 0;
184 while (cp != end && dest != dest + dest_max)
185 {
186 gint i, mask = 0, len;
187 guchar c = *cp;
188
189 if (c < 0x80)
190 {
191 len = 1;
192 mask = 0x7f;
193 }
194 else if ((c & 0xe0) == 0xc0)
195 {
196 len = 2;
197 mask = 0x1f;
198 }
199 else if ((c & 0xf0) == 0xe0)
200 {
201 len = 3;
202 mask = 0x0f;
203 }
204 else if ((c & 0xf8) == 0xf0)
205 {
206 len = 4;
207 mask = 0x07;
208 }
209 else if ((c & 0xfc) == 0xf8)
210 {
211 len = 5;
212 mask = 0x03;
213 }
214 else if ((c & 0xfc) == 0xfc)
215 {
216 len = 6;
217 mask = 0x01;
218 }
219 else
220 return -1;
221
222 if (cp + len > end)
223 return -1;
224
225 *dest = (cp[0] & mask);
226 for (i = 1; i < len; i++)
227 {
228 if ((cp[i] & 0xc0) != 0x80)
229 return -1;
230 *dest <<= 6;
231 *dest |= (cp[i] & 0x3f);
232 }
233
234 if (*dest == -1)
235 return -1;
236
237 cp += len;
238 dest++;
239 n++;
240 }
241
242 if (cp != end)
243 return -1;
244
245 return n;
246 }
247
248 gint
gdk_mbstowcs(GdkWChar * dest,const gchar * src,gint dest_max)249 gdk_mbstowcs (GdkWChar *dest,
250 const gchar *src,
251 gint dest_max)
252 {
253 return gdk_nmbstowcs (dest, src, strlen (src), dest_max);
254 }
255
256
257 /* A version that converts to wchar_t wide chars */
258
259 gint
gdk_nmbstowchar_ts(wchar_t * dest,const gchar * src,gint src_len,gint dest_max)260 gdk_nmbstowchar_ts (wchar_t *dest,
261 const gchar *src,
262 gint src_len,
263 gint dest_max)
264 {
265 wchar_t *wcp;
266 guchar *cp, *end;
267 gint n;
268
269 wcp = dest;
270 cp = (guchar *) src;
271 end = cp + src_len;
272 n = 0;
273 while (cp != end && wcp != dest + dest_max)
274 {
275 gint i, mask = 0, len;
276 guchar c = *cp;
277
278 if (c < 0x80)
279 {
280 len = 1;
281 mask = 0x7f;
282 }
283 else if ((c & 0xe0) == 0xc0)
284 {
285 len = 2;
286 mask = 0x1f;
287 }
288 else if ((c & 0xf0) == 0xe0)
289 {
290 len = 3;
291 mask = 0x0f;
292 }
293 else /* Other lengths are not possible with 16-bit wchar_t! */
294 return -1;
295
296 if (cp + len > end)
297 return -1;
298
299 *wcp = (cp[0] & mask);
300 for (i = 1; i < len; i++)
301 {
302 if ((cp[i] & 0xc0) != 0x80)
303 return -1;
304 *wcp <<= 6;
305 *wcp |= (cp[i] & 0x3f);
306 }
307 if (*wcp == 0xFFFF)
308 return -1;
309
310 cp += len;
311 wcp++;
312 n++;
313 }
314
315 if (cp != end)
316 return -1;
317
318 return n;
319 }
320