(U+5364-itaiji-002): New character.
[chise/xemacs-chise.git.1] / src / mule-canna.c
1 /* CANNA interface -*- coding: euc-jp -*-
2
3    Copyright (C) 1995 Free Software Foundation, Inc.
4    Copyright (C) 1995 Sun Microsystems, Inc.
5
6 This file is part of XEmacs.
7
8 XEmacs is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by the
10 Free Software Foundation; either version 2, or (at your option) any
11 later version.
12
13 XEmacs is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with XEmacs; see the file COPYING.  If not, write to
20 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA.  */
22
23 /* Synched up with: Mule 2.3.  Not in FSF. */
24
25 /* Japanese comments were translated 2000-12-06 by Stephen Turnbull
26    <stephen@xemacs.org>.  I haven't verified that the Japanese comments
27    were correct.  YMMV, NO WARRANTY, not even the implied warranty of
28    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  (^^;;; as the
29    Japanese say. */
30
31 /*
32
33   Authors: Akira Kon (kon@uxd.fc.nec.co.jp)
34            Ichiro Hirakura (hirakura@uxd.fc.nec.co.jp)
35
36   Functions defined in this file are
37
38   (canna-key-proc key)
39                 key: single STRING
40                 RETURNS:
41                          Length of converted string if no error occurs.
42                          Error string if error occurs.
43                 DESCRIPTION:
44                          Convert a key input to a set of strings.  The
45                          strings contain both well-formed string and a
46                          intermediate result to show the translation
47                          information to a user.  converted strings are
48                          stored in specific variables.
49
50   (canna-initialize)
51                 RETURNS:
52                         List of the following things:
53                         - list of keys to toggle Japanese-mode
54                         - error message
55                         - list of warning messages
56                 DESCRIPTION:
57                         Initialize ``canna'', which is a kana-to-kanji
58                         converter for GNU Emacs.  The first arg
59                         specifies if inserting space character between
60                         BUNSETSU when candidates are displayed.  The
61                         second arg specifies server.  The third arg
62                         specifies a file which will be used as a
63                         customization description.  If nil is
64                         specified for each arg, the default value will
65                         be used.
66
67   (canna-finalize)
68                 RETURNS:
69                         list of warning messages
70                 DESCRIPTION:
71                         finalize ``canna'', which is a kana-to-kanji
72                         converter for GNU Emacs.  This cause to write
73                         miscellaneous informations to kana-to-kanji
74                         dictionary.
75
76   (canna-touroku-string string)
77                 string:
78                         String to register to a dictionary.
79                 RETURNS:
80                         The same thing returns as canna-key-proc does.
81                 DESCRIPTION:
82                         Register Kanji words into kana-to-kanji
83                         conversion dictionary.
84
85   (canna-set-width width)
86                 width:
87                         Column width of the place where the candidates
88                         of kana-to-kanji conversion will be shown.
89                 RETURNS:
90                         nil
91                 DESCRIPTION:
92                         Set status-line width information, which is
93                         used to display kanji candidates.
94
95   (canna-change-mode num)
96                 num:
97                         The mode number of Canna.
98                 RETURNS:
99                         The same thing returns as canna-key-proc does.
100                 DESCRIPTION:
101                         Change Japanese pre-edit mode.
102
103   (canna-store-yomi yomi roma)
104                 yomi:
105                         ``Yomi'' to be stored.
106                 roma:
107                         ``Romaji'' which corresponds to the ``Yomi''.
108                 RETURNS:
109                         The same thing returns as canna-key-proc does.
110                 DESCRIPTION:
111                         Store yomi characters as a YOMI of
112                         kana-to-kanji conversion.
113
114   (canna-do-function num ch)
115                 num:
116                         A function number to be called.
117                 ch:
118                         A character will be specified in order to feed
119                         the character to the function if the function
120                         needs a input character.
121                 RETURNS:
122                         The same thing returns as canna-key-proc does.
123                 DESCRIPTION:
124                         Do specified function at current mode.
125
126   (canna-parse string)
127                 string:
128                         To be parsed.
129                 RETURNS:
130                         List of warning messages.
131                 DESCRIPTION:
132                         Parse customize string.
133
134   (canna-query-mode)
135                 RETURNS:
136                         A string which indicate the current mode.
137                 DESCRIPTION:
138                         Get current mode string.
139
140   Functions below are used for KKCP compatible library.  These
141   functions provides a base kana-to-kanji conversion system for EGG.
142   These functions may be used when users want to change the engine
143   from Wnn to Canna without changing user interface of Japanese input.
144
145   (canna-henkan-begin)
146   (canna-henkan-next)
147   (canna-bunsetu-henkou)
148   (canna-henkan-kakutei)
149   (canna-henkan-end)
150   (canna-henkan-quit)
151
152  */
153
154 #include <config.h>
155 #include "lisp.h"
156
157 #include "buffer.h"
158 #include "file-coding.h"
159
160 #ifdef CANNA2
161 #define IROHA_BC
162 #include "canna/jrkanji.h"
163 #include "canna/RK.h"
164 #else /* !CANNA2 */
165 #include "iroha/jrkanji.h"
166 #include "iroha/RK.h"
167 #endif /* !CANNA2 */
168 extern char *jrKanjiError;
169
170 /* #### is this global really necessary? */
171 #define KEYTOSTRSIZE 2048
172 static unsigned char key_buffer[KEYTOSTRSIZE];
173 static char **warning;
174
175 static int canna_empty_info, canna_through_info;
176 static int canna_underline;
177 static int canna_inhibit_hankakukana;
178
179 static Lisp_Object Vcanna_kakutei_string;
180 static Lisp_Object Vcanna_kakutei_yomi;
181 static Lisp_Object Vcanna_kakutei_romaji;
182 static Lisp_Object Vcanna_henkan_string;
183 static Fixnum   canna_henkan_length;
184 static Fixnum   canna_henkan_revPos;
185 static Fixnum   canna_henkan_revLen;
186 static Lisp_Object Vcanna_ichiran_string;
187 static Fixnum   canna_ichiran_length;
188 static Fixnum   canna_ichiran_revPos;
189 static Fixnum   canna_ichiran_revLen;
190 static Lisp_Object Vcanna_mode_string;
191
192 static int IRCP_context;
193
194 static Lisp_Object storeResults (unsigned char *, int, jrKanjiStatus *);
195 static Lisp_Object kanjiYomiList (int, int);
196 static Lisp_Object CANNA_mode_keys (void);
197
198 #ifdef CANNA_MULE
199 static void m2c (unsigned char *, int, unsigned char *);
200 static Lisp_Object mule_make_string (unsigned char *, int);
201 static int mule_strlen (unsigned char *, int);
202 static void count_char (unsigned char *,int, int, int, Fixnum *, Fixnum *, Fixnum *);
203 #define make_string mule_make_string
204 #endif
205
206 /* Lisp functions definition */
207
208 DEFUN ("canna-key-proc", Fcanna_key_proc, 1, 1, 0, /*
209 Translate a key input to a set of strings.  The strings contain both
210 well-formed string and intermediate result to show the translation
211 information to a user.  Converted strings are stored in specific
212 variables.
213 */
214        (ch))
215 {
216   jrKanjiStatus ks;
217   int len;
218
219   CHECK_CHAR_COERCE_INT (ch);
220   len = jrKanjiString (0, XCHAR (ch), key_buffer, KEYTOSTRSIZE, &ks);
221   return storeResults (key_buffer, len, &ks);
222 }
223
224 static Lisp_Object
225 storeResults (unsigned char *buf, int len, jrKanjiStatus *ks)
226 {
227   Lisp_Object val = Qnil;
228
229   if (len < 0)
230     { /* Error detected */
231       val = make_string ((unsigned char*) jrKanjiError, strlen (jrKanjiError));
232     }
233   else
234     {
235       /* ³ÎÄꤷ¤¿Ê¸»úÎó (the confirmed string) */
236       Vcanna_kakutei_string = make_string (buf, len);
237       val = make_int (len);
238       /* ³ÎÄꤷ¤¿Ê¸»úÎó¤ÎÆɤߤξðÊó...
239          (info about the reading of the confirmed string) */
240       Vcanna_kakutei_yomi = Vcanna_kakutei_romaji = Qnil;
241       if (ks->info & KanjiYomiInfo)
242         {
243           unsigned char *p = buf + len + 1;
244           int yomilen = strlen (p);
245
246           if (len + yomilen + 1 < KEYTOSTRSIZE)
247             {
248               int yomilen2;
249
250               Vcanna_kakutei_yomi = make_string (p, yomilen); /* Æɤß
251                                                                  (reading) */
252               p += yomilen + 1;
253               yomilen2 = strlen (p);
254               if (len + yomilen + yomilen2 + 2 < KEYTOSTRSIZE)
255                 {
256                   Vcanna_kakutei_romaji = make_string (p, yomilen2);
257                                 /* ¥í¡¼¥Þ»ú (romanization) */
258                 }
259             }
260         }
261
262
263       /* ¸õÊäɽ¼¨¤Îʸ»úÎó¤Ç¤¹¡£
264          (string for displaying candidate translations) */
265       Vcanna_henkan_string = Qnil;
266       if (ks->length >= 0)
267         {
268           Vcanna_henkan_string = make_string (ks->echoStr, ks->length);
269 #ifndef CANNA_MULE
270           canna_henkan_length = ks->length;
271           canna_henkan_revPos = ks->revPos;
272           canna_henkan_revLen = ks->revLen;
273 #else /* CANNA_MULE */
274           if (canna_underline)
275             {
276               canna_henkan_length = mule_strlen (ks->echoStr,ks->length);
277               canna_henkan_revPos = mule_strlen (ks->echoStr,ks->revPos);
278               canna_henkan_revLen = mule_strlen (ks->echoStr+ks->revPos,
279                                                  ks->revLen);
280             }
281           else
282             {
283               count_char (ks->echoStr, ks->length, ks->revPos, ks->revLen,
284                           &canna_henkan_length, &canna_henkan_revPos,
285                           &canna_henkan_revLen);
286             }
287 #endif /* CANNA_MULE */
288         }
289
290       /* °ìÍ÷¤Î¾ðÊó (information about the echo area menu) */
291       Vcanna_ichiran_string = Qnil;
292       if (ks->info & KanjiGLineInfo && ks->gline.length >= 0)
293         {
294           Vcanna_ichiran_string = make_string (ks->gline.line,
295                                                ks->gline.length);
296 #ifndef CANNA_MULE
297           canna_ichiran_length = ks->gline.length;
298           canna_ichiran_revPos = ks->gline.revPos;
299           canna_ichiran_revLen = ks->gline.revLen;
300 #else /* CANNA_MULE */
301           count_char (ks->gline.line, ks->gline.length,
302                       ks->gline.revPos, ks->gline.revLen,
303                       &canna_ichiran_length,
304                       &canna_ichiran_revPos, &canna_ichiran_revLen);
305 #endif /* CANNA_MULE */
306         }
307
308       /* ¥â¡¼¥É¤Î¾ðÊó (mode information) */
309       Vcanna_mode_string = Qnil;
310       if (ks->info & KanjiModeInfo)
311         {
312           Vcanna_mode_string = make_string (ks->mode, strlen (ks->mode));
313         }
314
315       /* ¤½¤Î¾¤Î¾ðÊó (other information) */
316       canna_empty_info = (ks->info & KanjiEmptyInfo) ? 1 : 0;
317       canna_through_info = (ks->info & KanjiThroughInfo) ? 1 : 0;
318     }
319
320   return val;
321 }
322
323 DEFUN ("canna-set-bunsetsu-kugiri", Fcanna_set_bunsetsu, 0, 1, 0, /*
324 This function sets the clause separator.
325 If non-nil value is specified, the white space separator will be used.
326 No separator will be used otherwise.
327 */
328        (num))
329 {
330   int kugiri; /* Ê¸Àá¶èÀÚ¤ê¤ò¤¹¤ë¤«¡© (display clause separator?) */
331
332   kugiri = NILP (num) ? 0 : 1;
333
334   jrKanjiControl (0, KC_SETBUNSETSUKUGIRI, (char *) kugiri);
335
336   return Qnil;
337 }
338
339 /* For whatever reason, calling Fding directly from libCanna loses */
340 static void
341 call_Fding (void)
342 {
343   Fding (Qnil, Qnil, Qnil);
344 }
345
346 DEFUN ("canna-initialize", Fcanna_initialize, 0, 3, 0, /*
347 Initialize ``canna'', which is a kana-to-kanji converter for GNU Emacs.
348 The first arg specifies if inserting space character between BUNSETSU when
349 candidates are displayed.
350 The second arg specifies server.
351 The third arg specifies a file which will be used as a customization
352 description.
353 If nil is specified for each arg, the default value will be used.
354 */
355        (num, server, rcfile))
356 {
357   Lisp_Object val;
358   int res;
359   unsigned char **p, **q;
360
361   int kugiri; /* Ê¸Àá¶èÀÚ¤ê¤ò¤¹¤ë¤«¡© (display clause separator?) */
362
363   IRCP_context = -1;
364
365   if (NILP (num))
366     {
367       kugiri = 1;
368     }
369   else
370     {
371       CHECK_INT (num);
372       kugiri = XINT (num);
373       kugiri = (kugiri == 1) ? 1 : 0;
374     }
375
376   if (NILP (server))
377     {
378       jrKanjiControl (0, KC_SETSERVERNAME, (char *) 0);
379     }
380   else
381     {
382       char servername[256];
383
384       CHECK_STRING (server);
385       strncpy (servername, XSTRING_DATA (server), XSTRING_LENGTH (server));
386       servername[XSTRING_LENGTH (server)] = '\0';
387       jrKanjiControl (0, KC_SETSERVERNAME, servername);
388     }
389
390   if (NILP (rcfile))
391     {
392       jrKanjiControl (0, KC_SETINITFILENAME, (char *) 0);
393     }
394   else
395     {
396       char rcname[256];
397
398       CHECK_STRING (rcfile);
399       strncpy (rcname, XSTRING_DATA (rcfile), XSTRING_LENGTH (rcfile));
400       rcname[XSTRING_LENGTH (rcfile)] = '\0';
401       jrKanjiControl (0, KC_SETINITFILENAME, rcname);
402     }
403
404   warning = (char **) 0;
405 #ifdef nec_ews_svr4
406   stop_polling ();
407 #endif /* nec_ews_svr4 */
408   res = jrKanjiControl (0, KC_INITIALIZE, (char *)&warning);
409 #ifdef nec_ews_svr4
410   start_polling ();
411 #endif /* nec_ews_svr4 */
412   val = Qnil;
413   if (warning)
414     {
415       for (p = q = (unsigned char **) warning ; *q ; q++)
416         ;
417       while (p < q)
418         {
419           q--;
420           val = Fcons (make_string (*q, strlen (*q)), val);
421         }
422     }
423   val = Fcons (val, Qnil);
424
425   if (res == -1)
426     {
427       val = Fcons (make_string ((unsigned char*) jrKanjiError,
428                                 strlen (jrKanjiError)), val);
429       /* ¥¤¥Ë¥·¥ã¥é¥¤¥º¤Ç¼ºÇÔ¤·¤¿¾ì¹ç¡£ (on initialization failure) */
430       return Fcons (Qnil, val);
431     }
432   else
433     {
434       extern void (*jrBeepFunc) (void);
435
436       jrBeepFunc = call_Fding;
437
438 #ifdef KC_SETAPPNAME
439 #ifndef CANNA_MULE
440       wcKanjiControl (0, KC_SETAPPNAME, "nemacs");
441 #else /* CANNA_MULE */
442       wcKanjiControl (0, KC_SETAPPNAME, "mule");
443 #endif /* CANNA_MULE */
444 #endif /* KC_SETAPPNAME */
445
446       jrKanjiControl (0, KC_SETBUNSETSUKUGIRI, (char *) kugiri);
447       jrKanjiControl (0, KC_SETWIDTH, (char *) 78);
448 #ifndef CANNA_MULE
449       jrKanjiControl (0, KC_INHIBITHANKAKUKANA, (char *) 1);
450 #else
451       /* mule ¤À¤Ã¤¿¤éȾ³Ñ¥«¥¿¥«¥Ê¤â»È¤¨¤ë
452          (Mule can use half-width katakana) */
453       if (canna_inhibit_hankakukana)
454         jrKanjiControl (0, KC_INHIBITHANKAKUKANA, (char *) 1);
455 #endif
456       jrKanjiControl (0, KC_YOMIINFO, (char *) 2); /* ¢¨£²: ¥í¡¼¥Þ»ú¤Þ¤ÇÊÖ¤¹
457                                                       (*2: return to
458                                                       romanized form) */
459       val = Fcons (Qnil, val);
460       return Fcons (CANNA_mode_keys (), val);
461     }
462 }
463
464 DEFUN ("canna-finalize", Fcanna_finalize, 0, 0, 0, /*
465 finalize ``canna'', which is a kana-to-kanji converter for GNU Emacs.
466 This cause to write miscellaneous informations to kana-to-kanji dictionary.
467 */
468        ())
469 {
470   Lisp_Object val;
471   unsigned char **p;
472
473   jrKanjiControl (0, KC_FINALIZE, (char *)&warning);
474
475   val = Qnil;
476   if (warning)
477     {
478       for (p = (unsigned char**) warning ; *p ; p++)
479         {
480           val = Fcons (make_string (*p, strlen (*p)), val);
481         }
482     }
483   val = Fcons (val, Qnil);
484   IRCP_context = -1;
485   return val;
486 }
487
488 DEFUN ("canna-touroku-string", Fcanna_touroku_string, 1, 1, 0, /*
489 Register Kanji words into kana-to-kanji conversion dictionary.
490 */
491        (str))
492 {
493   jrKanjiStatusWithValue ksv;
494   jrKanjiStatus ks;
495   int len;
496   Lisp_Object val;
497 #ifdef CANNA_MULE
498   unsigned char cbuf[4096];
499 #endif
500
501   CHECK_STRING (str);
502   ksv.buffer = (unsigned char *) key_buffer;
503   ksv.bytes_buffer = KEYTOSTRSIZE;
504 #ifndef CANNA_MULE
505   ks.echoStr = XSTRING_DATA (str);
506   ks.length = XSTRING_LENGTH (str);
507 #else /* CANNA_MULE */
508   m2c (XSTRING_DATA (str), XSTRING_LENGTH (str), cbuf);
509   ks.echoStr = cbuf;
510   ks.length = strlen (cbuf);
511 #endif /* CANNA_MULE */
512   ksv.ks = &ks;
513   len = jrKanjiControl (0, KC_DEFINEKANJI, (char *)&ksv);
514   val = storeResults (key_buffer, ksv.val, ksv.ks);
515   return val;
516 }
517
518 DEFUN ("canna-set-width", Fcanna_set_width, 1, 1, 0, /*
519 Set status-line width information, which is used to display
520 kanji candidates.
521 */
522        (num))
523 {
524   CHECK_INT (num);
525
526   jrKanjiControl (0, KC_SETWIDTH,  (char *) XINT (num));
527   return Qnil;
528 }
529
530 DEFUN ("canna-change-mode", Fcanna_change_mode, 1, 1, 0, /*
531 Change Japanese pre-edit mode.
532 */
533        (num))
534 {
535   jrKanjiStatusWithValue ksv;
536   jrKanjiStatus ks;
537   Lisp_Object val;
538
539   CHECK_INT (num);
540
541   ksv.buffer = (unsigned char *) key_buffer;
542   ksv.bytes_buffer = KEYTOSTRSIZE;
543   ksv.ks = &ks;
544   ksv.val = XINT (num);
545   jrKanjiControl (0, KC_CHANGEMODE,  (char *)&ksv);
546   val = storeResults (key_buffer, ksv.val, ksv.ks);
547   return val;
548 }
549
550 static Lisp_Object
551 CANNA_mode_keys (void)
552 {
553 #define CANNAWORKBUFSIZE 32
554   char xxx[CANNAWORKBUFSIZE];
555   Lisp_Object val;
556   int i, n;
557
558   n = jrKanjiControl (0, KC_MODEKEYS, xxx);
559   val = Qnil;
560   for (i = n ; i > 0 ;)
561     {
562       --i;
563       /* !!#### something fucked here */
564       val = Fcons (make_char ((int)(0xFF & (unsigned char) xxx[i])), val);
565     }
566   return val;
567 }
568
569 DEFUN ("canna-store-yomi", Fcanna_store_yomi, 1, 2, 0, /*
570 Store yomi characters as a YOMI of kana-to-kanji conversion.
571 */
572        (yomi, roma))
573 {
574   jrKanjiStatusWithValue ksv;
575   jrKanjiStatus ks;
576
577   CHECK_STRING (yomi);
578 #ifndef CANNA_MULE
579   strncpy (key_buffer, XSTRING_DATA (yomi), XSTRING_LENGTH (yomi));
580   ks.length = XSTRING_LENGTH (yomi);
581   key_buffer[ks.length] = '\0';
582 #else /* CANNA_MULE */
583   m2c (XSTRING_DATA (yomi), XSTRING_LENGTH (yomi), key_buffer);
584   ks.length = strlen (key_buffer);
585 #endif /* CANNA_MULE */
586
587   if (NILP (roma))
588     {
589       ks.mode = 0;
590     }
591   else
592     {
593       CHECK_STRING (roma);
594
595 #ifndef CANNA_MULE
596       strncpy (key_buffer + XSTRING_LENGTH (yomi) + 1, XSTRING_DATA (roma),
597                XSTRING_LENGTH (roma));
598       key_buffer[XSTRING_LENGTH (yomi) + 1 + XSTRING_LENGTH (roma)] = '\0';
599       ks.mode = (unsigned char *)(key_buffer + XSTRING_LENGTH (yomi) + 1);
600 #else /* CANNA_MULE */
601       ks.mode = (unsigned char *)(key_buffer + ks.length + 1);
602       m2c (XSTRING_DATA (roma), XSTRING_LENGTH (roma), ks.mode);
603 #endif /* CANNA_MULE */
604     }
605
606   ks.echoStr = (unsigned char *) key_buffer;
607   ksv.buffer = (unsigned char *) key_buffer; /* ÊÖÃÍÍÑ (return value) */
608   ksv.bytes_buffer = KEYTOSTRSIZE;
609   ksv.ks = &ks;
610
611   jrKanjiControl (0, KC_STOREYOMI, (char *)&ksv);
612
613   return storeResults (key_buffer, ksv.val, ksv.ks);
614 }
615
616 DEFUN ("canna-do-function", Fcanna_do_function, 1, 2, 0, /*
617 Do specified function at current mode.
618 */
619        (num, ch))
620 {
621   jrKanjiStatusWithValue ksv;
622   jrKanjiStatus ks;
623   Lisp_Object val;
624
625   CHECK_INT (num);
626
627   if (NILP (ch))
628     {
629       *key_buffer = '@';
630     }
631   else
632     {
633       CHECK_CHAR (ch);
634       *key_buffer = XCHAR (ch);
635     }
636
637   ksv.buffer = (unsigned char *) key_buffer;
638   ksv.bytes_buffer = KEYTOSTRSIZE;
639   ksv.ks = &ks;
640   ksv.val = XINT (num);
641   jrKanjiControl (0, KC_DO, (char *) &ksv);
642   val = storeResults (key_buffer, ksv.val, ksv.ks);
643   return val;
644 }
645
646 DEFUN ("canna-parse", Fcanna_parse, 1, 1, 0, /*
647 Parse customize string.
648 */
649        (str))
650 {
651   Lisp_Object val;
652   unsigned char **p;
653   int n;
654
655   CHECK_STRING (str);
656
657 #ifndef CANNA_MULE
658   strncpy (key_buffer, XSTRING_DATA (str), XSTRING_LENGTH (str));
659   key_buffer[XSTRING_LENGTH (str)] = '\0';
660 #else /* CANNA_MULE */
661   m2c (XSTRING_DATA (str), XSTRING_LENGTH (str), key_buffer);
662 #endif /* CANNA_MULE */
663   p = (unsigned char**) key_buffer;
664   n = jrKanjiControl (0, KC_PARSE,  (char *) &p);
665   val = Qnil;
666   while (n > 0)
667     {
668       n--;
669       val = Fcons (make_string (p[n], strlen (p[n])), val);
670     }
671   return val;
672 }
673
674 DEFUN ("canna-query-mode", Fcanna_query_mode, 0, 0, 0, /*
675 Get current mode string.
676 */
677        ())
678 {
679   unsigned char buf[256];
680
681   jrKanjiControl (0, KC_QUERYMODE, buf);
682   return make_string (buf, strlen (buf));
683 }
684
685 /*
686  * Functions following this line are for KKCP interface compatible
687  * library.  These functions may be used by MILK system.
688  */
689
690 #define RKBUFSIZE 1024
691
692 static unsigned char yomibuf[RKBUFSIZE];
693 static short kugiri[RKBUFSIZE / 2];
694
695 static int
696 confirmContext (void)
697 {
698   if (IRCP_context < 0)
699     {
700       int context;
701
702       if ((context = jrKanjiControl (0, KC_GETCONTEXT, (char *) 0)) == -1)
703         {
704           return 0;
705         }
706       IRCP_context = context;
707     }
708   return 1;
709 }
710
711 static int
712 byteLen (int bun, int len)
713 {
714   int i = 0, offset = 0, ch;
715
716   if (0 <= bun && bun < RKBUFSIZE)
717     {
718       offset = kugiri[bun];
719     }
720
721   while (len-- > 0 && (ch = (int) yomibuf[offset + i]))
722     {
723       i++;
724       if (ch & 0x80)
725         {
726           i++;
727         }
728     }
729   return i;
730 }
731
732 DEFUN ("canna-henkan-begin", Fcanna_henkan_begin, 1, 1, 0, /*
733 Return the result of kana-to-kanji conversion.
734 Clause separator is set.
735 */
736        (yomi))
737 {
738   int nbun;
739
740   CHECK_STRING (yomi);
741   if (confirmContext () == 0)
742     {
743       return Qnil;
744     }
745 #ifndef CANNA_MULE
746   strncpy (yomibuf, XSTRING_DATA (yomi), XSTRING_LENGTH (yomi));
747   yomibuf[XSTRING_LENGTH (yomi)] = '\0';
748   nbun = RkBgnBun (IRCP_context, XSTRING_DATA (yomi), XSTRING_LENGTH (yomi),
749                    (RK_XFER << RK_XFERBITS) | RK_KFER);
750 #else /* CANNA_MULE */
751   m2c (XSTRING_DATA (yomi), XSTRING_LENGTH (yomi), yomibuf);
752   nbun = RkBgnBun (IRCP_context, (char *) yomibuf, strlen (yomibuf),
753                    (RK_XFER << RK_XFERBITS) | RK_KFER);
754 #endif /* CANNA_MULE */
755
756   return kanjiYomiList (IRCP_context, nbun);
757 }
758
759 static Lisp_Object
760 kanjiYomiList (int context, int nbun)
761 {
762   Lisp_Object val, res = Qnil;
763   unsigned char RkBuf[RKBUFSIZE];
764   int len, i, total;
765
766   for (i = nbun ; i > 0 ; )
767     {
768       i--;
769       RkGoTo (context, i);
770       len = RkGetKanji (context, RkBuf, RKBUFSIZE);
771       val = make_string (RkBuf, len);
772       len = RkGetYomi (context, RkBuf, RKBUFSIZE);
773       res = Fcons (Fcons (val, make_string (RkBuf, len)), res);
774       if (i < RKBUFSIZE / 2)
775         {
776           kugiri[i] = len;
777         }
778     }
779   for (i = 0, total = 0 ; i < nbun ; i++)
780     {
781       int temp = kugiri[i];
782       kugiri[i] = total;
783       total += temp;
784     }
785   return res;
786 }
787
788 DEFUN ("canna-henkan-next", Fcanna_henkan_next, 1, 1, 0, /*
789 Return the list of candidates.
790 */
791        (bunsetsu))
792 {
793   int i, slen, len;
794   unsigned char *p, RkBuf[RKBUFSIZE];
795   Lisp_Object res = Qnil, endp;
796
797   CHECK_INT (bunsetsu);
798   if (confirmContext () == 0)
799     {
800       return Qnil;
801     }
802   RkGoTo (IRCP_context, XINT (bunsetsu));
803   len = RkGetKanjiList (IRCP_context, RkBuf, RKBUFSIZE);
804   p = RkBuf;
805   for (i = 0 ; i < len ; i++)
806     {
807       slen = strlen (p);
808       if (NILP(res))
809         {
810           endp = res = Fcons (make_string (p, slen), Qnil);
811         }
812       else
813         {
814           endp = XCDR (res) = Fcons (make_string (p, slen), Qnil);
815         }
816       p += slen + 1;
817     }
818   return res;
819 }
820
821 DEFUN ("canna-bunsetu-henkou", Fcanna_bunsetu_henkou, 2, 2, 0, /*
822 Specify the length of a clause.
823 */
824        (bunsetsu, bunlen))
825 {
826   int nbun, len;
827
828   CHECK_INT (bunsetsu);
829   CHECK_INT (bunlen);
830
831   nbun = XINT (bunsetsu);
832   if (confirmContext () == 0)
833     {
834       return Qnil;
835     }
836   RkGoTo (IRCP_context, nbun);
837   len = byteLen (nbun, XINT (bunlen));
838   return kanjiYomiList (IRCP_context, RkResize (IRCP_context, len));
839 }
840
841 DEFUN ("canna-henkan-kakutei", Fcanna_henkan_kakutei, 2, 2, 0, /*
842 Select a candidate.
843 */
844        (bun, kouho))
845 {
846   int nbun, nkouho;
847
848   if (confirmContext () == 0)
849     {
850       return Qnil;
851     }
852   nbun = XINT(bun);
853   RkGoTo (IRCP_context, nbun);
854
855   nkouho = XINT(kouho);
856   RkXfer (IRCP_context, nkouho);
857   return Qt;
858 }
859
860 DEFUN ("canna-henkan-end", Fcanna_henkan_end, 0, 0, 0, /*
861 End conversion.
862 */
863        ())
864 {
865   if (confirmContext () == 0)
866     {
867       return Qnil;
868     }
869   RkEndBun (IRCP_context, 1); /* ³Ø½¬¤Ï¤¤¤Ä¤Ç¤â¹Ô¤Ã¤ÆÎɤ¤¤â¤Î¤Ê¤Î¤«¡©
870                                  (is it OK to invoke learning function
871                                  at arbitrary times?) */
872   return Qt;
873 }
874
875 DEFUN ("canna-henkan-quit", Fcanna_henkan_quit, 0, 0, 0, /*
876 Quit conversion.
877 */
878        ())
879 {
880   if (confirmContext () == 0)
881     {
882       return Qnil;
883     }
884   RkEndBun (IRCP_context, 0);
885   return Qt;
886 }
887
888 /* variables below this line is constants of Canna */
889
890 static Fixnum canna_mode_AlphaMode;
891 static Fixnum canna_mode_EmptyMode;
892 static Fixnum canna_mode_KigoMode;
893 static Fixnum canna_mode_YomiMode;
894 static Fixnum canna_mode_JishuMode;
895 static Fixnum canna_mode_TankouhoMode;
896 static Fixnum canna_mode_IchiranMode;
897 static Fixnum canna_mode_YesNoMode;
898 static Fixnum canna_mode_OnOffMode;
899 #ifdef CANNA_MODE_AdjustBunsetsuMode
900 static Fixnum canna_mode_AdjustBunsetsuMode;
901 #endif
902 #ifdef CANNA_MODE_ChikujiYomiMode
903 static Fixnum canna_mode_ChikujiYomiMode;
904 static Fixnum canna_mode_ChikujiTanMode;
905 #endif
906
907 static Fixnum canna_mode_HenkanMode;
908 #ifdef CANNA_MODE_HenkanNyuryokuMode
909 static Fixnum canna_mode_HenkanNyuryokuMode;
910 #endif
911 #ifdef CANNA_MODE_ZenHiraHenkanMode
912 static Fixnum canna_mode_ZenHiraHenkanMode;
913 #ifdef CANNA_MODE_HanHiraHenkanMode
914 static Fixnum canna_mode_HanHiraHenkanMode;
915 #endif
916 static Fixnum canna_mode_ZenKataHenkanMode;
917 static Fixnum canna_mode_HanKataHenkanMode;
918 static Fixnum canna_mode_ZenAlphaHenkanMode;
919 static Fixnum canna_mode_HanAlphaHenkanMode;
920 #endif
921 static Fixnum canna_mode_ZenHiraKakuteiMode;
922 #ifdef CANNA_MODE_HanHiraKakuteiMode
923 static Fixnum canna_mode_HanHiraKakuteiMode;
924 #endif
925 static Fixnum canna_mode_ZenKataKakuteiMode;
926 static Fixnum canna_mode_HanKataKakuteiMode;
927 static Fixnum canna_mode_ZenAlphaKakuteiMode;
928 static Fixnum canna_mode_HanAlphaKakuteiMode;
929 static Fixnum canna_mode_HexMode;
930 static Fixnum canna_mode_BushuMode;
931 static Fixnum canna_mode_ExtendMode;
932 static Fixnum canna_mode_RussianMode;
933 static Fixnum canna_mode_GreekMode;
934 static Fixnum canna_mode_LineMode;
935 static Fixnum canna_mode_ChangingServerMode;
936 static Fixnum canna_mode_HenkanMethodMode;
937 static Fixnum canna_mode_DeleteDicMode;
938 static Fixnum canna_mode_TourokuMode;
939 static Fixnum canna_mode_TourokuEmptyMode;
940 static Fixnum canna_mode_TourokuHinshiMode;
941 static Fixnum canna_mode_TourokuDicMode;
942 static Fixnum canna_mode_QuotedInsertMode;
943 static Fixnum canna_mode_BubunMuhenkanMode;
944 static Fixnum canna_mode_MountDicMode;
945
946 static Fixnum canna_fn_SelfInsert;
947 static Fixnum canna_fn_FunctionalInsert;
948 static Fixnum canna_fn_QuotedInsert;
949 static Fixnum canna_fn_JapaneseMode;
950 static Fixnum canna_fn_AlphaMode;
951 static Fixnum canna_fn_HenkanNyuryokuMode;
952 static Fixnum canna_fn_Forward;
953 static Fixnum canna_fn_Backward;
954 static Fixnum canna_fn_Next;
955 static Fixnum canna_fn_Prev;
956 static Fixnum canna_fn_BeginningOfLine;
957 static Fixnum canna_fn_EndOfLine;
958 static Fixnum canna_fn_DeleteNext;
959 static Fixnum canna_fn_DeletePrevious;
960 static Fixnum canna_fn_KillToEndOfLine;
961 static Fixnum canna_fn_Henkan;
962 static Fixnum canna_fn_Kakutei;
963 static Fixnum canna_fn_Extend;
964 static Fixnum canna_fn_Shrink;
965 #ifdef CANNA_FN_AdjustBunsetsu
966 static Fixnum canna_fn_AdjustBunsetsu;
967 #endif
968 static Fixnum canna_fn_Quit;
969 static Fixnum canna_fn_ConvertAsHex;
970 static Fixnum canna_fn_ConvertAsBushu;
971 static Fixnum canna_fn_KouhoIchiran;
972 static Fixnum canna_fn_BubunMuhenkan;
973 static Fixnum canna_fn_Zenkaku;
974 static Fixnum canna_fn_Hankaku;
975 static Fixnum canna_fn_ToUpper;
976 static Fixnum canna_fn_Capitalize;
977 static Fixnum canna_fn_ToLower;
978 static Fixnum canna_fn_Hiragana;
979 static Fixnum canna_fn_Katakana;
980 static Fixnum canna_fn_Romaji;
981 #ifdef CANNA_FN_BaseHiragana
982 static Fixnum canna_fn_BaseHiragana;
983 static Fixnum canna_fn_BaseKatakana;
984 static Fixnum canna_fn_BaseEisu;
985 static Fixnum canna_fn_BaseZenkaku;
986 static Fixnum canna_fn_BaseHankaku;
987 static Fixnum canna_fn_BaseKana;
988 static Fixnum canna_fn_BaseKakutei;
989 static Fixnum canna_fn_BaseHenkan;
990 static Fixnum canna_fn_BaseHiraKataToggle;
991 static Fixnum canna_fn_BaseZenHanToggle;
992 static Fixnum canna_fn_BaseKanaEisuToggle;
993 static Fixnum canna_fn_BaseKakuteiHenkanToggle;
994 static Fixnum canna_fn_BaseRotateForward;
995 static Fixnum canna_fn_BaseRotateBackward;
996 #endif
997 static Fixnum canna_fn_ExtendMode;
998 static Fixnum canna_fn_Touroku;
999 static Fixnum canna_fn_HexMode;
1000 static Fixnum canna_fn_BushuMode;
1001 static Fixnum canna_fn_KigouMode;
1002 #ifdef CANNA_FN_Mark
1003 static Fixnum canna_fn_Mark;
1004 #endif
1005 #ifdef CANNA_FN_TemporalMode
1006 static Fixnum canna_fn_TemporalMode;
1007 #endif
1008
1009 static Fixnum canna_key_Nfer;
1010 static Fixnum canna_key_Xfer;
1011 static Fixnum canna_key_Up;
1012 static Fixnum canna_key_Left;
1013 static Fixnum canna_key_Right;
1014 static Fixnum canna_key_Down;
1015 static Fixnum canna_key_Insert;
1016 static Fixnum canna_key_Rollup;
1017 static Fixnum canna_key_Rolldown;
1018 static Fixnum canna_key_Home;
1019 static Fixnum canna_key_Help;
1020 static Fixnum canna_key_KP_Key;
1021 static Fixnum canna_key_Shift_Nfer;
1022 static Fixnum canna_key_Shift_Xfer;
1023 static Fixnum canna_key_Shift_Up;
1024 static Fixnum canna_key_Shift_Left;
1025 static Fixnum canna_key_Shift_Right;
1026 static Fixnum canna_key_Shift_Down;
1027 static Fixnum canna_key_Cntrl_Nfer;
1028 static Fixnum canna_key_Cntrl_Xfer;
1029 static Fixnum canna_key_Cntrl_Up;
1030 static Fixnum canna_key_Cntrl_Left;
1031 static Fixnum canna_key_Cntrl_Right;
1032 static Fixnum canna_key_Cntrl_Down;
1033
1034 Lisp_Object VCANNA; /* by MORIOKA Tomohiko <morioka@jaist.ac.jp>
1035                           1996/6/7 */
1036
1037 void
1038 syms_of_mule_canna (void)
1039 {
1040   DEFSUBR (Fcanna_key_proc);
1041   DEFSUBR (Fcanna_initialize);
1042   DEFSUBR (Fcanna_finalize);
1043   DEFSUBR (Fcanna_touroku_string);
1044   DEFSUBR (Fcanna_set_width);
1045   DEFSUBR (Fcanna_change_mode);
1046   DEFSUBR (Fcanna_store_yomi);
1047   DEFSUBR (Fcanna_do_function);
1048   DEFSUBR (Fcanna_parse);
1049   DEFSUBR (Fcanna_query_mode);
1050   DEFSUBR (Fcanna_set_bunsetsu);
1051
1052   DEFSUBR (Fcanna_henkan_begin);
1053   DEFSUBR (Fcanna_henkan_next);
1054   DEFSUBR (Fcanna_bunsetu_henkou);
1055   DEFSUBR (Fcanna_henkan_kakutei);
1056   DEFSUBR (Fcanna_henkan_end);
1057   DEFSUBR (Fcanna_henkan_quit);
1058 }
1059
1060 void
1061 vars_of_mule_canna (void)
1062 {
1063   DEFVAR_LISP ("CANNA", &VCANNA);               /* hir@nec, 1992.5.21 */
1064   VCANNA = Qt;                                  /* hir@nec, 1992.5.21 */
1065
1066   DEFVAR_LISP ("canna-kakutei-string", &Vcanna_kakutei_string /*
1067
1068 */ );
1069   Vcanna_kakutei_string = Qnil;
1070
1071   DEFVAR_LISP ("canna-kakutei-yomi",   &Vcanna_kakutei_yomi /*
1072
1073 */ );
1074   Vcanna_kakutei_yomi = Qnil;
1075
1076   DEFVAR_LISP ("canna-kakutei-romaji", &Vcanna_kakutei_romaji /*
1077
1078 */ );
1079   Vcanna_kakutei_romaji = Qnil;
1080
1081   DEFVAR_LISP ("canna-henkan-string",  &Vcanna_henkan_string /*
1082
1083 */ );
1084   Vcanna_henkan_string = Qnil;
1085
1086   DEFVAR_INT ("canna-henkan-length",  &canna_henkan_length /*
1087
1088 */ );
1089   canna_henkan_length = 0;
1090
1091   DEFVAR_INT ("canna-henkan-revpos",  &canna_henkan_revPos /*
1092
1093 */ );
1094   canna_henkan_revPos = 0;
1095
1096   DEFVAR_INT ("canna-henkan-revlen",  &canna_henkan_revLen /*
1097
1098 */ );
1099   canna_henkan_revLen = 0;
1100
1101   DEFVAR_LISP ("canna-ichiran-string", &Vcanna_ichiran_string /*
1102
1103 */ );
1104   Vcanna_ichiran_string = Qnil;
1105
1106   DEFVAR_INT ("canna-ichiran-length", &canna_ichiran_length /*
1107
1108 */ );
1109   canna_ichiran_length = 0;
1110
1111   DEFVAR_INT ("canna-ichiran-revpos", &canna_ichiran_revPos /*
1112
1113 */ );
1114   canna_ichiran_revPos = 0;
1115
1116   DEFVAR_INT ("canna-ichiran-revlen", &canna_ichiran_revLen /*
1117
1118 */ );
1119   canna_ichiran_revLen = 0;
1120
1121   DEFVAR_LISP ("canna-mode-string",    &Vcanna_mode_string /*
1122
1123 */ );
1124   Vcanna_mode_string = Qnil;
1125
1126   DEFVAR_BOOL ("canna-empty-info", &canna_empty_info /*
1127 For canna
1128 */ );
1129   canna_empty_info = 0;
1130
1131   DEFVAR_BOOL ("canna-through-info", &canna_through_info /*
1132 For canna
1133 */ );
1134   canna_through_info = 0;
1135
1136   DEFVAR_BOOL ("canna-underline", &canna_underline /*
1137 For canna
1138 */ );
1139   canna_underline = 0;
1140
1141   DEFVAR_BOOL ("canna-inhibit-hankakukana", &canna_inhibit_hankakukana /*
1142 For canna
1143 */ );
1144   canna_inhibit_hankakukana = 0;
1145
1146   DEFVAR_INT ("canna-mode-alpha-mode", &canna_mode_AlphaMode /*
1147
1148 */ );
1149   canna_mode_AlphaMode = IROHA_MODE_AlphaMode;
1150
1151   DEFVAR_INT ("canna-mode-empty-mode", &canna_mode_EmptyMode /*
1152
1153 */ );
1154   canna_mode_EmptyMode = IROHA_MODE_EmptyMode;
1155
1156   DEFVAR_INT ("canna-mode-kigo-mode",  &canna_mode_KigoMode /*
1157
1158 */ );
1159   canna_mode_KigoMode = IROHA_MODE_KigoMode;
1160
1161   DEFVAR_INT ("canna-mode-yomi-mode",  &canna_mode_YomiMode /*
1162
1163 */ );
1164   canna_mode_YomiMode = IROHA_MODE_YomiMode;
1165
1166   DEFVAR_INT ("canna-mode-jishu-mode", &canna_mode_JishuMode /*
1167
1168 */ );
1169   canna_mode_JishuMode = IROHA_MODE_JishuMode;
1170
1171   DEFVAR_INT ("canna-mode-tankouho-mode", &canna_mode_TankouhoMode /*
1172
1173 */ );
1174   canna_mode_TankouhoMode = IROHA_MODE_TankouhoMode;
1175
1176   DEFVAR_INT ("canna-mode-ichiran-mode",  &canna_mode_IchiranMode /*
1177
1178 */ );
1179   canna_mode_IchiranMode = IROHA_MODE_IchiranMode;
1180
1181   DEFVAR_INT ("canna-mode-yes-no-mode", &canna_mode_YesNoMode /*
1182
1183 */ );
1184   canna_mode_YesNoMode = IROHA_MODE_YesNoMode;
1185
1186   DEFVAR_INT ("canna-mode-on-off-mode", &canna_mode_OnOffMode /*
1187
1188 */ );
1189   canna_mode_OnOffMode = IROHA_MODE_OnOffMode;
1190
1191 #ifdef CANNA_MODE_AdjustBunsetsuMode
1192   DEFVAR_INT ("canna-mode-adjust-bunsetsu-mode",
1193               &canna_mode_AdjustBunsetsuMode /*
1194
1195 */ );
1196   canna_mode_AdjustBunsetsuMode = CANNA_MODE_AdjustBunsetsuMode;
1197 #endif
1198 #ifdef CANNA_MODE_ChikujiYomiMode
1199   DEFVAR_INT ("canna-mode-chikuji-yomi-mode", &canna_mode_ChikujiYomiMode /*
1200
1201 */ );
1202   canna_mode_ChikujiYomiMode = CANNA_MODE_ChikujiYomiMode;
1203
1204   DEFVAR_INT ("canna-mode-chikuji-bunsetsu-mode",
1205               &canna_mode_ChikujiTanMode /*
1206
1207 */ );
1208   canna_mode_ChikujiTanMode = CANNA_MODE_ChikujiTanMode;
1209 #endif
1210
1211   DEFVAR_INT ("canna-mode-henkan-mode", &canna_mode_HenkanMode /*
1212
1213 */ );
1214   canna_mode_HenkanMode = IROHA_MODE_HenkanMode;
1215
1216 #ifdef CANNA_MODE_HenkanNyuryokuMode
1217   DEFVAR_INT ("canna-mode-henkan-nyuuryoku-mode",
1218               &canna_mode_HenkanNyuryokuMode /*
1219
1220 */ );
1221   canna_mode_HenkanNyuryokuMode = CANNA_MODE_HenkanNyuryokuMode;
1222 #endif
1223 #ifdef CANNA_MODE_ZenHiraHenkanMode
1224   DEFVAR_INT ("canna-mode-zen-hira-henkan-mode",
1225               &canna_mode_ZenHiraHenkanMode /*
1226
1227 */ );
1228   canna_mode_ZenHiraHenkanMode = CANNA_MODE_ZenHiraHenkanMode;
1229 #ifdef CANNA_MODE_HanHiraHenkanMode
1230   DEFVAR_INT ("canna-mode-han-hira-henkan-mode",
1231               &canna_mode_HanHiraHenkanMode /*
1232
1233 */ );
1234   canna_mode_HanHiraHenkanMode = CANNA_MODE_HanHiraHenkanMode;
1235 #endif
1236   DEFVAR_INT ("canna-mode-zen-kata-henkan-mode",
1237               &canna_mode_ZenKataHenkanMode /*
1238
1239 */ );
1240   canna_mode_ZenKataHenkanMode = CANNA_MODE_ZenKataHenkanMode;
1241
1242   DEFVAR_INT ("canna-mode-han-kata-henkan-mode",
1243               &canna_mode_HanKataHenkanMode /*
1244
1245 */ );
1246   canna_mode_HanKataHenkanMode = CANNA_MODE_HanKataHenkanMode;
1247
1248   DEFVAR_INT ("canna-mode-zen-alpha-henkan-mode",
1249               &canna_mode_ZenAlphaHenkanMode /*
1250
1251 */ );
1252   canna_mode_ZenAlphaHenkanMode = CANNA_MODE_ZenAlphaHenkanMode;
1253
1254   DEFVAR_INT ("canna-mode-han-alpha-henkan-mode",
1255               &canna_mode_HanAlphaHenkanMode /*
1256
1257 */ );
1258   canna_mode_HanAlphaHenkanMode = CANNA_MODE_HanAlphaHenkanMode;
1259 #endif
1260   DEFVAR_INT ("canna-mode-zen-hira-kakutei-mode",
1261               &canna_mode_ZenHiraKakuteiMode /*
1262
1263 */ );
1264   canna_mode_ZenHiraKakuteiMode = IROHA_MODE_ZenHiraKakuteiMode;
1265 #ifdef CANNA_MODE_HanHiraKakuteiMode
1266   DEFVAR_INT ("canna-mode-han-hira-kakutei-mode",
1267               &canna_mode_HanHiraKakuteiMode /*
1268
1269 */ );
1270   canna_mode_HanHiraKakuteiMode = CANNA_MODE_HanHiraKakuteiMode;
1271 #endif
1272   DEFVAR_INT ("canna-mode-zen-kata-kakutei-mode",
1273               &canna_mode_ZenKataKakuteiMode /*
1274
1275 */ );
1276   canna_mode_ZenKataKakuteiMode = IROHA_MODE_ZenKataKakuteiMode;
1277
1278   DEFVAR_INT ("canna-mode-han-kata-kakutei-mode",
1279               &canna_mode_HanKataKakuteiMode /*
1280
1281 */ );
1282   canna_mode_HanKataKakuteiMode = IROHA_MODE_HanKataKakuteiMode;
1283
1284   DEFVAR_INT ("canna-mode-zen-alpha-kakutei-mode",
1285               &canna_mode_ZenAlphaKakuteiMode /*
1286
1287 */ );
1288   canna_mode_ZenAlphaKakuteiMode = IROHA_MODE_ZenAlphaKakuteiMode;
1289
1290   DEFVAR_INT ("canna-mode-han-alpha-kakutei-mode",
1291               &canna_mode_HanAlphaKakuteiMode /*
1292
1293 */ );
1294   canna_mode_HanAlphaKakuteiMode = IROHA_MODE_HanAlphaKakuteiMode;
1295
1296   DEFVAR_INT ("canna-mode-hex-mode", &canna_mode_HexMode /*
1297
1298 */ );
1299   canna_mode_HexMode = IROHA_MODE_HexMode;
1300
1301   DEFVAR_INT ("canna-mode-bushu-mode", &canna_mode_BushuMode /*
1302
1303 */ );
1304   canna_mode_BushuMode = IROHA_MODE_BushuMode;
1305
1306   DEFVAR_INT ("canna-mode-extend-mode", &canna_mode_ExtendMode /*
1307
1308 */ );
1309   canna_mode_ExtendMode = IROHA_MODE_ExtendMode;
1310
1311   DEFVAR_INT ("canna-mode-russian-mode", &canna_mode_RussianMode /*
1312
1313 */ );
1314   canna_mode_RussianMode = IROHA_MODE_RussianMode;
1315
1316   DEFVAR_INT ("canna-mode-greek-mode", &canna_mode_GreekMode /*
1317
1318 */ );
1319   canna_mode_GreekMode = IROHA_MODE_GreekMode;
1320
1321   DEFVAR_INT ("canna-mode-line-mode", &canna_mode_LineMode /*
1322
1323 */ );
1324   canna_mode_LineMode = IROHA_MODE_LineMode;
1325
1326   DEFVAR_INT ("canna-mode-changing-server-mode",
1327               &canna_mode_ChangingServerMode /*
1328
1329 */ );
1330   canna_mode_ChangingServerMode = IROHA_MODE_ChangingServerMode;
1331
1332   DEFVAR_INT ("canna-mode-henkan-method-mode",
1333               &canna_mode_HenkanMethodMode /*
1334
1335 */ );
1336   canna_mode_HenkanMethodMode = IROHA_MODE_HenkanMethodMode;
1337
1338   DEFVAR_INT ("canna-mode-delete-dic-mode", &canna_mode_DeleteDicMode /*
1339
1340 */ );
1341   canna_mode_DeleteDicMode = IROHA_MODE_DeleteDicMode;
1342
1343   DEFVAR_INT ("canna-mode-touroku-mode", &canna_mode_TourokuMode /*
1344
1345 */ );
1346   canna_mode_TourokuMode = IROHA_MODE_TourokuMode;
1347
1348   DEFVAR_INT ("canna-mode-touroku-empty-mode",
1349               &canna_mode_TourokuEmptyMode /*
1350
1351 */ );
1352   canna_mode_TourokuEmptyMode = IROHA_MODE_TourokuEmptyMode;
1353
1354   DEFVAR_INT ("canna-mode-touroku-hinshi-mode",
1355               &canna_mode_TourokuHinshiMode /*
1356
1357 */ );
1358   canna_mode_TourokuHinshiMode = IROHA_MODE_TourokuHinshiMode;
1359
1360   DEFVAR_INT ("canna-mode-touroku-dic-mode", &canna_mode_TourokuDicMode /*
1361
1362 */ );
1363   canna_mode_TourokuDicMode = IROHA_MODE_TourokuDicMode;
1364
1365   DEFVAR_INT ("canna-mode-quoted-insert-mode",
1366               &canna_mode_QuotedInsertMode /*
1367
1368 */ );
1369   canna_mode_QuotedInsertMode = IROHA_MODE_QuotedInsertMode;
1370
1371   DEFVAR_INT ("canna-mode-bubun-muhenkan-mode",
1372               &canna_mode_BubunMuhenkanMode /*
1373
1374 */ );
1375   canna_mode_BubunMuhenkanMode = IROHA_MODE_BubunMuhenkanMode;
1376
1377   DEFVAR_INT ("canna-mode-mount-dic-mode", &canna_mode_MountDicMode /*
1378
1379 */ );
1380   canna_mode_MountDicMode = IROHA_MODE_MountDicMode;
1381
1382   DEFVAR_INT ("canna-func-self-insert", &canna_fn_SelfInsert  /*
1383
1384 */ );
1385   canna_fn_SelfInsert = IROHA_FN_SelfInsert;
1386
1387   DEFVAR_INT ("canna-func-functional-insert", &canna_fn_FunctionalInsert  /*
1388
1389 */ );
1390   canna_fn_FunctionalInsert = IROHA_FN_FunctionalInsert;
1391
1392   DEFVAR_INT ("canna-func-quoted-insert", &canna_fn_QuotedInsert  /*
1393
1394 */ );
1395   canna_fn_QuotedInsert = IROHA_FN_QuotedInsert;
1396
1397   DEFVAR_INT ("canna-func-japanese-mode", &canna_fn_JapaneseMode  /*
1398
1399 */ );
1400   canna_fn_JapaneseMode = IROHA_FN_JapaneseMode;
1401
1402   DEFVAR_INT ("canna-func-alpha-mode", &canna_fn_AlphaMode  /*
1403
1404 */ );
1405   canna_fn_AlphaMode = IROHA_FN_AlphaMode;
1406
1407   DEFVAR_INT ("canna-func-henkan-nyuryoku-mode",
1408               &canna_fn_HenkanNyuryokuMode  /*
1409
1410 */ );
1411   canna_fn_HenkanNyuryokuMode = IROHA_FN_HenkanNyuryokuMode;
1412
1413   DEFVAR_INT ("canna-func-forward", &canna_fn_Forward  /*
1414
1415 */ );
1416   canna_fn_Forward = IROHA_FN_Forward;
1417
1418   DEFVAR_INT ("canna-func-backward", &canna_fn_Backward  /*
1419
1420 */ );
1421   canna_fn_Backward = IROHA_FN_Backward;
1422
1423   DEFVAR_INT ("canna-func-next", &canna_fn_Next  /*
1424
1425 */ );
1426   canna_fn_Next = IROHA_FN_Next;
1427
1428   DEFVAR_INT ("canna-func-previous", &canna_fn_Prev  /*
1429
1430 */ );
1431   canna_fn_Prev = IROHA_FN_Prev;
1432
1433   DEFVAR_INT ("canna-func-beginning-of-line", &canna_fn_BeginningOfLine  /*
1434
1435 */ );
1436   canna_fn_BeginningOfLine = IROHA_FN_BeginningOfLine;
1437
1438   DEFVAR_INT ("canna-func-end-of-line", &canna_fn_EndOfLine  /*
1439
1440 */ );
1441   canna_fn_EndOfLine = IROHA_FN_EndOfLine;
1442
1443   DEFVAR_INT ("canna-func-delete-next", &canna_fn_DeleteNext  /*
1444
1445 */ );
1446   canna_fn_DeleteNext = IROHA_FN_DeleteNext;
1447
1448   DEFVAR_INT ("canna-func-delete-previous", &canna_fn_DeletePrevious  /*
1449
1450 */ );
1451   canna_fn_DeletePrevious = IROHA_FN_DeletePrevious;
1452
1453   DEFVAR_INT ("canna-func-kill-to-end-of-line", &canna_fn_KillToEndOfLine /*
1454
1455 */ );
1456   canna_fn_KillToEndOfLine = IROHA_FN_KillToEndOfLine;
1457
1458   DEFVAR_INT ("canna-func-henkan", &canna_fn_Henkan  /*
1459
1460 */ );
1461   canna_fn_Henkan = IROHA_FN_Henkan;
1462
1463   DEFVAR_INT ("canna-func-kakutei", &canna_fn_Kakutei  /*
1464
1465 */ );
1466   canna_fn_Kakutei = IROHA_FN_Kakutei;
1467
1468   DEFVAR_INT ("canna-func-extend", &canna_fn_Extend  /*
1469
1470 */ );
1471   canna_fn_Extend = IROHA_FN_Extend;
1472
1473   DEFVAR_INT ("canna-func-shrink", &canna_fn_Shrink  /*
1474
1475 */ );
1476   canna_fn_Shrink = IROHA_FN_Shrink;
1477
1478 #ifdef CANNA_FN_AdjustBunsetsu
1479   DEFVAR_INT ("canna-func-adjust-bunsetsu", &canna_fn_AdjustBunsetsu  /*
1480
1481 */ );
1482   canna_fn_AdjustBunsetsu = CANNA_FN_AdjustBunsetsu;
1483 #endif
1484   DEFVAR_INT ("canna-func-quit", &canna_fn_Quit  /*
1485
1486 */ );
1487   canna_fn_Quit = IROHA_FN_Quit;
1488
1489   DEFVAR_INT ("canna-func-convert-as-hex", &canna_fn_ConvertAsHex  /*
1490
1491 */ );
1492   canna_fn_ConvertAsHex = IROHA_FN_ConvertAsHex;
1493
1494   DEFVAR_INT ("canna-func-convert-as-bushu", &canna_fn_ConvertAsBushu  /*
1495
1496 */ );
1497   canna_fn_ConvertAsBushu = IROHA_FN_ConvertAsBushu;
1498
1499   DEFVAR_INT ("canna-func-kouho-ichiran", &canna_fn_KouhoIchiran  /*
1500
1501 */ );
1502   canna_fn_KouhoIchiran = IROHA_FN_KouhoIchiran;
1503
1504   DEFVAR_INT ("canna-func-bubun-muhenkan", &canna_fn_BubunMuhenkan  /*
1505
1506 */ );
1507   canna_fn_BubunMuhenkan = IROHA_FN_BubunMuhenkan;
1508
1509   DEFVAR_INT ("canna-func-zenkaku", &canna_fn_Zenkaku  /*
1510
1511 */ );
1512   canna_fn_Zenkaku = IROHA_FN_Zenkaku;
1513
1514   DEFVAR_INT ("canna-func-hankaku", &canna_fn_Hankaku  /*
1515
1516 */ );
1517   canna_fn_Hankaku = IROHA_FN_Hankaku;
1518
1519   DEFVAR_INT ("canna-func-to-upper", &canna_fn_ToUpper  /*
1520
1521 */ );
1522   canna_fn_ToUpper = IROHA_FN_ToUpper;
1523
1524   DEFVAR_INT ("canna-func-capitalize", &canna_fn_Capitalize  /*
1525
1526 */ );
1527   canna_fn_Capitalize = IROHA_FN_Capitalize;
1528
1529   DEFVAR_INT ("canna-func-to-lower", &canna_fn_ToLower  /*
1530
1531 */ );
1532   canna_fn_ToLower = IROHA_FN_ToLower;
1533
1534   DEFVAR_INT ("canna-func-hiragana", &canna_fn_Hiragana  /*
1535
1536 */ );
1537   canna_fn_Hiragana = IROHA_FN_Hiragana;
1538
1539   DEFVAR_INT ("canna-func-katakana", &canna_fn_Katakana  /*
1540
1541 */ );
1542   canna_fn_Katakana = IROHA_FN_Katakana;
1543
1544   DEFVAR_INT ("canna-func-romaji", &canna_fn_Romaji  /*
1545
1546 */ );
1547   canna_fn_Romaji = IROHA_FN_Romaji;
1548
1549 #ifdef CANNA_FN_BaseHiragana
1550   DEFVAR_INT ("canna-func-base-hiragana", &canna_fn_BaseHiragana  /*
1551
1552 */ );
1553   canna_fn_BaseHiragana = CANNA_FN_BaseHiragana;
1554
1555   DEFVAR_INT ("canna-func-base-katakana", &canna_fn_BaseKatakana  /*
1556
1557 */ );
1558   canna_fn_BaseKatakana = CANNA_FN_BaseKatakana;
1559
1560   DEFVAR_INT ("canna-func-base-eisu", &canna_fn_BaseEisu  /*
1561
1562 */ );
1563   canna_fn_BaseEisu = CANNA_FN_BaseEisu;
1564
1565   DEFVAR_INT ("canna-func-base-zenkaku", &canna_fn_BaseZenkaku  /*
1566
1567 */ );
1568   canna_fn_BaseZenkaku = CANNA_FN_BaseZenkaku;
1569
1570   DEFVAR_INT ("canna-func-base-hankaku", &canna_fn_BaseHankaku  /*
1571
1572 */ );
1573   canna_fn_BaseHankaku = CANNA_FN_BaseHankaku;
1574
1575   DEFVAR_INT ("canna-func-base-kana", &canna_fn_BaseKana  /*
1576
1577 */ );
1578   canna_fn_BaseKana = CANNA_FN_BaseKana;
1579
1580   DEFVAR_INT ("canna-func-base-kakutei", &canna_fn_BaseKakutei  /*
1581
1582 */ );
1583   canna_fn_BaseKakutei = CANNA_FN_BaseKakutei;
1584
1585   DEFVAR_INT ("canna-func-base-henkan", &canna_fn_BaseHenkan  /*
1586
1587 */ );
1588   canna_fn_BaseHenkan = CANNA_FN_BaseHenkan;
1589
1590   DEFVAR_INT ("canna-func-base-hiragana-katakana-toggle",
1591               &canna_fn_BaseHiraKataToggle  /*
1592
1593 */ );
1594   canna_fn_BaseHiraKataToggle = CANNA_FN_BaseHiraKataToggle;
1595
1596   DEFVAR_INT ("canna-func-base-zenkaku-hankaku-toggle",
1597               &canna_fn_BaseZenHanToggle  /*
1598
1599 */ );
1600   canna_fn_BaseZenHanToggle = CANNA_FN_BaseZenHanToggle;
1601
1602   DEFVAR_INT ("canna-func-base-kana-eisu-toggle",
1603               &canna_fn_BaseKanaEisuToggle  /*
1604
1605 */ );
1606   canna_fn_BaseKanaEisuToggle = CANNA_FN_BaseKanaEisuToggle;
1607
1608   DEFVAR_INT ("canna-func-base-kakutei-henkan-toggle",
1609               &canna_fn_BaseKakuteiHenkanToggle  /*
1610
1611 */ );
1612   canna_fn_BaseKakuteiHenkanToggle = CANNA_FN_BaseKakuteiHenkanToggle;
1613
1614   DEFVAR_INT ("canna-func-base-rotate-forward",
1615               &canna_fn_BaseRotateForward  /*
1616
1617 */ );
1618   canna_fn_BaseRotateForward = CANNA_FN_BaseRotateForward;
1619
1620   DEFVAR_INT ("canna-func-base-rotate-backward",
1621               &canna_fn_BaseRotateBackward  /*
1622
1623 */ );
1624   canna_fn_BaseRotateBackward = CANNA_FN_BaseRotateBackward;
1625
1626 #endif
1627   DEFVAR_INT ("canna-func-extend-mode", &canna_fn_ExtendMode  /*
1628
1629 */ );
1630   canna_fn_ExtendMode = IROHA_FN_ExtendMode;
1631
1632   DEFVAR_INT ("canna-func-touroku", &canna_fn_Touroku  /*
1633
1634 */ );
1635   canna_fn_Touroku = IROHA_FN_Touroku;
1636
1637   DEFVAR_INT ("canna-func-hex-mode", &canna_fn_HexMode  /*
1638
1639 */ );
1640   canna_fn_HexMode = IROHA_FN_HexMode;
1641
1642   DEFVAR_INT ("canna-func-bushu-mode", &canna_fn_BushuMode  /*
1643
1644 */ );
1645   canna_fn_BushuMode = IROHA_FN_BushuMode;
1646
1647   DEFVAR_INT ("canna-func-kigo-mode", &canna_fn_KigouMode  /*
1648
1649 */ );
1650   canna_fn_KigouMode = IROHA_FN_KigouMode;
1651
1652 #ifdef CANNA_FN_Mark
1653   DEFVAR_INT ("canna-func-mark", &canna_fn_Mark  /*
1654
1655 */ );
1656   canna_fn_Mark = CANNA_FN_Mark;
1657 #endif
1658 #ifdef CANNA_FN_TemporalMode
1659   DEFVAR_INT ("canna-func-temporal-mode", &canna_fn_TemporalMode  /*
1660
1661 */ );
1662   canna_fn_TemporalMode = CANNA_FN_TemporalMode;
1663 #endif
1664
1665   DEFVAR_INT ("canna-key-nfer", &canna_key_Nfer /*
1666
1667 */ );
1668   canna_key_Nfer = IROHA_KEY_Nfer;
1669
1670   DEFVAR_INT ("canna-key-xfer", &canna_key_Xfer /*
1671
1672 */ );
1673   canna_key_Xfer = IROHA_KEY_Xfer;
1674
1675   DEFVAR_INT ("canna-key-up", &canna_key_Up /*
1676
1677 */ );
1678   canna_key_Up = IROHA_KEY_Up;
1679
1680   DEFVAR_INT ("canna-key-left", &canna_key_Left /*
1681
1682 */ );
1683   canna_key_Left = IROHA_KEY_Left;
1684
1685   DEFVAR_INT ("canna-key-right", &canna_key_Right /*
1686
1687 */ );
1688   canna_key_Right = IROHA_KEY_Right;
1689
1690   DEFVAR_INT ("canna-key-down", &canna_key_Down /*
1691
1692 */ );
1693   canna_key_Down = IROHA_KEY_Down;
1694
1695   DEFVAR_INT ("canna-key-insert", &canna_key_Insert /*
1696
1697 */ );
1698   canna_key_Insert = IROHA_KEY_Insert;
1699
1700   DEFVAR_INT ("canna-key-rollup", &canna_key_Rollup /*
1701
1702 */ );
1703   canna_key_Rollup = IROHA_KEY_Rollup;
1704
1705   DEFVAR_INT ("canna-key-rolldown", &canna_key_Rolldown /*
1706
1707 */ );
1708   canna_key_Rolldown = IROHA_KEY_Rolldown;
1709
1710   DEFVAR_INT ("canna-key-home", &canna_key_Home /*
1711
1712 */ );
1713   canna_key_Home = IROHA_KEY_Home;
1714
1715   DEFVAR_INT ("canna-key-help", &canna_key_Help /*
1716
1717 */ );
1718   canna_key_Help = IROHA_KEY_Help;
1719
1720   DEFVAR_INT ("canna-key-kp-key", &canna_key_KP_Key /*
1721
1722 */ );
1723   canna_key_KP_Key = IROHA_KEY_KP_Key;
1724
1725   DEFVAR_INT ("canna-key-shift-nfer", &canna_key_Shift_Nfer /*
1726
1727 */ );
1728   canna_key_Shift_Nfer = IROHA_KEY_Shift_Nfer;
1729
1730   DEFVAR_INT ("canna-key-shift-xfer", &canna_key_Shift_Xfer /*
1731
1732 */ );
1733   canna_key_Shift_Xfer = IROHA_KEY_Shift_Xfer;
1734
1735   DEFVAR_INT ("canna-key-shift-up", &canna_key_Shift_Up /*
1736
1737 */ );
1738   canna_key_Shift_Up = IROHA_KEY_Shift_Up;
1739
1740   DEFVAR_INT ("canna-key-shift-left", &canna_key_Shift_Left /*
1741
1742 */ );
1743   canna_key_Shift_Left = IROHA_KEY_Shift_Left;
1744
1745   DEFVAR_INT ("canna-key-shift-right", &canna_key_Shift_Right /*
1746
1747 */ );
1748   canna_key_Shift_Right = IROHA_KEY_Shift_Right;
1749
1750   DEFVAR_INT ("canna-key-shift-down", &canna_key_Shift_Down /*
1751
1752 */ );
1753   canna_key_Shift_Down = IROHA_KEY_Shift_Down;
1754
1755   DEFVAR_INT ("canna-key-control-nfer", &canna_key_Cntrl_Nfer /*
1756
1757 */ );
1758   canna_key_Cntrl_Nfer = IROHA_KEY_Cntrl_Nfer;
1759
1760   DEFVAR_INT ("canna-key-control-xfer", &canna_key_Cntrl_Xfer /*
1761
1762 */ );
1763   canna_key_Cntrl_Xfer = IROHA_KEY_Cntrl_Xfer;
1764
1765   DEFVAR_INT ("canna-key-control-up", &canna_key_Cntrl_Up /*
1766
1767 */ );
1768   canna_key_Cntrl_Up = IROHA_KEY_Cntrl_Up;
1769
1770   DEFVAR_INT ("canna-key-control-left", &canna_key_Cntrl_Left /*
1771
1772 */ );
1773   canna_key_Cntrl_Left = IROHA_KEY_Cntrl_Left;
1774
1775   DEFVAR_INT ("canna-key-control-right", &canna_key_Cntrl_Right /*
1776
1777 */ );
1778   canna_key_Cntrl_Right = IROHA_KEY_Cntrl_Right;
1779
1780   DEFVAR_INT ("canna-key-control-down", &canna_key_Cntrl_Down /*
1781
1782 */ );
1783   canna_key_Cntrl_Down = IROHA_KEY_Cntrl_Down;
1784
1785   Fprovide(intern("CANNA"));
1786 }
1787
1788 #ifdef CANNA_MULE
1789 /* To handle MULE internal code and EUC.
1790    I assume CANNA can handle only Japanese EUC. */
1791
1792 /* EUC multibyte string to MULE internal string */
1793
1794 static void
1795 c2mu (unsigned char *cp, int l, unsigned char *mp)
1796 {
1797   unsigned char ch, *ep = cp+l;
1798 #ifdef UTF2000
1799   Emchar chr;
1800
1801   while ((cp < ep) && (ch = *cp++))
1802     {
1803       if (ch == ISO_CODE_SS2)
1804         {
1805           chr = (*cp++) + MIN_CHAR_HALFWIDTH_KATAKANA - 0x20;
1806         }
1807       else if (ch == ISO_CODE_SS3)
1808         {
1809           ch = *cp++;
1810           chr = MAKE_CHAR (Vcharset_japanese_jisx0212,
1811                            ch & 0x7f, (*cp++) & 0x7f);
1812         }
1813       else if (ch & 0x80)
1814         {
1815           chr = MAKE_CHAR (Vcharset_japanese_jisx0208,
1816                            ch & 0x7f, (*cp++) & 0x7f);
1817         }
1818       else
1819         {
1820           chr = ch;
1821         }
1822       if ( chr <= 0x7f )
1823         {
1824           *mp++ = chr;
1825         }
1826       else if ( chr <= 0x7ff )
1827         {
1828           *mp++ = (chr >> 6) | 0xc0;
1829           *mp++ = (chr & 0x3f) | 0x80;
1830         }
1831       else if ( chr <= 0xffff )
1832         {
1833           *mp++ =  (chr >> 12) | 0xe0;
1834           *mp++ = ((chr >>  6) & 0x3f) | 0x80;
1835           *mp++ =  (chr        & 0x3f) | 0x80;
1836         }
1837       else if ( chr <= 0x1fffff )
1838         {
1839           *mp++ =  (chr >> 18) | 0xf0;
1840           *mp++ = ((chr >> 12) & 0x3f) | 0x80;
1841           *mp++ = ((chr >>  6) & 0x3f) | 0x80;
1842           *mp++ =  (chr        & 0x3f) | 0x80;
1843         }
1844       else if ( chr <= 0x3ffffff )
1845         {
1846           *mp++ =  (chr >> 24) | 0xf8;
1847           *mp++ = ((chr >> 18) & 0x3f) | 0x80;
1848           *mp++ = ((chr >> 12) & 0x3f) | 0x80;
1849           *mp++ = ((chr >>  6) & 0x3f) | 0x80;
1850           *mp++ =  (chr        & 0x3f) | 0x80;
1851         }
1852       else
1853         {
1854           *mp++ =  (chr >> 30) | 0xfc;
1855           *mp++ = ((chr >> 24) & 0x3f) | 0x80;
1856           *mp++ = ((chr >> 18) & 0x3f) | 0x80;
1857           *mp++ = ((chr >> 12) & 0x3f) | 0x80;
1858           *mp++ = ((chr >>  6) & 0x3f) | 0x80;
1859           *mp++ =  (chr        & 0x3f) | 0x80;
1860         }
1861     }
1862 #else
1863   while ((cp < ep) && (ch = *cp))
1864     {
1865       if ((unsigned char) ch == ISO_CODE_SS2)
1866         {
1867           *mp++ = LEADING_BYTE_KATAKANA_JISX0201;
1868           cp++;
1869         }
1870       else if ((unsigned char) ch == ISO_CODE_SS3)
1871         {
1872           *mp++ = LEADING_BYTE_JAPANESE_JISX0212;
1873           cp++;
1874           *mp++ = *cp++;
1875         }
1876       else if (ch & 0x80)
1877         {
1878           *mp++ = LEADING_BYTE_JAPANESE_JISX0208;
1879           *mp++ = *cp++;
1880         }
1881       *mp++ = *cp++;
1882     }
1883 #endif
1884   *mp = 0;
1885 }
1886
1887 /* MULE internal string to EUC multibyte string */
1888
1889 static void
1890 m2c (unsigned char *mp, int l, unsigned char *cp)
1891 {
1892   unsigned char ch, *ep = mp + l;
1893 #ifdef UTF2000
1894   int len;
1895   Emchar chr;
1896 #endif
1897
1898   while ((mp < ep) && (ch = *mp++))
1899     {
1900 #ifdef UTF2000
1901       if ( ch >= 0xfc )
1902         {
1903           chr = (ch & 0x01);
1904           len = 5;
1905         }
1906       else if ( ch >= 0xf8 )
1907         {
1908           chr = ch & 0x03;
1909           len = 4;
1910         }
1911       else if ( ch >= 0xf0 )
1912         {
1913           chr = ch & 0x07;
1914           len = 3;
1915         }
1916       else if ( ch >= 0xe0 )
1917         {
1918           chr = ch & 0x0f;
1919           len = 2;
1920         }
1921       else if ( ch >= 0xc0 )
1922         {
1923           chr = ch & 0x1f;
1924           len = 1;
1925         }
1926       else
1927         {
1928           chr = ch;
1929           len = 0;
1930         }
1931       for( ; len > 0; len-- )
1932         {
1933           ch = *mp++;
1934           chr = ( chr << 6 ) | ( ch & 0x3f );
1935         }
1936       if ( chr <= 0x7f )
1937         *cp++ = chr;
1938       else
1939         {
1940           int code;
1941
1942           if ( (code
1943                 = charset_code_point (Vcharset_japanese_jisx0208,
1944                                       chr, 0)) >= 0 )
1945             {
1946               *cp++ = (code >> 8) | 0x80;
1947               *cp++ = (code & 0xFF) | 0x80;
1948             }
1949           else if ( (code
1950                      = charset_code_point (Vcharset_katakana_jisx0201,
1951                                            chr, 0)) >= 0 )
1952             {
1953               *cp++ = ISO_CODE_SS2;
1954               *cp++ = code | 0x80;
1955             }
1956           else if ( (code
1957                      = charset_code_point (Vcharset_japanese_jisx0212,
1958                                            chr, 0)) >= 0 )
1959             {
1960               *cp++ = ISO_CODE_SS3;
1961               *cp++ = (code >> 8) | 0x80;
1962               *cp++ = (code & 0xFF) | 0x80;
1963             }
1964         }
1965 #else
1966       switch (ch)
1967         {
1968         case LEADING_BYTE_KATAKANA_JISX0201:
1969           *cp++ = ISO_CODE_SS2;
1970           *cp++ = *mp++;
1971           break;
1972         case LEADING_BYTE_JAPANESE_JISX0212:
1973           *cp++ = ISO_CODE_SS3;
1974         case LEADING_BYTE_JAPANESE_JISX0208:
1975           *cp++ = *mp++;
1976           *cp++ = *mp++;
1977           break;
1978         default:
1979           *cp++ = ch;
1980           break;
1981         }
1982 #endif
1983     }
1984   *cp = 0;
1985 }
1986
1987 #undef make_string
1988
1989 /* make_string after converting EUC string to MULE internal string */
1990 static Lisp_Object
1991 mule_make_string (unsigned char *p, int l)
1992 {
1993   unsigned char cbuf[4096];
1994
1995   c2mu (p,l,cbuf);
1996   return (make_string (cbuf,strlen (cbuf)));
1997 }
1998
1999 /* return the MULE internal string length of EUC string */
2000 /* Modified by sb to return a character count not byte count. */
2001 static int
2002 mule_strlen (unsigned char *p, int l)
2003 {
2004   unsigned char ch, *cp = p;
2005   int len = 0;
2006
2007   while ((cp < p + l) && (ch = *cp))
2008     {
2009       if ((unsigned char) ch == ISO_CODE_SS2)
2010         {
2011           len++;
2012           cp += 2;
2013         }
2014       else if ((unsigned char) ch == ISO_CODE_SS3)
2015         {
2016           len++;
2017           cp += 3;
2018         }
2019       else if (ch & 0x80)
2020         {
2021           len++;
2022           cp += 2;
2023         }
2024       else
2025         {
2026           len++;
2027           cp++;
2028         }
2029     }
2030   return (len);
2031 }
2032
2033 /* count number of characters */
2034 static void
2035 count_char (unsigned char *p, int len, int pos, int rev,
2036             Fixnum *clen, Fixnum *cpos, Fixnum *crev)
2037 {
2038   unsigned char *q = p;
2039
2040   *clen = *cpos = *crev = 0;
2041   if (len == 0) return;
2042   while (q < p + pos)
2043     {
2044       (*clen)++;
2045       (*cpos)++;
2046       if (*q++ & 0x80) q++;
2047     }
2048   while (q < p + pos + rev)
2049     {
2050       (*clen)++;
2051       (*crev)++;
2052       if (*q++ & 0x80) q++;
2053     }
2054   while (q < p + len)
2055     {
2056       (*clen)++;
2057       if (*q++ & 0x80) q++;
2058     }
2059 }
2060 #endif /* CANNA_MULE */