]> Pileus Git - ~andy/gtk/blob - gdk/directfb/gdkim-directfb.c
f41ec9fcb2747c2c22bcdf7e76c3bb25c7562ee5
[~andy/gtk] / gdk / directfb / gdkim-directfb.c
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*
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 *
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 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
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
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
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 }