1 /*
2 * $Id: xlc_util.c,v 1.2 2001/06/14 18:16:18 ura Exp $
3 */
4
5 /*
6 * FreeWnn is a network-extensible Kana-to-Kanji conversion system.
7 * This file is part of FreeWnn.
8 *
9 * Copyright OMRON Corporation. 1987, 1988, 1989, 1990, 1991, 1992, 1999
10 * Copyright 1991, 1992 by Massachusetts Institute of Technology
11 *
12 * Author: OMRON SOFTWARE Co., Ltd. <freewnn@rd.kyoto.omronsoft.co.jp>
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2, or (at your option)
17 * any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with GNU Emacs; see the file COPYING. If not, write to the
26 * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 *
28 * Commentary:
29 *
30 * Change log:
31 *
32 * Last modified date: 8,Feb.1999
33 *
34 * Code:
35 *
36 */
37 /* Version 4.0
38 */
39 #include <stdio.h>
40 #include <string.h>
41 #include "commonhd.h"
42 #include "sdefine.h"
43 #ifdef XJUTIL
44 #include "xjutil.h"
45 #include "sxheader.h"
46 #include "xext.h"
47 #else /* XJUTIL */
48 #include "xim.h"
49 #include "sheader.h"
50 #include "ext.h"
51 #endif /* XJUTIL */
52
53 #ifdef X11R5
54 extern int _XConvertMBToWC (), _XConvertMBToCT (), _XConvertWCToCT ();
55 #ifndef X_WCHAR
56 extern int _XConvertWCToMB ();
57 #endif
58 #else
59 #include "Xlibint.h"
60 #include "XlcPubI.h"
61
62 #define BadBuffer (-1)
63
64 static int
_XConvertWCToMB(lcd,wstr,wc_len,str,mb_bytes,scanned_len)65 _XConvertWCToMB (lcd, wstr, wc_len, str, mb_bytes, scanned_len)
66 XLCd lcd;
67 wchar *wstr;
68 int wc_len;
69 unsigned char *str;
70 int *mb_bytes;
71 int *scanned_len;
72 {
73 /* modified from _Xlcwcstombs in lcStd.c */
74 XlcConv conv;
75 XPointer from, to;
76 int from_left, to_left, ret;
77 int len = *mb_bytes;
78
79 if (lcd == NULL)
80 {
81 lcd = _XlcCurrentLC ();
82 if (lcd == NULL)
83 return -1;
84 }
85
86 conv = _XlcOpenConverter (lcd, XlcNWideChar, lcd, XlcNMultiByte);
87 if (conv == NULL)
88 return -1;
89
90 from = (XPointer) wstr;
91 from_left = wc_len;
92 to = (XPointer) str;
93 to_left = len;
94
95 if (_XlcConvert (conv, &from, &from_left, &to, &to_left, NULL, 0) < 0)
96 ret = -1;
97 else
98 {
99 ret = len - to_left;
100 if (str && to_left > 0)
101 str[ret] = '\0';
102 }
103
104 _XlcCloseConverter (conv);
105
106 *mb_bytes = ret;
107 if (scanned_len)
108 *scanned_len = wc_len - from_left;
109 return ret;
110
111 }
112
113 /* ARGSUSED */
114 static int
_XConvertMBToWC(lcd,str,mb_bytes,wstr,wc_len,scanned_bytes,state)115 _XConvertMBToWC (lcd, str, mb_bytes, wstr, wc_len, scanned_bytes, state)
116 XLCd lcd;
117 unsigned char *str;
118 int mb_bytes;
119 wchar *wstr;
120 int *wc_len;
121 int *scanned_bytes;
122 int *state;
123 {
124 /* modified from _Xlcmbstowcs in lcStd.c */
125 XlcConv conv;
126 XPointer from, to;
127 int from_left, to_left, ret;
128 int len = *wc_len;
129
130 if (lcd == NULL)
131 {
132 lcd = _XlcCurrentLC ();
133 if (lcd == NULL)
134 return -1;
135 }
136
137 conv = _XlcOpenConverter (lcd, XlcNMultiByte, lcd, XlcNWideChar);
138 if (conv == NULL)
139 return -1;
140
141 from = (XPointer) str;
142 from_left = mb_bytes;
143 to = (XPointer) wstr;
144 to_left = len;
145
146 if (_XlcConvert (conv, &from, &from_left, &to, &to_left, NULL, 0) < 0)
147 ret = -1;
148 else
149 {
150 ret = len - to_left;
151 if (wstr && to_left > 0)
152 wstr[ret] = (wchar_t) 0;
153 }
154
155 _XlcCloseConverter (conv);
156
157 *wc_len = ret;
158 if (scanned_bytes)
159 *scanned_bytes = mb_bytes - from_left;
160 return 0;
161 }
162
163 /* ARGSUSED */
164 static int
_XConvertMBToCT(lcd,str,mb_bytes,ctstr,ct_bytes,scanned_bytes,state)165 _XConvertMBToCT (lcd, str, mb_bytes, ctstr, ct_bytes, scanned_bytes, state)
166 XLCd lcd;
167 unsigned char *str;
168 int mb_bytes;
169 unsigned char *ctstr;
170 int *ct_bytes;
171 int *scanned_bytes;
172 int *state;
173 {
174 /* modified from _Xlcmbstowcs in lcStd.c */
175 XlcConv conv;
176 XPointer from, to;
177 int from_left, to_left, ret;
178 int len = *ct_bytes;
179
180 if (lcd == NULL)
181 {
182 lcd = _XlcCurrentLC ();
183 if (lcd == NULL)
184 return -1;
185 }
186
187 conv = _XlcOpenConverter (lcd, XlcNMultiByte, lcd, XlcNCompoundText);
188 if (conv == NULL)
189 return -1;
190
191 from = (XPointer) str;
192 from_left = mb_bytes;
193 to = (XPointer) ctstr;
194 to_left = len;
195
196 if (_XlcConvert (conv, &from, &from_left, &to, &to_left, NULL, 0) < 0)
197 ret = -1;
198 else
199 {
200 ret = len - to_left;
201 if (ctstr && to_left > 0)
202 ctstr[ret] = '\0';
203 }
204
205 _XlcCloseConverter (conv);
206
207 *ct_bytes = ret;
208 if (scanned_bytes)
209 *scanned_bytes = mb_bytes - from_left;
210 return 0;
211 }
212
213 static int
_XConvertWCToCT(lcd,wstr,wc_len,str,ct_bytes,scanned_len)214 _XConvertWCToCT (lcd, wstr, wc_len, str, ct_bytes, scanned_len)
215 XLCd lcd;
216 wchar *wstr;
217 int wc_len;
218 unsigned char *str;
219 int *ct_bytes;
220 int *scanned_len;
221 {
222 /* modified from _Xlcwcstombs in lcStd.c */
223 XlcConv conv;
224 XPointer from, to;
225 int from_left, to_left, ret;
226 int len = *ct_bytes;
227
228 if (lcd == NULL)
229 {
230 lcd = _XlcCurrentLC ();
231 if (lcd == NULL)
232 return -1;
233 }
234
235 conv = _XlcOpenConverter (lcd, XlcNWideChar, lcd, XlcNCompoundText);
236 if (conv == NULL)
237 return -1;
238
239 from = (XPointer) wstr;
240 from_left = wc_len;
241 to = (XPointer) str;
242 to_left = len;
243
244 if (_XlcConvert (conv, &from, &from_left, &to, &to_left, NULL, 0) < 0)
245 ret = -1;
246 else
247 {
248 ret = len - to_left;
249 if (str && to_left > 0)
250 str[ret] = '\0';
251 }
252
253 _XlcCloseConverter (conv);
254
255 *ct_bytes = ret;
256 if (scanned_len)
257 *scanned_len = wc_len - from_left;
258 return ret;
259
260 }
261
262 #endif /* X11R5 */
263
264 int
alloc_all_buf()265 alloc_all_buf ()
266 {
267 char *wc, *ct, *c;
268 #ifndef X_WCHAR
269 char *w;
270 #endif /* !X_WCHAR */
271 if (((wc = Malloc (sizeof (wchar) * BUF_ALLOC_SIZE)) == NULL) || ((ct = Malloc (sizeof (unsigned char) * BUF_ALLOC_SIZE)) == NULL) || ((c = Malloc (sizeof (unsigned char) * BUF_ALLOC_SIZE)) == NULL)
272 #ifndef X_WCHAR
273 || ((w = Malloc (sizeof (wchar_t) * BUF_ALLOC_SIZE)) == NULL)
274 #endif /* !X_WCHAR */
275 )
276 {
277 malloc_error ("allocation of temporary buffer");
278 return (-1);
279 }
280 wc_buf = (wchar *) wc;
281 ct_buf = (unsigned char *) ct;
282 c_buf = (unsigned char *) c;
283 wc_buf_max = ct_buf_max = c_buf_max = BUF_ALLOC_SIZE;
284 #ifndef X_WCHAR
285 wt_buf = (wchar_t *) w;
286 wt_buf_max = BUF_ALLOC_SIZE;
287 #endif /* !X_WCHAR */
288 return (0);
289 }
290
291 int
realloc_wc_buf()292 realloc_wc_buf ()
293 {
294 register char *p;
295
296 if ((p = Malloc (sizeof (wchar) * (wc_buf_max + BUF_ALLOC_SIZE))) == NULL)
297 {
298 malloc_error ("re-allocation of temporary buffer");
299 return (-1);
300 }
301 Free ((char *) wc_buf);
302 wc_buf = (wchar *) p;
303 wc_buf_max += BUF_ALLOC_SIZE;
304 return (0);
305 }
306
307 int
realloc_ct_buf()308 realloc_ct_buf ()
309 {
310 register char *p;
311 if ((p = Malloc (sizeof (unsigned char) * (ct_buf_max + BUF_ALLOC_SIZE))) == NULL)
312 {
313 malloc_error ("re-allocation of temporary buffer");
314 return (-1);
315 }
316 Free ((char *) ct_buf);
317 ct_buf = (unsigned char *) p;
318 ct_buf_max += BUF_ALLOC_SIZE;
319 return (0);
320 }
321
322 int
realloc_c_buf()323 realloc_c_buf ()
324 {
325 register char *p;
326
327 if ((p = Malloc (sizeof (unsigned char) * (c_buf_max + BUF_ALLOC_SIZE))) == NULL)
328 {
329 malloc_error ("re-allocation of temporary buffer");
330 return (-1);
331 }
332 Free ((char *) c_buf);
333 c_buf = (unsigned char *) p;
334 c_buf_max += BUF_ALLOC_SIZE;
335 return (0);
336 }
337
338 #ifndef X_WCHAR
339 int
realloc_wt_buf()340 realloc_wt_buf ()
341 {
342 register char *p;
343
344 if ((p = Malloc (sizeof (wchar_t) * (wt_buf_max + BUF_ALLOC_SIZE))) == NULL)
345 {
346 malloc_error ("re-allocation of temporary buffer");
347 return (-1);
348 }
349 Free ((char *) wt_buf);
350 wt_buf = (wchar_t *) p;
351 wt_buf_max += BUF_ALLOC_SIZE;
352 return (0);
353 }
354 #endif /* !X_WCHAR */
355
356 int
get_columns_wchar(from)357 get_columns_wchar (from)
358 register wchar *from;
359 {
360 register wchar *wc = from;
361
362 while (*wc == PENDING_WCHAR)
363 wc++;
364 if (*wc)
365 wc++;
366 return (wc - from);
367 }
368
369 #ifndef X11R5
370 /*
371 * wchar encoding is for EUC in X11R6.
372 * WARNING: This is rough alorithm, unless we can call ANSI C function.
373 */
374 static int
_XcwGetLength(wc)375 _XcwGetLength (wc)
376 wchar wc;
377 {
378 if (!(wc & ~0xFF))
379 return 1;
380 else
381 return 2;
382 }
383 #endif /* !X11R5 */
384
385 int
XwcGetColumn(wc)386 XwcGetColumn (wc)
387 wchar wc;
388 {
389 if (wc == PENDING_WCHAR)
390 return (0);
391 #if defined(__STDC__) && defined(_I18N_)
392 return wcwidth (wc);
393 #else
394 return _XcwGetLength (wc);
395 #endif /* defined(__STDC__) && defined(_I18N_) */
396 }
397
398 int
check_mb(buf,x)399 check_mb (buf, x)
400 register wchar *buf;
401 register int x;
402 {
403 if (*(buf + x) == PENDING_WCHAR)
404 return (1);
405 if (XwcGetColumn (*(buf + x)) > 1)
406 return (2);
407 return (0);
408 }
409
410 int
w_char_to_char(w,c,n)411 w_char_to_char (w, c, n)
412 register w_char *w;
413 register char *c;
414 register int n;
415 {
416 #ifndef XJUTIL
417 set_cswidth (cur_lang->cswidth_id);
418 #endif /* !XJUTIL */
419 return (ieuc_to_eeuc (c, w, (n * sizeof (w_char))));
420 }
421
422 int
skip_pending_wchar(to,from)423 skip_pending_wchar (to, from)
424 register wchar *to, *from;
425 {
426 register wchar *wc = to;
427 for (; *from;)
428 {
429 if (*from == PENDING_WCHAR)
430 from++;
431 *wc++ = *from++;
432 }
433 *wc = 0;
434 return (wc - to);
435 }
436
437 int
put_pending_wchar_and_flg(wc,buf,att,flg)438 put_pending_wchar_and_flg (wc, buf, att, flg)
439 register wchar wc;
440 wchar *buf;
441 unsigned char *att, flg;
442 {
443 register wchar *p = buf;
444 register unsigned char *f = att;
445 register int mb_len, i;
446
447 mb_len = XwcGetColumn (wc);
448 for (i = 1; i < mb_len; i++)
449 {
450 *p++ = PENDING_WCHAR;
451 *f++ = flg;
452 }
453 *p++ = wc;;
454 *f++ = flg;
455 return (mb_len);
456 }
457
458 #ifdef CALLBACKS
459 int
XwcGetChars(wc,end,left)460 XwcGetChars (wc, end, left)
461 register wchar *wc;
462 int end;
463 int *left;
464 {
465 register int i, cnt;
466
467 *left = 0;
468 for (i = 0, cnt = 0; i < end && *wc; i++, cnt++, wc++)
469 {
470 if (*wc == PENDING_WCHAR)
471 {
472 wc++;
473 i++;
474 if (!(i < end))
475 {
476 for (*left = 1; *wc == PENDING_WCHAR; wc++)
477 *left += 1;
478 cnt++;
479 return (cnt);
480 }
481 }
482 }
483 return (cnt);
484 }
485 #endif /* CALLBACKS */
486
487 int
char_to_wchar(xlc,c,wc,len,wc_len)488 char_to_wchar (xlc, c, wc, len, wc_len)
489 #ifdef X11R5
490 XLocale xlc;
491 #else
492 XLCd xlc;
493 #endif /* X11R5 */
494 unsigned char *c;
495 wchar *wc;
496 int len;
497 int wc_len;
498 {
499 int wc_str_len = wc_len;
500 int scanned_byte = 0;
501 int ret;
502
503 ret = _XConvertMBToWC (xlc, c, len, wc, &wc_str_len, &scanned_byte, NULL);
504 if (ret < 0)
505 {
506 if (ret == BadBuffer)
507 {
508 return (-1);
509 }
510 else
511 {
512 return (-2);
513 }
514 }
515 return (wc_str_len);
516 }
517
518 int
w_char_to_wchar(xlc,w,wc,len,wc_len)519 w_char_to_wchar (xlc, w, wc, len, wc_len)
520 #ifdef X11R5
521 XLocale xlc;
522 #else
523 XLCd xlc;
524 #endif /* X11R5 */
525 w_char *w;
526 wchar *wc;
527 int len;
528 int wc_len;
529 {
530 int ret;
531
532 while (c_buf_max < (len * 2))
533 {
534 if (realloc_c_buf () < 0)
535 return (0);
536 }
537 ret = w_char_to_char (w, c_buf, len);
538 if (ret <= 0)
539 return (0);
540
541 return (char_to_wchar (xlc, (unsigned char *) c_buf, wc, ret, wc_len));
542 }
543
544 int
w_char_to_ct(xlc,w,ct,len,ct_len)545 w_char_to_ct (xlc, w, ct, len, ct_len)
546 #ifdef X11R5
547 XLocale xlc;
548 #else
549 XLCd xlc;
550 #endif /* X11R5 */
551 w_char *w;
552 unsigned char *ct;
553 int len;
554 int ct_len;
555 {
556 int ret;
557 int ct_str_len = ct_len;
558 int scanned_byte = 0;
559
560 while (c_buf_max < (len * 2))
561 {
562 if (realloc_c_buf () < 0)
563 return (0);
564 }
565 ret = w_char_to_char (w, c_buf, len);
566 if (ret <= 0)
567 return (0);
568
569 ret = _XConvertMBToCT (xlc, c_buf, ret, ct, &ct_str_len, &scanned_byte, NULL);
570 if (ret < 0)
571 {
572 if (ret == BadBuffer)
573 {
574 return (-1);
575 }
576 else
577 {
578 return (-2);
579 }
580 }
581 return (ct_str_len);
582 }
583
584 int
wchar_to_ct(xlc,w,ct,len,ct_len)585 wchar_to_ct (xlc, w, ct, len, ct_len)
586 #ifdef X11R5
587 XLocale xlc;
588 #else
589 XLCd xlc;
590 #endif /* X11R5 */
591 wchar *w;
592 unsigned char *ct;
593 int len;
594 int ct_len;
595 {
596 int scanned_byte;
597 int ct_str_len = ct_len;
598 int ret;
599
600 ret = _XConvertWCToCT (xlc, w, len, ct, &ct_str_len, &scanned_byte, NULL);
601 if (ret < 0)
602 {
603 if (ret == BadBuffer)
604 {
605 return (-1);
606 }
607 else
608 {
609 return (-2);
610 }
611 }
612 return (ct_str_len);
613 }
614
615 void
JWOutput(w,fs,gc,start_col,col,flg,offset_x,offset_y,cs,text,text_len)616 JWOutput (w, fs, gc, start_col, col, flg, offset_x, offset_y, cs, text, text_len)
617 Window w;
618 XFontSet fs;
619 GC gc;
620 short start_col, col;
621 unsigned char flg;
622 short offset_x, offset_y;
623 XCharStruct *cs;
624 wchar *text;
625 int text_len;
626 {
627 register int start_x, start_y;
628 wchar_t *w_text;
629 int w_text_len;
630 #ifndef X_WCHAR
631 int mb_buf_len;
632 int scanned_byte;
633 int ret;
634 #endif /* !X_WCHAR */
635
636 #ifdef X_WCHAR
637 w_text = (wchar_t *) text;
638 w_text_len = text_len;
639 #else /* X_WCHAR */
640 while (1)
641 {
642 mb_buf_len = c_buf_max;
643 ret = _XConvertWCToMB (
644 #ifdef XJUTIL
645 NULL,
646 #else
647 cur_p->cur_xl->xlc,
648 #endif
649 text, text_len, c_buf, &mb_buf_len, &scanned_byte, NULL);
650 if (ret < 0)
651 {
652 if (ret == BadBuffer)
653 {
654 if (realloc_c_buf () < 0)
655 return;
656 }
657 else
658 {
659 return;
660 }
661 }
662 else
663 {
664 break;
665 }
666 }
667 w_text = wt_buf;
668 while (1)
669 {
670 w_text_len = mbstowcs (wt_buf, (char *) c_buf, wt_buf_max);
671 if (w_text_len == wt_buf_max)
672 {
673 if (realloc_wt_buf () < 0)
674 return;
675 }
676 else
677 {
678 break;
679 }
680 }
681 #endif /* X_WCHAR */
682
683 start_x = (cs->width * start_col) + offset_x;
684 start_y = cs->ascent + offset_y;
685 if (flg & REV_FLAG)
686 {
687 XwcDrawImageString (dpy, w, fs, gc, start_x, start_y, w_text, w_text_len);
688 }
689 else
690 {
691 XClearArea (dpy, w, start_x, offset_y, (cs->width * col), (cs->ascent + cs->descent), False);
692 XwcDrawString (dpy, w, fs, gc, start_x, start_y, w_text, w_text_len);
693 }
694 if (flg & BOLD_FLAG)
695 XwcDrawString (dpy, w, fs, gc, (start_x + 1), start_y, w_text, w_text_len);
696 if (flg & UNDER_FLAG)
697 XDrawLine (dpy, w, gc, start_x, (start_y + 1), (start_x + cs->width * col), start_y + 1);
698 return;
699 }
700
701 XCharStruct *
get_base_char(fs)702 get_base_char (fs)
703 XFontSet fs;
704 {
705 XCharStruct *cs;
706 XFontStruct **fs_list;
707 char **fn_list;
708
709 if (XFontsOfFontSet (fs, &fs_list, &fn_list) < 1)
710 {
711 print_out ("I could not get base char struct.");
712 return (NULL);
713 }
714 if (!(cs = (XCharStruct *) Malloc (sizeof (XCharStruct))))
715 {
716 malloc_error ("allocation of base char struct");
717 return (NULL);
718 }
719 cs->width = fs_list[0]->max_bounds.width;
720 cs->ascent = fs_list[0]->ascent;
721 cs->descent = fs_list[0]->descent;
722 return ((XCharStruct *) cs);
723 }
724
725 /* *INDENT-OFF* */
726 XFontSet
create_font_set(s)727 create_font_set (s)
728 char *s;
729 /* *INDENT-ON* */
730
731 {
732 XFontSet xfontset;
733 char **missing_charset_list;
734 int missing_charset_count;
735 char *def_string;
736
737 xfontset = XCreateFontSet (dpy, s, &missing_charset_list, &missing_charset_count, &def_string);
738 if ((xfontset == NULL) /* || (missing_charset_count > 0) */ )
739 {
740 print_out ("Can not create FontSet\n");
741 return ((XFontSet) NULL);
742 }
743 if (missing_charset_count > 0)
744 {
745 XFreeStringList (missing_charset_list);
746 }
747 return ((XFontSet) xfontset);
748 }
749