Initial revision
[chise/xemacs-chise.git.1] / src / mule-canna.c
1 /* CANNA interface
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 /* #### The comments in this file are mostly in EUC-formatted Japanese.
26    It would be ***soooo*** much nicer if someone could translate
27    them ... */
28
29 /*
30
31   Authors: Akira Kon (kon@uxd.fc.nec.co.jp)
32            Ichiro Hirakura (hirakura@uxd.fc.nec.co.jp)
33
34   Functions defined in this file are
35
36   (canna-key-proc key)
37                 key: single STRING
38                 RETURNS:
39                          Length of converted string if no error occurs.
40                          Error string if error occurs.
41                 DESCRIPTION:
42                          Convert a key input to a set of strings.  The
43                          strings contain both well-formed string and a
44                          intermediate result to show the translation
45                          information to a user.  converted strings are
46                          stored in specific variables.
47
48   (canna-initialize)
49                 RETURNS:
50                         List of the following things:
51                         - list of keys to toggle Japanese-mode
52                         - error message
53                         - list of warning messages
54                 DESCRIPTION:
55                         Initialize ``canna'', which is a kana-to-kanji
56                         converter for GNU Emacs.  The first arg
57                         specifies if inserting space character between
58                         BUNSETSU when candidates are displayed.  The
59                         second arg specifies server.  The third arg
60                         specifies a file which will be used as a
61                         customization description.  If nil is
62                         specified for each arg, the default value will
63                         be used.
64
65   (canna-finalize)
66                 RETURNS:
67                         list of warning messages
68                 DESCRIPTION:
69                         finalize ``canna'', which is a kana-to-kanji
70                         converter for GNU Emacs.  This cause to write
71                         miscellaneous informations to kana-to-kanji
72                         dictionary.
73
74   (canna-touroku-string string)
75                 string:
76                         String to register to a dictionary.
77                 RETURNS:
78                         The same thing returns as canna-key-proc does.
79                 DESCRIPTION:
80                         Register Kanji words into kana-to-kanji
81                         conversion dictionary.
82
83   (canna-set-width width)
84                 width:
85                         Column width of the place where the candidates
86                         of kana-to-kanji conversion will be shown.
87                 RETURNS:
88                         nil
89                 DESCRIPTION:
90                         Set status-line width information, which is
91                         used to display kanji candidates.
92
93   (canna-change-mode num)
94                 num:
95                         The mode number of Canna.
96                 RETURNS:
97                         The same thing returns as canna-key-proc does.
98                 DESCRIPTION:
99                         Change Japanese pre-edit mode.
100
101   (canna-store-yomi yomi roma)
102                 yomi:
103                         ``Yomi'' to be stored.
104                 roma:
105                         ``Romaji'' which corresponds to the ``Yomi''.
106                 RETURNS:
107                         The same thing returns as canna-key-proc does.
108                 DESCRIPTION:
109                         Store yomi characters as a YOMI of
110                         kana-to-kanji conversion.
111
112   (canna-do-function num ch)
113                 num:
114                         A function number to be called.
115                 ch:
116                         A character will be specified in order to feed
117                         the character to the function if the function
118                         needs a input character.
119                 RETURNS:
120                         The same thing returns as canna-key-proc does.
121                 DESCRIPTION:
122                         Do specified function at current mode.
123
124   (canna-parse string)
125                 string:
126                         To be parsed.
127                 RETURNS:
128                         List of warning messages.
129                 DESCRIPTION:
130                         Parse customize string.
131
132   (canna-query-mode)
133                 RETURNS:
134                         A string which indicate the current mode.
135                 DESCRIPTION:
136                         Get current mode string.
137
138   Functions below are used for KKCP compatible library.  These
139   functions provides a base kana-to-kanji conversion system for EGG.
140   These functions may be used when users want to change the engine
141   from Wnn to Canna without changing user interface of Japanese input.
142
143   (canna-henkan-begin)
144   (canna-henkan-next)
145   (canna-bunsetu-henkou)
146   (canna-henkan-kakutei)
147   (canna-henkan-end)
148   (canna-henkan-quit)
149
150  */
151
152 #include <config.h>
153 #include "lisp.h"
154
155 #include "buffer.h"
156 #include "file-coding.h"
157
158 #ifdef CANNA2
159 #define IROHA_BC
160 #include "canna/jrkanji.h"
161 #include "canna/RK.h"
162 #else /* !CANNA2 */
163 #include "iroha/jrkanji.h"
164 #include "iroha/RK.h"
165 #endif /* !CANNA2 */
166 extern char *jrKanjiError;
167
168 #define KEYTOSTRSIZE 2048
169 static unsigned char buf[KEYTOSTRSIZE];
170 static char **warning;
171
172 static int Vcanna_empty_info, Vcanna_through_info;
173 static int Vcanna_underline;
174 static int Vcanna_inhibit_hankakukana;
175
176 static Lisp_Object Vcanna_kakutei_string;
177 static Lisp_Object Vcanna_kakutei_yomi;
178 static Lisp_Object Vcanna_kakutei_romaji;
179 static Lisp_Object Vcanna_henkan_string;
180 static int         Vcanna_henkan_length;
181 static int         Vcanna_henkan_revPos;
182 static int         Vcanna_henkan_revLen;
183 static Lisp_Object Vcanna_ichiran_string;
184 static int         Vcanna_ichiran_length;
185 static int         Vcanna_ichiran_revPos;
186 static int         Vcanna_ichiran_revLen;
187 static Lisp_Object Vcanna_mode_string;
188
189 static int IRCP_context;
190
191 static Lisp_Object storeResults (unsigned char *, int, jrKanjiStatus *);
192 static Lisp_Object kanjiYomiList (int, int);
193
194 #ifdef CANNA_MULE
195 static void m2c (unsigned char *, int, unsigned char *);
196 static Lisp_Object mule_make_string (unsigned char *, int);
197 static int mule_strlen (unsigned char *, int);
198 static void count_char (unsigned char *,int, int, int, int *, int *, int *);
199 #define make_string mule_make_string
200 #endif
201
202 /* Lisp functions definition */
203
204 DEFUN ("canna-key-proc", Fcanna_key_proc, 1, 1, 0, /*
205 Translate a key input to a set of strings.  The strings contain both
206 well-formed string and intermediate result to show the translation
207 information to a user.  Converted strings are stored in specific
208 variables.
209 */
210        (ch))
211 {
212   jrKanjiStatus ks;
213   int len;
214
215   CHECK_CHAR_COERCE_INT (ch);
216   len = jrKanjiString (0, XCHAR (ch), buf, KEYTOSTRSIZE, &ks);
217   return storeResults (buf, len, &ks);
218 }
219
220 static Lisp_Object
221 storeResults (unsigned char *buf, int len, jrKanjiStatus *ks)
222 {
223   Lisp_Object val = Qnil;
224
225   if (len < 0)
226     { /* Error detected */
227       val = make_string ((unsigned char*) jrKanjiError, strlen (jrKanjiError));
228     }
229   else
230     {
231       /* ³ÎÄꤷ¤¿Ê¸»úÎó */
232       Vcanna_kakutei_string = make_string (buf, len);
233       val = make_int (len);
234       /* ³ÎÄꤷ¤¿Ê¸»úÎó¤ÎÆɤߤξðÊó... */
235       Vcanna_kakutei_yomi = Vcanna_kakutei_romaji = Qnil;
236       if (ks->info & KanjiYomiInfo)
237         {
238           unsigned char *p = buf + len + 1;
239           int yomilen = strlen (p);
240
241           if (len + yomilen + 1 < KEYTOSTRSIZE)
242             {
243               int yomilen2;
244
245               Vcanna_kakutei_yomi = make_string (p, yomilen); /* Æɤߠ*/
246               p += yomilen + 1;
247               yomilen2 = strlen (p);
248               if (len + yomilen + yomilen2 + 2 < KEYTOSTRSIZE)
249                 {
250                   Vcanna_kakutei_romaji = make_string (p, yomilen2); /* ¥í¡¼¥Þ»ú */
251                 }
252             }
253         }
254
255
256       /* ¸õÊäɽ¼¨¤Îʸ»úÎó¤Ç¤¹¡£*/
257       Vcanna_henkan_string = Qnil;
258       if (ks->length >= 0)
259         {
260           Vcanna_henkan_string = make_string (ks->echoStr, ks->length);
261 #ifndef CANNA_MULE
262           Vcanna_henkan_length = ks->length;
263           Vcanna_henkan_revPos = ks->revPos;
264           Vcanna_henkan_revLen = ks->revLen;
265 #else /* CANNA_MULE */
266           if (Vcanna_underline)
267             {
268               Vcanna_henkan_length = mule_strlen (ks->echoStr,ks->length);
269               Vcanna_henkan_revPos = mule_strlen (ks->echoStr,ks->revPos);
270               Vcanna_henkan_revLen = mule_strlen (ks->echoStr+ks->revPos,ks->revLen);
271             }
272           else
273             {
274               count_char (ks->echoStr, ks->length, ks->revPos, ks->revLen,
275                           &Vcanna_henkan_length, &Vcanna_henkan_revPos,
276                           &Vcanna_henkan_revLen);
277             }
278 #endif /* CANNA_MULE */
279         }
280
281       /* °ìÍ÷¤Î¾ðÊó */
282       Vcanna_ichiran_string = Qnil;
283       if (ks->info & KanjiGLineInfo && ks->gline.length >= 0)
284         {
285           Vcanna_ichiran_string = make_string (ks->gline.line, ks->gline.length);
286 #ifndef CANNA_MULE
287           Vcanna_ichiran_length = ks->gline.length;
288           Vcanna_ichiran_revPos = ks->gline.revPos;
289           Vcanna_ichiran_revLen = ks->gline.revLen;
290 #else /* CANNA_MULE */
291           count_char (ks->gline.line, ks->gline.length,
292                       ks->gline.revPos, ks->gline.revLen, &Vcanna_ichiran_length,
293                       &Vcanna_ichiran_revPos, &Vcanna_ichiran_revLen);
294 #endif /* CANNA_MULE */
295         }
296
297       /* ¥â¡¼¥É¤Î¾ðÊó */
298       Vcanna_mode_string = Qnil;
299       if (ks->info & KanjiModeInfo)
300         {
301           Vcanna_mode_string = make_string (ks->mode, strlen (ks->mode));
302         }
303
304       /* ¤½¤Î¾¤Î¾ðÊó */
305       Vcanna_empty_info = (ks->info & KanjiEmptyInfo) ? 1 : 0;
306       Vcanna_through_info = (ks->info & KanjiThroughInfo) ? 1 : 0;
307     }
308
309   return val;
310 }
311
312 DEFUN ("canna-set-bunsetsu-kugiri", Fcanna_set_bunsetsu, 0, 1, 0, /*
313 This function sets the clause separator.
314 If non-nil value is specified, the white space separator will be used.
315 No separator will be used otherwise.
316 */
317        (num))
318 {
319   int kugiri; /* Ê¸Àá¶èÀÚ¤ê¤ò¤¹¤ë¤«¡© */
320
321   kugiri = NILP (num) ? 0 : 1;
322
323   jrKanjiControl (0, KC_SETBUNSETSUKUGIRI, (char *) kugiri);
324
325   return Qnil;
326 }
327
328 /* For whatever reason, calling Fding directly from libCanna loses */
329 static void call_Fding()
330 {
331   extern Lisp_Object Fding();
332
333   Fding (Qnil, Qnil, Qnil);
334 }
335
336 DEFUN ("canna-initialize", Fcanna_initialize, 0, 3, 0, /*
337 Initialize ``canna'', which is a kana-to-kanji converter for GNU Emacs.
338 The first arg specifies if inserting space character between BUNSETSU when
339 candidates are displayed.
340 The second arg specifies server.
341 The third arg specifies a file which will be used as a customization
342 description.
343 If nil is specified for each arg, the default value will be used.
344 */
345        (num, server, rcfile))
346 {
347   Lisp_Object val;
348   int res;
349   unsigned char **p, **q;
350
351   int kugiri; /* Ê¸Àá¶èÀÚ¤ê¤ò¤¹¤ë¤«¡© */
352
353   IRCP_context = -1;
354
355   if (NILP (num))
356     {
357       kugiri = 1;
358     }
359   else
360     {
361       CHECK_INT (num);
362       kugiri = XINT (num);
363       kugiri = (kugiri == 1) ? 1 : 0;
364     }
365
366   if (NILP (server))
367     {
368       jrKanjiControl (0, KC_SETSERVERNAME, (char *) 0);
369     }
370   else
371     {
372       char servername[256];
373
374       CHECK_STRING (server);
375       strncpy (servername, XSTRING (server)->_data, XSTRING (server)->_size);
376       servername[XSTRING (server)->_size] = '\0';
377       jrKanjiControl (0, KC_SETSERVERNAME, servername);
378     }
379
380   if (NILP (rcfile))
381     {
382       jrKanjiControl (0, KC_SETINITFILENAME, (char *) 0);
383     }
384   else
385     {
386       char rcname[256];
387
388       CHECK_STRING (rcfile);
389       strncpy (rcname, XSTRING (rcfile)->_data, XSTRING (rcfile)->_size);
390       rcname[XSTRING (rcfile)->_size] = '\0';
391       jrKanjiControl (0, KC_SETINITFILENAME, rcname);
392     }
393
394   warning = (char **) 0;
395 #ifdef nec_ews_svr4
396   stop_polling ();
397 #endif /* nec_ews_svr4 */
398   res = jrKanjiControl (0, KC_INITIALIZE, (char *)&warning);
399 #ifdef nec_ews_svr4
400   start_polling ();
401 #endif /* nec_ews_svr4 */
402   val = Qnil;
403   if (warning)
404     {
405       for (p = q = (unsigned char **) warning ; *q ; q++)
406         ;
407       while (p < q)
408         {
409           q--;
410           val = Fcons (make_string (*q, strlen (*q)), val);
411         }
412     }
413   val = Fcons (val, Qnil);
414
415   if (res == -1)
416     {
417       val = Fcons (make_string ((unsigned char*) jrKanjiError, 
418                                 strlen (jrKanjiError)), val);
419       /* ¥¤¥Ë¥·¥ã¥é¥¤¥º¤Ç¼ºÇÔ¤·¤¿¾ì¹ç¡£ */
420       return Fcons (Qnil, val);
421     }
422   else
423     {
424       extern void (*jrBeepFunc)();
425       Lisp_Object CANNA_mode_keys ();
426
427       jrBeepFunc = call_Fding;
428
429 #ifdef KC_SETAPPNAME
430 #ifndef CANNA_MULE
431       wcKanjiControl (0, KC_SETAPPNAME, "nemacs");
432 #else /* CANNA_MULE */
433       wcKanjiControl (0, KC_SETAPPNAME, "mule");
434 #endif /* CANNA_MULE */
435 #endif /* KC_SETAPPNAME */
436
437       jrKanjiControl (0, KC_SETBUNSETSUKUGIRI, (char *) kugiri);
438       jrKanjiControl (0, KC_SETWIDTH, (char *) 78);
439 #ifndef CANNA_MULE
440       jrKanjiControl (0, KC_INHIBITHANKAKUKANA, (char *) 1);
441 #else
442       /* mule ¤À¤Ã¤¿¤éȾ³Ñ¥«¥¿¥«¥Ê¤â»È¤¨¤ë */
443       if (Vcanna_inhibit_hankakukana)
444         jrKanjiControl (0, KC_INHIBITHANKAKUKANA, (char *) 1);
445 #endif
446       jrKanjiControl (0, KC_YOMIINFO, (char *) 2); /* ¢¨£²: ¥í¡¼¥Þ»ú¤Þ¤ÇÊÖ¤¹ */
447       val = Fcons (Qnil, val);
448       return Fcons (CANNA_mode_keys (), val);
449     }
450 }
451
452 DEFUN ("canna-finalize", Fcanna_finalize, 0, 0, 0, /*
453 finalize ``canna'', which is a kana-to-kanji converter for GNU Emacs.
454 This cause to write miscellaneous informations to kana-to-kanji dictionary.
455 */
456        ())
457 {
458   Lisp_Object val;
459   unsigned char **p;
460
461   jrKanjiControl (0, KC_FINALIZE, (char *)&warning);
462
463   val = Qnil;
464   if (warning)
465     {
466       for (p = (unsigned char**) warning ; *p ; p++)
467         {
468           val = Fcons (make_string (*p, strlen (*p)), val);
469         }
470     }
471   val = Fcons (val, Qnil);
472   IRCP_context = -1;
473   return val;
474 }
475
476 DEFUN ("canna-touroku-string", Fcanna_touroku_string, 1, 1, 0, /*
477 Register Kanji words into kana-to-kanji conversion dictionary.
478 */
479        (str))
480 {
481   jrKanjiStatusWithValue ksv;
482   jrKanjiStatus ks;
483   int len;
484   Lisp_Object val;
485 #ifdef CANNA_MULE
486   unsigned char cbuf[4096];
487 #endif
488
489   CHECK_STRING (str);
490   ksv.buffer = (unsigned char *) buf;
491   ksv.bytes_buffer = KEYTOSTRSIZE;
492 #ifndef CANNA_MULE
493   ks.echoStr = XSTRING (str)->_data;
494   ks.length = XSTRING (str)->_size;
495 #else /* CANNA_MULE */
496   m2c (XSTRING (str)->_data, XSTRING (str)->_size, cbuf);
497   ks.echoStr = cbuf;
498   ks.length = strlen (cbuf);
499 #endif /* CANNA_MULE */
500   ksv.ks = &ks;
501   len = jrKanjiControl (0, KC_DEFINEKANJI, (char *)&ksv);
502   val = storeResults (buf, ksv.val, ksv.ks);
503   return val;
504 }
505
506 DEFUN ("canna-set-width", Fcanna_set_width, 1, 1, 0, /*
507 Set status-line width information, which is used to display 
508 kanji candidates.
509 */
510        (num))
511 {
512   CHECK_INT (num);
513
514   jrKanjiControl (0, KC_SETWIDTH,  (char *) XINT (num));
515   return Qnil;
516 }
517
518 DEFUN ("canna-change-mode", Fcanna_change_mode, 1, 1, 0, /*
519 Change Japanese pre-edit mode.
520 */
521        (num))
522 {
523   jrKanjiStatusWithValue ksv;
524   jrKanjiStatus ks;
525   Lisp_Object val;
526
527   CHECK_INT (num);
528
529   ksv.buffer = (unsigned char *) buf;
530   ksv.bytes_buffer = KEYTOSTRSIZE;
531   ksv.ks = &ks;
532   ksv.val = XINT (num);
533   jrKanjiControl (0, KC_CHANGEMODE,  (char *)&ksv);
534   val = storeResults (buf, ksv.val, ksv.ks);
535   return val;
536 }
537
538 Lisp_Object
539 CANNA_mode_keys (void)
540 {
541 #define CANNAWORKBUFSIZE 32
542   char xxx[CANNAWORKBUFSIZE];
543   Lisp_Object val;
544   int i, n;
545
546   n = jrKanjiControl (0, KC_MODEKEYS, xxx);
547   val = Qnil;
548   for (i = n ; i > 0 ;)
549     {
550       --i;
551       /* !!#### something fucked here */
552       val = Fcons (make_char ((int)(0xFF & (unsigned char) xxx[i])), val);
553     }
554   return val;
555 }
556
557 DEFUN ("canna-store-yomi", Fcanna_store_yomi, 1, 2, 0, /*
558 Store yomi characters as a YOMI of kana-to-kanji conversion.
559 */
560        (yomi, roma))
561 {
562   jrKanjiStatusWithValue ksv;
563   jrKanjiStatus ks;
564
565   CHECK_STRING (yomi);
566 #ifndef CANNA_MULE
567   strncpy (buf, XSTRING (yomi)->_data, XSTRING (yomi)->_size);
568   ks.length = XSTRING (yomi)->_size;
569   buf[ks.length] = '\0';
570 #else /* CANNA_MULE */
571   m2c (XSTRING (yomi)->_data, XSTRING (yomi)->_size, buf);
572   ks.length = strlen (buf);
573 #endif /* CANNA_MULE */
574
575   if (NILP (roma))
576     {
577       ks.mode = 0;
578     }
579   else
580     {
581       CHECK_STRING (roma);
582
583 #ifndef CANNA_MULE
584       strncpy (buf + XSTRING (yomi)->_size + 1, XSTRING (roma)->_data,
585                XSTRING (roma)->_size);
586       buf[XSTRING (yomi)->_size + 1 + XSTRING (roma)->_size] = '\0';
587       ks.mode = (unsigned char *)(buf + XSTRING (yomi)->_size + 1);
588 #else /* CANNA_MULE */
589       ks.mode = (unsigned char *)(buf + ks.length + 1);
590       m2c (XSTRING (roma)->_data, XSTRING (roma)->_size, ks.mode);
591 #endif /* CANNA_MULE */
592     }
593
594   ks.echoStr = (unsigned char *) buf;
595   ksv.buffer = (unsigned char *) buf; /* ÊÖÃÍÍÑ */
596   ksv.bytes_buffer = KEYTOSTRSIZE;
597   ksv.ks = &ks;
598
599   jrKanjiControl (0, KC_STOREYOMI, (char *)&ksv);
600
601   return storeResults (buf, ksv.val, ksv.ks);
602 }
603
604 DEFUN ("canna-do-function", Fcanna_do_function, 1, 2, 0, /*
605 Do specified function at current mode.
606 */
607        (num, ch))
608 {
609   jrKanjiStatusWithValue ksv;
610   jrKanjiStatus ks;
611   Lisp_Object val;
612
613   CHECK_INT (num);
614
615   if (NILP (ch))
616     {
617       *buf = '@';
618     }
619   else
620     {
621       CHECK_CHAR (ch);
622       *buf = XCHAR (ch);
623     }
624
625   ksv.buffer = (unsigned char *) buf;
626   ksv.bytes_buffer = KEYTOSTRSIZE;
627   ksv.ks = &ks;
628   ksv.val = XINT (num);
629   jrKanjiControl (0, KC_DO, (char *) &ksv);
630   val = storeResults (buf, ksv.val, ksv.ks);
631   return val;
632 }
633
634 DEFUN ("canna-parse", Fcanna_parse, 1, 1, 0, /*
635 Parse customize string.
636 */
637        (str))
638 {
639   Lisp_Object val;
640   unsigned char **p;
641   int n;
642
643   CHECK_STRING (str);
644
645 #ifndef CANNA_MULE
646   strncpy (buf, XSTRING (str)->_data, XSTRING (str)->_size);
647   buf[XSTRING (str)->_size] = '\0';
648 #else /* CANNA_MULE */
649   m2c (XSTRING (str)->_data, XSTRING (str)->_size, buf);
650 #endif /* CANNA_MULE */
651   p = (unsigned char**) buf;
652   n = jrKanjiControl (0, KC_PARSE,  (char *) &p);
653   val = Qnil;
654   while (n > 0)
655     {
656       n--;
657       val = Fcons (make_string (p[n], strlen (p[n])), val);
658     }
659   return val;
660 }
661
662 DEFUN ("canna-query-mode", Fcanna_query_mode, 0, 0, 0, /*
663 Get current mode string.
664 */
665        ())
666 {
667   unsigned char buf[256];
668
669   jrKanjiControl (0, KC_QUERYMODE, buf);
670   return make_string (buf, strlen (buf));
671 }
672
673 /*
674  * Functions following this line are for KKCP interface compatible
675  * library.  These functions may be used by MILK system.
676  */
677
678 #define RKBUFSIZE 1024
679
680 static unsigned char yomibuf[RKBUFSIZE];
681 static short kugiri[RKBUFSIZE / 2];
682
683 static int
684 confirmContext (void)
685 {
686   if (IRCP_context < 0)
687     {
688       int context;
689
690       if ((context = jrKanjiControl (0, KC_GETCONTEXT, (char *) 0)) == -1)
691         {
692           return 0;
693         }
694       IRCP_context = context;
695     }
696   return 1;
697 }
698
699 static int
700 byteLen (int bun, int len)
701 {
702   int i = 0, offset = 0, ch;
703
704   if (0 <= bun && bun < RKBUFSIZE)
705     {
706       offset = kugiri[bun];
707     }
708
709   while (len-- > 0 && (ch = (int) yomibuf[offset + i]))
710     {
711       i++;
712       if (ch & 0x80)
713         {
714           i++;
715         }
716     }
717   return i;
718 }
719
720 DEFUN ("canna-henkan-begin", Fcanna_henkan_begin, 1, 1, 0, /*
721 ¤«¤Ê´Á»úÊÑ´¹¤·¤¿·ë²Ì¤òÊÖ´Ô¤¹¤ë¡£Ê¸ÀáÀڤ꤬¤·¤Æ¤¢¤ë¡£
722 */
723        (yomi))
724 {
725   int nbun;
726
727   CHECK_STRING (yomi);
728   if (confirmContext () == 0)
729     {
730       return Qnil;
731     }
732 #ifndef CANNA_MULE
733   strncpy (yomibuf, XSTRING (yomi)->_data, XSTRING (yomi)->_size);
734   yomibuf[XSTRING (yomi)->_size] = '\0';
735   nbun = RkBgnBun (IRCP_context, XSTRING (yomi)->_data, XSTRING (yomi)->_size,
736                    (RK_XFER << RK_XFERBITS) | RK_KFER);
737 #else /* CANNA_MULE */
738   m2c (XSTRING (yomi)->_data, XSTRING (yomi)->_size, yomibuf);
739   nbun = RkBgnBun (IRCP_context, (char *) yomibuf, strlen (yomibuf),
740                    (RK_XFER << RK_XFERBITS) | RK_KFER);
741 #endif /* CANNA_MULE */
742
743   return kanjiYomiList (IRCP_context, nbun);
744 }
745
746 static Lisp_Object
747 kanjiYomiList (int context, int nbun)
748 {
749   Lisp_Object val, res = Qnil;
750   unsigned char RkBuf[RKBUFSIZE];
751   int len, i, total;
752
753   for (i = nbun ; i > 0 ; )
754     {
755       i--;
756       RkGoTo (context, i);
757       len = RkGetKanji (context, RkBuf, RKBUFSIZE);
758       val = make_string (RkBuf, len);
759       len = RkGetYomi (context, RkBuf, RKBUFSIZE);
760       res = Fcons (Fcons (val, make_string (RkBuf, len)), res);
761       if (i < RKBUFSIZE / 2)
762         {
763           kugiri[i] = len;
764         }
765     }
766   for (i = 0, total = 0 ; i < nbun ; i++)
767     {
768       int temp = kugiri[i];
769       kugiri[i] = total;
770       total += temp;
771     }
772   return res;
773 }
774
775 DEFUN ("canna-henkan-next", Fcanna_henkan_next, 1, 1, 0, /*
776 ¸õÊä°ìÍ÷¤òµá¤á¤ë¡£
777 */
778        (bunsetsu))
779 {
780   int i, slen, len;
781   unsigned char *p, RkBuf[RKBUFSIZE];
782   Lisp_Object res = Qnil, endp;
783
784   CHECK_INT (bunsetsu);
785   if (confirmContext () == 0)
786     {
787       return Qnil;
788     }
789   RkGoTo (IRCP_context, XINT (bunsetsu));
790   len = RkGetKanjiList (IRCP_context, RkBuf, RKBUFSIZE);
791   p = RkBuf;
792   for (i = 0 ; i < len ; i++)
793     {
794       slen = strlen (p);
795       if (NILP(res))
796         {
797           endp = res = Fcons (make_string (p, slen), Qnil);
798         }
799       else
800         {
801           endp = XCDR (endp) = Fcons (make_string (p, slen), Qnil);
802         }
803       p += slen + 1;
804     }
805   return res;
806 }
807
808 DEFUN ("canna-bunsetu-henkou", Fcanna_bunsetu_henkou, 2, 2, 0, /*
809 ʸÀá¤ÎŤµ¤ò»ØÄꤹ¤ë¡£
810 */
811        (bunsetsu, bunlen))
812 {
813   int nbun, len;
814
815   CHECK_INT (bunsetsu);
816   CHECK_INT (bunlen);
817   
818   nbun = XINT (bunsetsu);
819   if (confirmContext () == 0)
820     {
821       return Qnil;
822     }
823   RkGoTo (IRCP_context, nbun);
824   len = byteLen (nbun, XINT (bunlen));
825   return kanjiYomiList (IRCP_context, RkResize (IRCP_context, len));
826 }
827
828 DEFUN ("canna-henkan-kakutei", Fcanna_henkan_kakutei, 2, 2, 0, /*
829 ¸õÊäÁªÂò¡£
830 */
831        (bun, kouho))
832 {
833   int nbun, nkouho;
834
835   if (confirmContext () == 0)
836     {
837       return Qnil;
838     }
839   nbun = XINT(bun);
840   RkGoTo (IRCP_context, nbun);
841
842   nkouho = XINT(kouho);
843   RkXfer (IRCP_context, nkouho);
844   return Qt;
845 }
846
847 DEFUN ("canna-henkan-end", Fcanna_henkan_end, 0, 0, 0, /*
848 ÊÑ´¹½ªÎ»¡£
849 */
850        ())
851 {
852   if (confirmContext () == 0)
853     {
854       return Qnil;
855     }
856   RkEndBun (IRCP_context, 1); /* ³Ø½¬¤Ï¤¤¤Ä¤Ç¤â¹Ô¤Ã¤ÆÎɤ¤¤â¤Î¤Ê¤Î¤«¡© */
857   return Qt;
858 }
859
860 DEFUN ("canna-henkan-quit", Fcanna_henkan_quit, 0, 0, 0, /*
861 ÊÑ´¹½ªÎ»¡£
862 */
863        ())
864 {
865   if (confirmContext () == 0)
866     {
867       return Qnil;
868     }
869   RkEndBun (IRCP_context, 0);
870   return Qt;
871 }
872
873 /* variables below this line is constants of Canna */
874
875 static int Vcanna_mode_AlphaMode = IROHA_MODE_AlphaMode;
876 static int Vcanna_mode_EmptyMode = IROHA_MODE_EmptyMode;
877 static int Vcanna_mode_KigoMode = IROHA_MODE_KigoMode;
878 static int Vcanna_mode_YomiMode = IROHA_MODE_YomiMode;
879 static int Vcanna_mode_JishuMode = IROHA_MODE_JishuMode;
880 static int Vcanna_mode_TankouhoMode = IROHA_MODE_TankouhoMode;
881 static int Vcanna_mode_IchiranMode = IROHA_MODE_IchiranMode;
882 static int Vcanna_mode_YesNoMode = IROHA_MODE_YesNoMode;
883 static int Vcanna_mode_OnOffMode = IROHA_MODE_OnOffMode;
884 #ifdef CANNA_MODE_AdjustBunsetsuMode
885 static int Vcanna_mode_AdjustBunsetsuMode = CANNA_MODE_AdjustBunsetsuMode;
886 #endif
887 #ifdef CANNA_MODE_ChikujiYomiMode
888 static int Vcanna_mode_ChikujiYomiMode = CANNA_MODE_ChikujiYomiMode;
889 static int Vcanna_mode_ChikujiTanMode = CANNA_MODE_ChikujiTanMode;
890 #endif
891
892 static int Vcanna_mode_HenkanMode = IROHA_MODE_HenkanMode;
893 #ifdef CANNA_MODE_HenkanNyuryokuMode
894 static int Vcanna_mode_HenkanNyuryokuMode = CANNA_MODE_HenkanNyuryokuMode;
895 #endif
896 #ifdef CANNA_MODE_ZenHiraHenkanMode
897 static int Vcanna_mode_ZenHiraHenkanMode = CANNA_MODE_ZenHiraHenkanMode;
898 #ifdef CANNA_MODE_HanHiraHenkanMode
899 static int Vcanna_mode_HanHiraHenkanMode = CANNA_MODE_HanHiraHenkanMode;
900 #endif
901 static int Vcanna_mode_ZenKataHenkanMode = CANNA_MODE_ZenKataHenkanMode;
902 static int Vcanna_mode_HanKataHenkanMode = CANNA_MODE_HanKataHenkanMode;
903 static int Vcanna_mode_ZenAlphaHenkanMode = CANNA_MODE_ZenAlphaHenkanMode;
904 static int Vcanna_mode_HanAlphaHenkanMode = CANNA_MODE_HanAlphaHenkanMode;
905 #endif
906 static int Vcanna_mode_ZenHiraKakuteiMode = IROHA_MODE_ZenHiraKakuteiMode;
907 #ifdef CANNA_MODE_HanHiraKakuteiMode
908 static int Vcanna_mode_HanHiraKakuteiMode = CANNA_MODE_HanHiraKakuteiMode;
909 #endif
910 static int Vcanna_mode_ZenKataKakuteiMode = IROHA_MODE_ZenKataKakuteiMode;
911 static int Vcanna_mode_HanKataKakuteiMode = IROHA_MODE_HanKataKakuteiMode;
912 static int Vcanna_mode_ZenAlphaKakuteiMode = IROHA_MODE_ZenAlphaKakuteiMode;
913 static int Vcanna_mode_HanAlphaKakuteiMode = IROHA_MODE_HanAlphaKakuteiMode;
914 static int Vcanna_mode_HexMode = IROHA_MODE_HexMode;
915 static int Vcanna_mode_BushuMode = IROHA_MODE_BushuMode;
916 static int Vcanna_mode_ExtendMode = IROHA_MODE_ExtendMode;
917 static int Vcanna_mode_RussianMode = IROHA_MODE_RussianMode;
918 static int Vcanna_mode_GreekMode = IROHA_MODE_GreekMode;
919 static int Vcanna_mode_LineMode = IROHA_MODE_LineMode;
920 static int Vcanna_mode_ChangingServerMode = IROHA_MODE_ChangingServerMode;
921 static int Vcanna_mode_HenkanMethodMode = IROHA_MODE_HenkanMethodMode;
922 static int Vcanna_mode_DeleteDicMode = IROHA_MODE_DeleteDicMode;
923 static int Vcanna_mode_TourokuMode = IROHA_MODE_TourokuMode;
924 static int Vcanna_mode_TourokuEmptyMode = IROHA_MODE_TourokuEmptyMode;
925 static int Vcanna_mode_TourokuHinshiMode = IROHA_MODE_TourokuHinshiMode;
926 static int Vcanna_mode_TourokuDicMode = IROHA_MODE_TourokuDicMode;
927 static int Vcanna_mode_QuotedInsertMode = IROHA_MODE_QuotedInsertMode;
928 static int Vcanna_mode_BubunMuhenkanMode = IROHA_MODE_BubunMuhenkanMode;
929 static int Vcanna_mode_MountDicMode = IROHA_MODE_MountDicMode;
930
931 static int Vcanna_fn_SelfInsert = IROHA_FN_SelfInsert;
932 static int Vcanna_fn_FunctionalInsert = IROHA_FN_FunctionalInsert;
933 static int Vcanna_fn_QuotedInsert = IROHA_FN_QuotedInsert;
934 static int Vcanna_fn_JapaneseMode = IROHA_FN_JapaneseMode;
935 static int Vcanna_fn_AlphaMode = IROHA_FN_AlphaMode;
936 static int Vcanna_fn_HenkanNyuryokuMode = IROHA_FN_HenkanNyuryokuMode;
937 static int Vcanna_fn_Forward = IROHA_FN_Forward;
938 static int Vcanna_fn_Backward = IROHA_FN_Backward;
939 static int Vcanna_fn_Next = IROHA_FN_Next;
940 static int Vcanna_fn_Prev = IROHA_FN_Prev;
941 static int Vcanna_fn_BeginningOfLine = IROHA_FN_BeginningOfLine;
942 static int Vcanna_fn_EndOfLine = IROHA_FN_EndOfLine;
943 static int Vcanna_fn_DeleteNext = IROHA_FN_DeleteNext;
944 static int Vcanna_fn_DeletePrevious = IROHA_FN_DeletePrevious;
945 static int Vcanna_fn_KillToEndOfLine = IROHA_FN_KillToEndOfLine;
946 static int Vcanna_fn_Henkan = IROHA_FN_Henkan;
947 static int Vcanna_fn_Kakutei = IROHA_FN_Kakutei;
948 static int Vcanna_fn_Extend = IROHA_FN_Extend;
949 static int Vcanna_fn_Shrink = IROHA_FN_Shrink;
950 #ifdef CANNA_FN_AdjustBunsetsu
951 static int Vcanna_fn_AdjustBunsetsu = CANNA_FN_AdjustBunsetsu;
952 #endif
953 static int Vcanna_fn_Quit = IROHA_FN_Quit;
954 static int Vcanna_fn_ConvertAsHex = IROHA_FN_ConvertAsHex;
955 static int Vcanna_fn_ConvertAsBushu = IROHA_FN_ConvertAsBushu;
956 static int Vcanna_fn_KouhoIchiran = IROHA_FN_KouhoIchiran;
957 static int Vcanna_fn_BubunMuhenkan = IROHA_FN_BubunMuhenkan;
958 static int Vcanna_fn_Zenkaku = IROHA_FN_Zenkaku;
959 static int Vcanna_fn_Hankaku = IROHA_FN_Hankaku;
960 static int Vcanna_fn_ToUpper = IROHA_FN_ToUpper;
961 static int Vcanna_fn_Capitalize = IROHA_FN_Capitalize;
962 static int Vcanna_fn_ToLower = IROHA_FN_ToLower;
963 static int Vcanna_fn_Hiragana = IROHA_FN_Hiragana;
964 static int Vcanna_fn_Katakana = IROHA_FN_Katakana;
965 static int Vcanna_fn_Romaji = IROHA_FN_Romaji;
966 #ifdef CANNA_FN_BaseHiragana
967 static int Vcanna_fn_BaseHiragana = CANNA_FN_BaseHiragana;
968 static int Vcanna_fn_BaseKatakana = CANNA_FN_BaseKatakana;
969 static int Vcanna_fn_BaseEisu = CANNA_FN_BaseEisu;
970 static int Vcanna_fn_BaseZenkaku = CANNA_FN_BaseZenkaku;
971 static int Vcanna_fn_BaseHankaku = CANNA_FN_BaseHankaku;
972 static int Vcanna_fn_BaseKana = CANNA_FN_BaseKana;
973 static int Vcanna_fn_BaseKakutei = CANNA_FN_BaseKakutei;
974 static int Vcanna_fn_BaseHenkan = CANNA_FN_BaseHenkan;
975 static int Vcanna_fn_BaseHiraKataToggle = CANNA_FN_BaseHiraKataToggle;
976 static int Vcanna_fn_BaseZenHanToggle = CANNA_FN_BaseZenHanToggle;
977 static int Vcanna_fn_BaseKanaEisuToggle = CANNA_FN_BaseKanaEisuToggle;
978 static int Vcanna_fn_BaseKakuteiHenkanToggle =
979   CANNA_FN_BaseKakuteiHenkanToggle;
980 static int Vcanna_fn_BaseRotateForward = CANNA_FN_BaseRotateForward;
981 static int Vcanna_fn_BaseRotateBackward = CANNA_FN_BaseRotateBackward;
982 #endif
983 static int Vcanna_fn_ExtendMode = IROHA_FN_ExtendMode;
984 static int Vcanna_fn_Touroku = IROHA_FN_Touroku;
985 static int Vcanna_fn_HexMode = IROHA_FN_HexMode;
986 static int Vcanna_fn_BushuMode = IROHA_FN_BushuMode;
987 static int Vcanna_fn_KigouMode = IROHA_FN_KigouMode;
988 #ifdef CANNA_FN_Mark
989 static int Vcanna_fn_Mark = CANNA_FN_Mark;
990 #endif
991 #ifdef CANNA_FN_TemporalMode
992 static int Vcanna_fn_TemporalMode = CANNA_FN_TemporalMode;
993 #endif
994
995 static int Vcanna_key_Nfer = IROHA_KEY_Nfer;
996 static int Vcanna_key_Xfer = IROHA_KEY_Xfer;
997 static int Vcanna_key_Up = IROHA_KEY_Up;
998 static int Vcanna_key_Left = IROHA_KEY_Left;
999 static int Vcanna_key_Right = IROHA_KEY_Right;
1000 static int Vcanna_key_Down = IROHA_KEY_Down;
1001 static int Vcanna_key_Insert = IROHA_KEY_Insert;
1002 static int Vcanna_key_Rollup = IROHA_KEY_Rollup;
1003 static int Vcanna_key_Rolldown = IROHA_KEY_Rolldown;
1004 static int Vcanna_key_Home = IROHA_KEY_Home;
1005 static int Vcanna_key_Help = IROHA_KEY_Help;
1006 static int Vcanna_key_KP_Key = IROHA_KEY_KP_Key;
1007 static int Vcanna_key_Shift_Nfer = IROHA_KEY_Shift_Nfer;
1008 static int Vcanna_key_Shift_Xfer = IROHA_KEY_Shift_Xfer;
1009 static int Vcanna_key_Shift_Up = IROHA_KEY_Shift_Up;
1010 static int Vcanna_key_Shift_Left = IROHA_KEY_Shift_Left;
1011 static int Vcanna_key_Shift_Right = IROHA_KEY_Shift_Right;
1012 static int Vcanna_key_Shift_Down = IROHA_KEY_Shift_Down;
1013 static int Vcanna_key_Cntrl_Nfer = IROHA_KEY_Cntrl_Nfer;
1014 static int Vcanna_key_Cntrl_Xfer = IROHA_KEY_Cntrl_Xfer;
1015 static int Vcanna_key_Cntrl_Up = IROHA_KEY_Cntrl_Up;
1016 static int Vcanna_key_Cntrl_Left = IROHA_KEY_Cntrl_Left;
1017 static int Vcanna_key_Cntrl_Right = IROHA_KEY_Cntrl_Right;
1018 static int Vcanna_key_Cntrl_Down = IROHA_KEY_Cntrl_Down;
1019
1020 Lisp_Object VCANNA; /* by MORIOKA Tomohiko <morioka@jaist.ac.jp>
1021                           1996/6/7 */
1022
1023 void
1024 syms_of_mule_canna (void)
1025 {
1026   DEFVAR_LISP ("CANNA", &VCANNA);               /* hir@nec, 1992.5.21 */
1027   VCANNA = Qt;                                  /* hir@nec, 1992.5.21 */
1028   
1029   DEFSUBR (Fcanna_key_proc);
1030   DEFSUBR (Fcanna_initialize);
1031   DEFSUBR (Fcanna_finalize);
1032   DEFSUBR (Fcanna_touroku_string);
1033   DEFSUBR (Fcanna_set_width);
1034   DEFSUBR (Fcanna_change_mode);
1035   DEFSUBR (Fcanna_store_yomi);
1036   DEFSUBR (Fcanna_do_function);
1037   DEFSUBR (Fcanna_parse);
1038   DEFSUBR (Fcanna_query_mode);
1039   DEFSUBR (Fcanna_set_bunsetsu);
1040
1041   DEFSUBR (Fcanna_henkan_begin);
1042   DEFSUBR (Fcanna_henkan_next);
1043   DEFSUBR (Fcanna_bunsetu_henkou);
1044   DEFSUBR (Fcanna_henkan_kakutei);
1045   DEFSUBR (Fcanna_henkan_end);
1046   DEFSUBR (Fcanna_henkan_quit);
1047 }
1048
1049 void
1050 vars_of_mule_canna (void)
1051 {
1052   DEFVAR_LISP ("canna-kakutei-string", &Vcanna_kakutei_string /*
1053
1054 */ );
1055   DEFVAR_LISP ("canna-kakutei-yomi",   &Vcanna_kakutei_yomi /*
1056
1057 */ );
1058   DEFVAR_LISP ("canna-kakutei-romaji", &Vcanna_kakutei_romaji /*
1059
1060 */ );
1061   DEFVAR_LISP ("canna-henkan-string",  &Vcanna_henkan_string /*
1062
1063 */ );
1064   DEFVAR_INT ("canna-henkan-length",  &Vcanna_henkan_length /*
1065
1066 */ );
1067   DEFVAR_INT ("canna-henkan-revpos",  &Vcanna_henkan_revPos /*
1068
1069 */ );
1070   DEFVAR_INT ("canna-henkan-revlen",  &Vcanna_henkan_revLen /*
1071
1072 */ );
1073   DEFVAR_LISP ("canna-ichiran-string", &Vcanna_ichiran_string /*
1074
1075 */ );
1076   DEFVAR_INT ("canna-ichiran-length", &Vcanna_ichiran_length /*
1077
1078 */ );
1079   DEFVAR_INT ("canna-ichiran-revpos", &Vcanna_ichiran_revPos /*
1080
1081 */ );
1082   DEFVAR_INT ("canna-ichiran-revlen", &Vcanna_ichiran_revLen /*
1083
1084 */ );
1085   DEFVAR_LISP ("canna-mode-string",    &Vcanna_mode_string /*
1086
1087 */ );
1088
1089   DEFVAR_BOOL ("canna-empty-info", &Vcanna_empty_info /*
1090 For canna
1091 */ );
1092   DEFVAR_BOOL ("canna-through-info", &Vcanna_through_info /*
1093 For canna
1094 */ );
1095   DEFVAR_BOOL ("canna-underline", &Vcanna_underline /*
1096 For canna
1097 */ );
1098   DEFVAR_BOOL ("canna-inhibit-hankakukana", &Vcanna_inhibit_hankakukana /*
1099 For canna
1100 */ );
1101
1102   DEFVAR_INT ("canna-mode-alpha-mode", &Vcanna_mode_AlphaMode /*
1103
1104 */ );
1105   DEFVAR_INT ("canna-mode-empty-mode", &Vcanna_mode_EmptyMode /*
1106
1107 */ );
1108   DEFVAR_INT ("canna-mode-kigo-mode",  &Vcanna_mode_KigoMode /*
1109
1110 */ );
1111   DEFVAR_INT ("canna-mode-yomi-mode",  &Vcanna_mode_YomiMode /*
1112
1113 */ );
1114   DEFVAR_INT ("canna-mode-jishu-mode", &Vcanna_mode_JishuMode /*
1115
1116 */ );
1117   DEFVAR_INT ("canna-mode-tankouho-mode", &Vcanna_mode_TankouhoMode /*
1118
1119 */ );
1120   DEFVAR_INT ("canna-mode-ichiran-mode",  &Vcanna_mode_IchiranMode /*
1121
1122 */ );
1123   DEFVAR_INT ("canna-mode-yes-no-mode", &Vcanna_mode_YesNoMode /*
1124
1125 */ );
1126   DEFVAR_INT ("canna-mode-on-off-mode", &Vcanna_mode_OnOffMode /*
1127
1128 */ );
1129 #ifdef CANNA_MODE_AdjustBunsetsuMode
1130   DEFVAR_INT ("canna-mode-adjust-bunsetsu-mode",
1131               &Vcanna_mode_AdjustBunsetsuMode /*
1132
1133 */ );
1134 #endif
1135 #ifdef CANNA_MODE_ChikujiYomiMode
1136   DEFVAR_INT ("canna-mode-chikuji-yomi-mode", &Vcanna_mode_ChikujiYomiMode /*
1137
1138 */ );
1139   DEFVAR_INT ("canna-mode-chikuji-bunsetsu-mode",
1140               &Vcanna_mode_ChikujiTanMode /*
1141
1142 */ );
1143 #endif
1144
1145   DEFVAR_INT ("canna-mode-henkan-mode", &Vcanna_mode_HenkanMode /*
1146
1147 */ );
1148 #ifdef CANNA_MODE_HenkanNyuryokuMode
1149   DEFVAR_INT ("canna-mode-henkan-nyuuryoku-mode",
1150               &Vcanna_mode_HenkanNyuryokuMode /*
1151
1152 */ );
1153 #endif
1154 #ifdef CANNA_MODE_ZenHiraHenkanMode
1155   DEFVAR_INT ("canna-mode-zen-hira-henkan-mode",
1156               &Vcanna_mode_ZenHiraHenkanMode /*
1157
1158 */ );
1159 #ifdef CANNA_MODE_HanHiraHenkanMode
1160   DEFVAR_INT ("canna-mode-han-hira-henkan-mode",
1161               &Vcanna_mode_HanHiraHenkanMode /*
1162
1163 */ );
1164 #endif
1165   DEFVAR_INT ("canna-mode-zen-kata-henkan-mode",
1166               &Vcanna_mode_ZenKataHenkanMode /*
1167
1168 */ );
1169   DEFVAR_INT ("canna-mode-han-kata-henkan-mode",
1170               &Vcanna_mode_HanKataHenkanMode /*
1171
1172 */ );
1173   DEFVAR_INT ("canna-mode-zen-alpha-henkan-mode",
1174               &Vcanna_mode_ZenAlphaHenkanMode /*
1175
1176 */ );
1177   DEFVAR_INT ("canna-mode-han-alpha-henkan-mode",
1178               &Vcanna_mode_HanAlphaHenkanMode /*
1179
1180 */ );
1181 #endif
1182   DEFVAR_INT ("canna-mode-zen-hira-kakutei-mode",
1183               &Vcanna_mode_ZenHiraKakuteiMode /*
1184
1185 */ );
1186 #ifdef CANNA_MODE_HanHiraKakuteiMode
1187   DEFVAR_INT ("canna-mode-han-hira-kakutei-mode",
1188               &Vcanna_mode_HanHiraKakuteiMode /*
1189
1190 */ );
1191 #endif
1192   DEFVAR_INT ("canna-mode-zen-kata-kakutei-mode",
1193               &Vcanna_mode_ZenKataKakuteiMode /*
1194
1195 */ );
1196   DEFVAR_INT ("canna-mode-han-kata-kakutei-mode",
1197               &Vcanna_mode_HanKataKakuteiMode /*
1198
1199 */ );
1200   DEFVAR_INT ("canna-mode-zen-alpha-kakutei-mode",
1201               &Vcanna_mode_ZenAlphaKakuteiMode /*
1202
1203 */ );
1204   DEFVAR_INT ("canna-mode-han-alpha-kakutei-mode",
1205               &Vcanna_mode_HanAlphaKakuteiMode /*
1206
1207 */ );
1208   DEFVAR_INT ("canna-mode-hex-mode", &Vcanna_mode_HexMode /*
1209
1210 */ );
1211   DEFVAR_INT ("canna-mode-bushu-mode", &Vcanna_mode_BushuMode /*
1212
1213 */ );
1214   DEFVAR_INT ("canna-mode-extend-mode", &Vcanna_mode_ExtendMode /*
1215
1216 */ );
1217   DEFVAR_INT ("canna-mode-russian-mode", &Vcanna_mode_RussianMode /*
1218
1219 */ );
1220   DEFVAR_INT ("canna-mode-greek-mode", &Vcanna_mode_GreekMode /*
1221
1222 */ );
1223   DEFVAR_INT ("canna-mode-line-mode", &Vcanna_mode_LineMode /*
1224
1225 */ );
1226   DEFVAR_INT ("canna-mode-changing-server-mode",
1227               &Vcanna_mode_ChangingServerMode /*
1228
1229 */ );
1230   DEFVAR_INT ("canna-mode-henkan-method-mode",
1231               &Vcanna_mode_HenkanMethodMode /*
1232
1233 */ );
1234   DEFVAR_INT ("canna-mode-delete-dic-mode", &Vcanna_mode_DeleteDicMode /*
1235
1236 */ );
1237   DEFVAR_INT ("canna-mode-touroku-mode", &Vcanna_mode_TourokuMode /*
1238
1239 */ );
1240   DEFVAR_INT ("canna-mode-touroku-empty-mode",
1241               &Vcanna_mode_TourokuEmptyMode /*
1242
1243 */ );
1244   DEFVAR_INT ("canna-mode-touroku-hinshi-mode",
1245               &Vcanna_mode_TourokuHinshiMode /*
1246
1247 */ );
1248   DEFVAR_INT ("canna-mode-touroku-dic-mode", &Vcanna_mode_TourokuDicMode /*
1249
1250 */ );
1251   DEFVAR_INT ("canna-mode-quoted-insert-mode",
1252               &Vcanna_mode_QuotedInsertMode /*
1253
1254 */ );
1255   DEFVAR_INT ("canna-mode-bubun-muhenkan-mode",
1256               &Vcanna_mode_BubunMuhenkanMode /*
1257
1258 */ );
1259   DEFVAR_INT ("canna-mode-mount-dic-mode", &Vcanna_mode_MountDicMode /*
1260
1261 */ );
1262
1263   DEFVAR_INT ("canna-func-self-insert", &Vcanna_fn_SelfInsert  /*
1264
1265 */ );
1266   DEFVAR_INT ("canna-func-functional-insert", &Vcanna_fn_FunctionalInsert  /*
1267
1268 */ );
1269   DEFVAR_INT ("canna-func-quoted-insert", &Vcanna_fn_QuotedInsert  /*
1270
1271 */ );
1272   DEFVAR_INT ("canna-func-japanese-mode", &Vcanna_fn_JapaneseMode  /*
1273
1274 */ );
1275   DEFVAR_INT ("canna-func-alpha-mode", &Vcanna_fn_AlphaMode  /*
1276
1277 */ );
1278   DEFVAR_INT ("canna-func-henkan-nyuryoku-mode",
1279               &Vcanna_fn_HenkanNyuryokuMode  /*
1280
1281 */ );
1282   DEFVAR_INT ("canna-func-forward", &Vcanna_fn_Forward  /*
1283
1284 */ );
1285   DEFVAR_INT ("canna-func-backward", &Vcanna_fn_Backward  /*
1286
1287 */ );
1288   DEFVAR_INT ("canna-func-next", &Vcanna_fn_Next  /*
1289
1290 */ );
1291   DEFVAR_INT ("canna-func-previous", &Vcanna_fn_Prev  /*
1292
1293 */ );
1294   DEFVAR_INT ("canna-func-beginning-of-line", &Vcanna_fn_BeginningOfLine  /*
1295
1296 */ );
1297   DEFVAR_INT ("canna-func-end-of-line", &Vcanna_fn_EndOfLine  /*
1298
1299 */ );
1300   DEFVAR_INT ("canna-func-delete-next", &Vcanna_fn_DeleteNext  /*
1301
1302 */ );
1303   DEFVAR_INT ("canna-func-delete_previous", &Vcanna_fn_DeletePrevious  /*
1304
1305 */ );
1306   DEFVAR_INT ("canna-func-kill-to-end-of-line", &Vcanna_fn_KillToEndOfLine /*
1307
1308 */ );
1309   DEFVAR_INT ("canna-func-henkan", &Vcanna_fn_Henkan  /*
1310
1311 */ );
1312   DEFVAR_INT ("canna-func-kakutei", &Vcanna_fn_Kakutei  /*
1313
1314 */ );
1315   DEFVAR_INT ("canna-func-extend", &Vcanna_fn_Extend  /*
1316
1317 */ );
1318   DEFVAR_INT ("canna-func-shrink", &Vcanna_fn_Shrink  /*
1319
1320 */ );
1321 #ifdef CANNA_FN_AdjustBunsetsu
1322   DEFVAR_INT ("canna-func-adjust-bunsetsu", &Vcanna_fn_AdjustBunsetsu  /*
1323
1324 */ );
1325 #endif
1326   DEFVAR_INT ("canna-func-quit", &Vcanna_fn_Quit  /*
1327
1328 */ );
1329   DEFVAR_INT ("canna-func-convert-as-hex", &Vcanna_fn_ConvertAsHex  /*
1330
1331 */ );
1332   DEFVAR_INT ("canna-func-convert-as-bushu", &Vcanna_fn_ConvertAsBushu  /*
1333
1334 */ );
1335   DEFVAR_INT ("canna-func-kouho-ichiran", &Vcanna_fn_KouhoIchiran  /*
1336
1337 */ );
1338   DEFVAR_INT ("canna-func-bubun-muhenkan", &Vcanna_fn_BubunMuhenkan  /*
1339
1340 */ );
1341   DEFVAR_INT ("canna-func-zenkaku", &Vcanna_fn_Zenkaku  /*
1342
1343 */ );
1344   DEFVAR_INT ("canna-func-hankaku", &Vcanna_fn_Hankaku  /*
1345
1346 */ );
1347   DEFVAR_INT ("canna-func-to-upper", &Vcanna_fn_ToUpper  /*
1348
1349 */ );
1350   DEFVAR_INT ("canna-func-capitalize", &Vcanna_fn_Capitalize  /*
1351
1352 */ );
1353   DEFVAR_INT ("canna-func-to-lower", &Vcanna_fn_ToLower  /*
1354
1355 */ );
1356   DEFVAR_INT ("canna-func-hiragana", &Vcanna_fn_Hiragana  /*
1357
1358 */ );
1359   DEFVAR_INT ("canna-func-katakana", &Vcanna_fn_Katakana  /*
1360
1361 */ );
1362   DEFVAR_INT ("canna-func-romaji", &Vcanna_fn_Romaji  /*
1363
1364 */ );
1365 #ifdef CANNA_FN_BaseHiragana
1366   DEFVAR_INT ("canna-func-base-hiragana", &Vcanna_fn_BaseHiragana  /*
1367
1368 */ );
1369   DEFVAR_INT ("canna-func-base-katakana", &Vcanna_fn_BaseKatakana  /*
1370
1371 */ );
1372   DEFVAR_INT ("canna-func-base-eisu", &Vcanna_fn_BaseEisu  /*
1373
1374 */ );
1375   DEFVAR_INT ("canna-func-base-zenkaku", &Vcanna_fn_BaseZenkaku  /*
1376
1377 */ );
1378   DEFVAR_INT ("canna-func-base-hankaku", &Vcanna_fn_BaseHankaku  /*
1379
1380 */ );
1381   DEFVAR_INT ("canna-func-base-kana", &Vcanna_fn_BaseKana  /*
1382
1383 */ );
1384   DEFVAR_INT ("canna-func-base-kakutei", &Vcanna_fn_BaseKakutei  /*
1385
1386 */ );
1387   DEFVAR_INT ("canna-func-base-henkan", &Vcanna_fn_BaseHenkan  /*
1388
1389 */ );
1390   DEFVAR_INT ("canna-func-base-hiragana-katakana-toggle",
1391               &Vcanna_fn_BaseHiraKataToggle  /*
1392
1393 */ );
1394   DEFVAR_INT ("canna-func-base-zenkaku-hankaku-toggle",
1395               &Vcanna_fn_BaseZenHanToggle  /*
1396
1397 */ );
1398   DEFVAR_INT ("canna-func-base-kana-eisu-toggle",
1399               &Vcanna_fn_BaseKanaEisuToggle  /*
1400
1401 */ );
1402   DEFVAR_INT ("canna-func-base-kakutei-henkan-toggle",
1403               &Vcanna_fn_BaseKakuteiHenkanToggle  /*
1404
1405 */ );
1406   DEFVAR_INT ("canna-func-base-rotate-forward",
1407               &Vcanna_fn_BaseRotateForward  /*
1408
1409 */ );
1410   DEFVAR_INT ("canna-func-base-rotate-backward",
1411               &Vcanna_fn_BaseRotateBackward  /*
1412
1413 */ );
1414 #endif
1415   DEFVAR_INT ("canna-func-extend-mode", &Vcanna_fn_ExtendMode  /*
1416
1417 */ );
1418   DEFVAR_INT ("canna-func-touroku", &Vcanna_fn_Touroku  /*
1419
1420 */ );
1421   DEFVAR_INT ("canna-func-hex-mode", &Vcanna_fn_HexMode  /*
1422
1423 */ );
1424   DEFVAR_INT ("canna-func-bushu-mode", &Vcanna_fn_BushuMode  /*
1425
1426 */ );
1427   DEFVAR_INT ("canna-func-kigo-mode", &Vcanna_fn_KigouMode  /*
1428
1429 */ );
1430 #ifdef CANNA_FN_Mark
1431   DEFVAR_INT ("canna-func-mark", &Vcanna_fn_Mark  /*
1432
1433 */ );
1434 #endif
1435 #ifdef CANNA_FN_TemporalMode
1436   DEFVAR_INT ("canna-func-temporal-mode", &Vcanna_fn_TemporalMode  /*
1437
1438 */ );
1439 #endif
1440
1441   DEFVAR_INT ("canna-key-nfer", &Vcanna_key_Nfer /*
1442
1443 */ );
1444   DEFVAR_INT ("canna-key-xfer", &Vcanna_key_Xfer /*
1445
1446 */ );
1447   DEFVAR_INT ("canna-key-up", &Vcanna_key_Up /*
1448
1449 */ );
1450   DEFVAR_INT ("canna-key-left", &Vcanna_key_Left /*
1451
1452 */ );
1453   DEFVAR_INT ("canna-key-right", &Vcanna_key_Right /*
1454
1455 */ );
1456   DEFVAR_INT ("canna-key-down", &Vcanna_key_Down /*
1457
1458 */ );
1459   DEFVAR_INT ("canna-key-insert", &Vcanna_key_Insert /*
1460
1461 */ );
1462   DEFVAR_INT ("canna-key-rollup", &Vcanna_key_Rollup /*
1463
1464 */ );
1465   DEFVAR_INT ("canna-key-rolldown", &Vcanna_key_Rolldown /*
1466
1467 */ );
1468   DEFVAR_INT ("canna-key-home", &Vcanna_key_Home /*
1469
1470 */ );
1471   DEFVAR_INT ("canna-key-help", &Vcanna_key_Help /*
1472
1473 */ );
1474   DEFVAR_INT ("canna-key-kp-key", &Vcanna_key_KP_Key /*
1475
1476 */ );
1477   DEFVAR_INT ("canna-key-shift-nfer", &Vcanna_key_Shift_Nfer /*
1478
1479 */ );
1480   DEFVAR_INT ("canna-key-shift-xfer", &Vcanna_key_Shift_Xfer /*
1481
1482 */ );
1483   DEFVAR_INT ("canna-key-shift-up", &Vcanna_key_Shift_Up /*
1484
1485 */ );
1486   DEFVAR_INT ("canna-key-shift-left", &Vcanna_key_Shift_Left /*
1487
1488 */ );
1489   DEFVAR_INT ("canna-key-shift-right", &Vcanna_key_Shift_Right /*
1490
1491 */ );
1492   DEFVAR_INT ("canna-key-shift-down", &Vcanna_key_Shift_Down /*
1493
1494 */ );
1495   DEFVAR_INT ("canna-key-control-nfer", &Vcanna_key_Cntrl_Nfer /*
1496
1497 */ );
1498   DEFVAR_INT ("canna-key-control-xfer", &Vcanna_key_Cntrl_Xfer /*
1499
1500 */ );
1501   DEFVAR_INT ("canna-key-control-up", &Vcanna_key_Cntrl_Up /*
1502
1503 */ );
1504   DEFVAR_INT ("canna-key-control-left", &Vcanna_key_Cntrl_Left /*
1505
1506 */ );
1507   DEFVAR_INT ("canna-key-control-right", &Vcanna_key_Cntrl_Right /*
1508
1509 */ );
1510   DEFVAR_INT ("canna-key-control-down", &Vcanna_key_Cntrl_Down /*
1511
1512 */ );
1513
1514   Fprovide(intern("CANNA"));
1515 }
1516
1517 #ifdef CANNA_MULE
1518 /* To handle MULE internal code and EUC.
1519    I assume CANNA can handle only Japanese EUC. */
1520
1521 /* EUC multibyte string to MULE internal string */
1522
1523 static void
1524 c2mu (char *cp, int l, char *mp)
1525 {
1526   char  ch, *ep = cp+l;
1527   
1528   while ((cp < ep) && (ch = *cp))
1529     {
1530       if ((unsigned char) ch == ISO_CODE_SS2)
1531         {
1532           *mp++ = LEADING_BYTE_KATAKANA_JISX0201;
1533           cp++;
1534         }
1535       else if ((unsigned char) ch == ISO_CODE_SS3)
1536         {
1537           *mp++ = LEADING_BYTE_JAPANESE_JISX0212;
1538           cp++;
1539           *mp++ = *cp++;
1540         }
1541       else if (ch & 0x80)
1542         {
1543           *mp++ = LEADING_BYTE_JAPANESE_JISX0208;
1544           *mp++ = *cp++;
1545         }
1546       *mp++ = *cp++;
1547     }
1548   *mp = 0;
1549 }
1550
1551 /* MULE internal string to EUC multibyte string */
1552
1553 static void
1554 m2c (unsigned char *mp, int l, unsigned char *cp)
1555 {
1556   unsigned char ch, *ep = mp + l;;
1557   
1558   while ((mp < ep) && (ch = *mp++))
1559     {
1560       switch (ch)
1561         {
1562         case LEADING_BYTE_KATAKANA_JISX0201:
1563           *cp++ = ISO_CODE_SS2;
1564           *cp++ = *mp++;
1565           break;
1566         case LEADING_BYTE_JAPANESE_JISX0212:
1567           *cp++ = ISO_CODE_SS3;
1568         case LEADING_BYTE_JAPANESE_JISX0208:
1569           *cp++ = *mp++;
1570           *cp++ = *mp++;
1571           break;
1572         default:
1573           *cp++ = ch;
1574           break;
1575         }
1576     }   
1577   *cp = 0;
1578 }
1579
1580 #undef make_string
1581
1582 /* make_string after converting EUC string to MULE internal string */
1583 static Lisp_Object
1584 mule_make_string (unsigned char *p, int l)
1585 {
1586   unsigned char cbuf[4096];
1587   
1588   c2mu (p,l,cbuf);
1589   return (make_string (cbuf,strlen (cbuf)));
1590 }       
1591
1592 /* return the MULE internal string length of EUC string */
1593 /* Modified by sb to return a character count not byte count. */
1594 static int
1595 mule_strlen (unsigned char *p, int l)
1596 {
1597   unsigned char ch, *cp = p;
1598   int len = 0;
1599   
1600   while ((cp < p + l) && (ch = *cp))
1601     {
1602       if ((unsigned char) ch == ISO_CODE_SS2)
1603         {
1604           len++;
1605           cp += 2;
1606         }
1607       else if ((unsigned char) ch == ISO_CODE_SS3)
1608         {
1609           len++;
1610           cp += 3;
1611         }
1612       else if (ch & 0x80)
1613         {
1614           len++;
1615           cp += 2;
1616         }
1617       else
1618         {
1619           len++;
1620           cp++; 
1621         }
1622     }
1623   return (len);
1624 }
1625
1626 /* count number of characters */
1627 static void
1628 count_char (unsigned char *p, int len, int pos, int rev, int *clen, int *cpos,
1629             int *crev)
1630 {
1631   unsigned char *q = p;
1632   
1633   *clen = *cpos = *crev = 0;
1634   if (len == 0) return;
1635   while (q < p + pos)
1636     {
1637       (*clen)++;
1638       (*cpos)++;
1639       if (*q++ & 0x80) q++;
1640     }
1641   while (q < p + pos + rev)
1642     {
1643       (*clen)++;
1644       (*crev)++;
1645       if (*q++ & 0x80) q++;
1646     }           
1647   while (q < p + len)
1648     {
1649       (*clen)++;
1650       if (*q++ & 0x80) q++;
1651     }
1652 }
1653 #endif /* CANNA_MULE */