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