]> Pileus Git - ~andy/gtk/blob - gdk/win32/gdkim-win32.c
applied patch from Andreas Persenius <ndap@swipnet.se> that updates the
[~andy/gtk] / gdk / win32 / gdkim-win32.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.  See the ChangeLog
23  * files for a list of changes.  These files are distributed with
24  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
25  */
26
27 #include <config.h>
28
29 #include <stdlib.h>
30 #include <string.h>
31 #include <locale.h>
32
33 #include "gdkim.h"
34 #include "gdkpixmap.h"
35 #include "gdkinternals.h"
36 #include "gdki18n.h"
37 #include "gdkwin32.h"
38
39 /*
40  *--------------------------------------------------------------
41  * gdk_set_locale
42  *
43  * Arguments:
44  *
45  * Results:
46  *
47  * Side effects:
48  *
49  *--------------------------------------------------------------
50  */
51
52 gchar*
53 gdk_set_locale (void)
54 {
55   if (!setlocale (LC_ALL, ""))
56     g_warning ("locale not supported by C library");
57   
58   return g_win32_getlocale ();
59 }
60
61 void 
62 gdk_im_begin (GdkIC *ic, GdkWindow* window)
63 {
64 }
65
66 void 
67 gdk_im_end (void)
68 {
69 }
70
71 GdkIMStyle
72 gdk_im_decide_style (GdkIMStyle supported_style)
73 {
74   return GDK_IM_PREEDIT_NONE | GDK_IM_STATUS_NONE;
75 }
76
77 GdkIMStyle
78 gdk_im_set_best_style (GdkIMStyle style)
79 {
80   return GDK_IM_PREEDIT_NONE | GDK_IM_STATUS_NONE;
81 }
82
83 gint 
84 gdk_im_ready (void)
85 {
86   return FALSE;
87 }
88
89 GdkIC * 
90 gdk_ic_new (GdkICAttr *attr, GdkICAttributesType mask)
91 {
92   return NULL;
93 }
94
95 void 
96 gdk_ic_destroy (GdkIC *ic)
97 {
98 }
99
100 GdkIMStyle
101 gdk_ic_get_style (GdkIC *ic)
102 {
103   return GDK_IM_PREEDIT_NONE | GDK_IM_STATUS_NONE;
104 }
105
106 void 
107 gdk_ic_set_values (GdkIC *ic, ...)
108 {
109 }
110
111 void 
112 gdk_ic_get_values (GdkIC *ic, ...)
113 {
114 }
115
116 GdkICAttributesType 
117 gdk_ic_set_attr (GdkIC *ic, GdkICAttr *attr, GdkICAttributesType mask)
118 {
119   return 0;
120 }
121
122 GdkICAttributesType 
123 gdk_ic_get_attr (GdkIC *ic, GdkICAttr *attr, GdkICAttributesType mask)
124 {
125   return 0;
126 }
127
128 GdkEventMask 
129 gdk_ic_get_events (GdkIC *ic)
130 {
131   return 0;
132 }
133
134 /*
135  * gdk_wcstombs 
136  *
137  * Returns a multi-byte string converted from the specified array
138  * of wide characters. The string is newly allocated. The array of
139  * wide characters must be null-terminated. If the conversion is
140  * failed, it returns NULL.
141  *
142  * On Win32, we always use UTF-8.
143  */
144 gchar *
145 gdk_wcstombs (const GdkWChar *src)
146 {
147   gint len;
148   const GdkWChar *wcp;
149   guchar *mbstr, *bp;
150
151   wcp = src;
152   len = 0;
153   while (*wcp)
154     {
155       const GdkWChar c = *wcp++;
156
157       if (c < 0x80)
158         len += 1;
159       else if (c < 0x800)
160         len += 2;
161       else if (c < 0x10000)
162         len += 3;
163       else if (c < 0x200000)
164         len += 4;
165       else if (c < 0x4000000)
166         len += 5;
167       else
168         len += 6;
169     }
170
171   mbstr = g_malloc (len + 1);
172   
173   wcp = src;
174   bp = mbstr;
175   while (*wcp)
176     {
177       int first;
178       int i;
179       GdkWChar c = *wcp++;
180
181       if (c < 0x80)
182         {
183           first = 0;
184           len = 1;
185         }
186       else if (c < 0x800)
187         {
188           first = 0xc0;
189           len = 2;
190         }
191       else if (c < 0x10000)
192         {
193           first = 0xe0;
194           len = 3;
195         }
196       else if (c < 0x200000)
197         {
198           first = 0xf0;
199           len = 4;
200         }
201       else if (c < 0x4000000)
202         {
203           first = 0xf8;
204           len = 5;
205         }
206       else
207         {
208           first = 0xfc;
209           len = 6;
210         }
211       
212       /* Woo-hoo! */
213       switch (len)
214         {
215         case 6: bp[5] = (c & 0x3f) | 0x80; c >>= 6; /* Fall through */
216         case 5: bp[4] = (c & 0x3f) | 0x80; c >>= 6; /* Fall through */
217         case 4: bp[3] = (c & 0x3f) | 0x80; c >>= 6; /* Fall through */
218         case 3: bp[2] = (c & 0x3f) | 0x80; c >>= 6; /* Fall through */
219         case 2: bp[1] = (c & 0x3f) | 0x80; c >>= 6; /* Fall through */
220         case 1: bp[0] = c | first;
221         }
222
223       bp += len;
224     }
225   *bp = 0;
226   return mbstr;
227 }
228
229   
230 /*
231  * gdk_mbstowcs
232  *
233  * Converts the specified string into GDK wide characters, and,
234  * returns the number of wide characters written. The string 'src'
235  * must be null-terminated. If the conversion is failed, it returns
236  * -1.
237  *
238  * On Win32, the string is assumed to be in UTF-8.  Also note that
239  * GdkWChar is 32 bits, while wchar_t, and the wide characters the
240  * Windows API uses, are 16 bits!
241  */
242
243 /* First a helper function for not zero-terminated strings */
244 gint
245 gdk_nmbstowcs (GdkWChar    *dest,
246                const gchar *src,
247                gint         src_len,
248                gint         dest_max)
249 {
250   guchar *cp, *end;
251   gint n;
252   
253   cp = (guchar *) src;
254   end = cp + src_len;
255   n = 0;
256   while (cp != end && dest != dest + dest_max)
257     {
258       gint i, mask = 0, len;
259       guchar c = *cp;
260
261       if (c < 0x80)
262         {
263           len = 1;
264           mask = 0x7f;
265         }
266       else if ((c & 0xe0) == 0xc0)
267         {
268           len = 2;
269           mask = 0x1f;
270         }
271       else if ((c & 0xf0) == 0xe0)
272         {
273           len = 3;
274           mask = 0x0f;
275         }
276       else if ((c & 0xf8) == 0xf0)
277         {
278           len = 4;
279           mask = 0x07;
280         }
281       else if ((c & 0xfc) == 0xf8)
282         {
283           len = 5;
284           mask = 0x03;
285         }
286       else if ((c & 0xfc) == 0xfc)
287         {
288           len = 6;
289           mask = 0x01;
290         }
291       else
292         return -1;
293
294       if (cp + len > end)
295         return -1;
296
297       *dest = (cp[0] & mask);
298       for (i = 1; i < len; i++)
299         {
300           if ((cp[i] & 0xc0) != 0x80)
301             return -1;
302           *dest <<= 6;
303           *dest |= (cp[i] & 0x3f);
304         }
305       if (*dest == -1)
306         return -1;
307
308       cp += len;
309       dest++;
310       n++;
311     }
312   if (cp != end)
313     return -1;
314
315   return n;
316 }
317
318 gint
319 gdk_mbstowcs (GdkWChar    *dest,
320               const gchar *src,
321               gint         dest_max)
322 {
323   return gdk_nmbstowcs (dest, src, strlen (src), dest_max);
324 }
325
326
327 /* A version that converts to wchar_t wide chars */
328
329 gint
330 gdk_nmbstowchar_ts (wchar_t     *dest,
331                     const gchar *src,
332                     gint         src_len,
333                     gint         dest_max)
334 {
335   wchar_t *wcp;
336   guchar *cp, *end;
337   gint n;
338   
339   wcp = dest;
340   cp = (guchar *) src;
341   end = cp + src_len;
342   n = 0;
343   while (cp != end && wcp != dest + dest_max)
344     {
345       gint i, mask = 0, len;
346       guchar c = *cp;
347
348       if (c < 0x80)
349         {
350           len = 1;
351           mask = 0x7f;
352         }
353       else if ((c & 0xe0) == 0xc0)
354         {
355           len = 2;
356           mask = 0x1f;
357         }
358       else if ((c & 0xf0) == 0xe0)
359         {
360           len = 3;
361           mask = 0x0f;
362         }
363       else /* Other lengths are not possible with 16-bit wchar_t! */
364         return -1;
365
366       if (cp + len > end)
367         return -1;
368
369       *wcp = (cp[0] & mask);
370       for (i = 1; i < len; i++)
371         {
372           if ((cp[i] & 0xc0) != 0x80)
373             return -1;
374           *wcp <<= 6;
375           *wcp |= (cp[i] & 0x3f);
376         }
377       if (*wcp == 0xFFFF)
378         return -1;
379
380       cp += len;
381       wcp++;
382       n++;
383     }
384   if (cp != end)
385     return -1;
386
387   return n;
388 }