1 /* Copyright 1992 NEC Corporation, Tokyo, Japan.
2  *
3  * Permission to use, copy, modify, distribute and sell this software
4  * and its documentation for any purpose is hereby granted without
5  * fee, provided that the above copyright notice appear in all copies
6  * and that both that copyright notice and this permission notice
7  * appear in supporting documentation, and that the name of NEC
8  * Corporation not be used in advertising or publicity pertaining to
9  * distribution of the software without specific, written prior
10  * permission.  NEC Corporation makes no representations about the
11  * suitability of this software for any purpose.  It is provided "as
12  * is" without express or implied warranty.
13  *
14  * NEC CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
16  * NO EVENT SHALL NEC CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
18  * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
19  * OTHER TORTUOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20  * PERFORMANCE OF THIS SOFTWARE.
21  */
22 
23 #if !defined(lint) && !defined(__CODECENTER__)
24 static char rcs_id[] = "@(#) 102.1 $Id: keydef.c,v 1.2 2003/09/17 08:50:53 aida_s Exp $";
25 #endif /* lint */
26 
27 #include "canna.h"
28 #include <canna/mfdef.h>
29 #include <canna/keydef.h>
30 
31 extern KanjiModeRec alpha_mode, empty_mode, yomi_mode;
32 extern KanjiModeRec jishu_mode, ce_mode, cy_mode, cb_mode;
33 extern KanjiModeRec tankouho_mode, ichiran_mode, onoff_mode;
34 extern KanjiModeRec khal_mode, khkt_mode, kzal_mode, kzhr_mode, kzkt_mode;
35 extern KanjiModeRec kigo_mode;
36 extern KanjiModeRec tourokureibun_mode;
37 extern KanjiModeRec bunsetsu_mode;
38 extern KanjiModeRec cy_mode, cb_mode;
39 
40 extern multiSequenceFunc
41   pro((struct _uiContext *, struct _kanjiMode *, int, int, int));
42 
43 static void undefineKeyfunc pro((unsigned char *, unsigned));
44 static regist_key_hash(), copyMultiSequence();
45 static void freeMultiSequence();
46 static void clearAllFuncSequence(), clearAllKeySequence();
47 
48 #define NONE 0
49 #define ACTHASHTABLESIZE 64
50 #define KEYHASHTABLESIZE 16
51 
52 #define SINGLE 0
53 #define MULTI  1
54 #define OTHER  2
55 
56 struct  seq_struct{
57   unsigned char    *to_tbl;
58   unsigned char    as_key;
59   unsigned char    *kinou_seq;
60   struct  seq_struct *next;
61 };
62 
63 static struct seq_struct *seq_hash[ACTHASHTABLESIZE];
64 
65 struct map{
66   KanjiMode tbl;
67   unsigned char key;
68   KanjiMode  mode;
69   struct map *next;
70 };
71 
72 static struct map *otherMap[KEYHASHTABLESIZE];
73 
74 static KanjiMode ModeTbl[CANNA_MODE_MAX_REAL_MODE] = {
75   &alpha_mode,        /* AlphaMode          ����ե��٥åȥ⡼��         */
76   &empty_mode,	      /* EmptyMode          �ɤ����Ϥ��ʤ�����           */
77   &kigo_mode,	      /* KigoMode           ���������ɽ�����Ƥ������   */
78   &yomi_mode,         /* YomiMode           �ɤ����Ϥ��Ƥ������         */
79   &jishu_mode,	      /* JishuMode          ʸ�����Ѵ����Ƥ������       */
80   &tankouho_mode,     /* TankouhoMode       ñ��θ����ɽ�����Ƥ������ */
81   &ichiran_mode,      /* IchiranMode        ���������ɽ�����Ƥ������   */
82   &tourokureibun_mode, /* TourokuReibunMode ñ����Ͽ����ʸɽ������       */
83   &onoff_mode,        /* OnOffMode          On/Off�ΰ�����ɽ������       */
84   &bunsetsu_mode,     /* AdjustBunsetsuMode ʸ�῭�̥⡼��               */
85   &cy_mode,	      /* ChikujiYomiMode    �༡�λ����ɤ���ʬ           */
86   &cb_mode,           /* ChikujiHenkanMode  �༡�λ����Ѵ�����ʬ         */
87 };
88 
89 unsigned char *actFromHash();
90 static void regist_act_hash();
91 
92 static unsigned char *
duplicatekmap(kmap)93 duplicatekmap(kmap)
94 unsigned char *kmap;
95 {
96   unsigned char *res;
97   int i;
98 
99   res = (unsigned char *)calloc(256, sizeof(unsigned char));
100   if (res) {
101     for (i = 0 ; i < 256 ; i++) {
102       res[i] = kmap[i];
103     }
104   }
105   return res;
106 }
107 
108 static unsigned char *defaultkeytables[CANNA_MODE_MAX_REAL_MODE];
109 static unsigned char defaultsharing[CANNA_MODE_MAX_REAL_MODE];
110 static unsigned char *defaultmap;
111 unsigned char *alphamap, *emptymap;
112 
113 /* cfuncdef
114 
115   initKeyTables() -- �����ơ��֥����������ؿ���
116 
117   �ǥե���ȤΥ����ơ��֥��Ͽ���Ƥ������»��ѤΥơ��֥�� �ǥե���
118   �ȥơ��֥뤫�饳�ԡ����������Ԥ���
119 
120 */
121 
initKeyTables()122 initKeyTables()
123 {
124   int i;
125   unsigned char *tbl;
126   extern unsigned char default_kmap[], alpha_kmap[], empty_kmap[];
127 
128   defaultmap = duplicatekmap(default_kmap);
129   if (defaultmap) {
130     alphamap   = duplicatekmap(alpha_kmap);
131     if (alphamap) {
132       emptymap   = duplicatekmap(empty_kmap);
133       if (emptymap) {
134         for (i = 0 ; i < CANNA_MODE_MAX_REAL_MODE ; i++) {
135           if (ModeTbl[i]) {
136             defaultsharing[i] = ModeTbl[i]->flags;
137             tbl = defaultkeytables[i] = ModeTbl[i]->keytbl;
138             if (tbl == default_kmap) {
139               ModeTbl[i]->keytbl = defaultmap;
140             }
141             else if (tbl == alpha_kmap) {
142               ModeTbl[i]->keytbl = alphamap;
143             }
144             else if (tbl == empty_kmap) {
145               ModeTbl[i]->keytbl = emptymap;
146             }
147           }
148         }
149         return 0;
150       }
151       free((char *)alphamap);
152     }
153     free((char *)defaultmap);
154   }
155   return NG;
156 }
157 
158 void
restoreDefaultKeymaps()159 restoreDefaultKeymaps()
160 {
161   int i;
162 
163   for (i = 0 ; i < CANNA_MODE_MAX_REAL_MODE ; i++) {
164     if (ModeTbl[i]) {
165       if ( !(ModeTbl[i]->flags & CANNA_KANJIMODE_TABLE_SHARED) ) {
166 	free(ModeTbl[i]->keytbl);
167       }
168       ModeTbl[i]->keytbl = defaultkeytables[i];
169       ModeTbl[i]->flags = defaultsharing[i];
170     }
171   }
172   free(defaultmap);
173   free(alphamap);
174   free(emptymap);
175   clearAllFuncSequence();
176   clearAllKeySequence();
177 }
178 
179 
180 /*
181  * ����⡼�ɤΥ������Ф��ƴؿ��������Ƥ����
182  *
183  */
184 
185 /*
186 
187   �����ʤλ��ϣ�ʸ���ܤ����줿���Υ⡼�ɤˤ����ꤹ�롣
188 
189  */
190 
191 extern nothermodes;
192 
changeKeyfunc(modenum,key,fnum,actbuff,keybuff)193 changeKeyfunc(modenum, key, fnum, actbuff, keybuff)
194 int modenum;
195 int key;
196 int fnum;
197 unsigned char *actbuff, *keybuff;
198 {
199   int i, retval = 0;
200   unsigned char *p, *q;
201   KanjiMode mode;
202   newmode *nmode;
203 
204   /* ����äȾ��ٹ� */
205   if (modenum == CANNA_MODE_HenkanNyuryokuMode) {
206     retval = changeKeyfunc(CANNA_MODE_EmptyMode, key, fnum, actbuff, keybuff);
207     if (retval < 0) {
208       return retval;
209     }
210     modenum = CANNA_MODE_YomiMode;
211   }
212 
213   if (modenum < 0) {
214     return 0;
215   }
216   else if (modenum < CANNA_MODE_MAX_REAL_MODE) {
217     mode = ModeTbl[modenum];
218   }
219   else if (modenum < CANNA_MODE_MAX_IMAGINARY_MODE) {
220     return 0;
221   }
222   else if (modenum < CANNA_MODE_MAX_IMAGINARY_MODE + nothermodes) {
223     nmode = findExtraKanjiMode(modenum);
224     if (!nmode) {
225       return 0;
226     }
227     else {
228       mode = nmode->emode;
229     }
230   }
231   else {
232     return 0;
233   }
234 
235   if (mode && mode->func((uiContext)0/*dummy*/, mode,
236                            KEY_CHECK, 0/*dummy*/, fnum)) {
237     /* ���ε�ǽ�����Υ⡼�ɤˤ�����ͭ���ʵ�ǽ�Ǥ���� */
238     if (mode->keytbl) { /* �����ơ��֥뤬¸�ߤ���� */
239       /* ��������Ф�¸�ߤ���ΤǤϡ� */
240       if (mode->flags & CANNA_KANJIMODE_TABLE_SHARED) {
241 	/* �����ޥåפ�¾�Υ⡼�ɤȶ�ͭ����Ƥ���ʤ� */
242 	p = (unsigned char *)calloc(256, sizeof(unsigned char));
243         if (!p) {
244           return -1;
245         }
246         bcopy(mode->keytbl, p, 256 * sizeof(unsigned char));
247         for (i = 0; i < 256; i++) {
248           if (mode->keytbl[i] == CANNA_FN_FuncSequence) {
249             q = actFromHash(mode->keytbl,i);
250             if (q) { /* �������륭���������������ä��� */
251               regist_act_hash(p, i, q);
252             }
253           }
254           if (mode->keytbl[i] == CANNA_FN_UseOtherKeymap) {
255 	    debug_message("changeKeyfunc:\245\306\241\274\245\326\245\353"
256 		"\260\334\306\260\72\244\263\244\316\244\310\244\255\244\316"
257 		"\245\255\241\274\244\317%d\n",i,0,0);
258                           /* �ơ��֥��ư:���ΤȤ��Υ����� */
259             (void)copyMultiSequence(i, (KanjiMode)mode->keytbl,
260                                        (KanjiMode)p);
261           }
262         }
263         mode->keytbl = p;
264         mode->flags &= ~CANNA_KANJIMODE_TABLE_SHARED;
265         if (modenum == CANNA_MODE_YomiMode &&
266              (ModeTbl[CANNA_MODE_ChikujiYomiMode]->flags
267               & CANNA_KANJIMODE_TABLE_SHARED)) {
268           ModeTbl[CANNA_MODE_ChikujiYomiMode]->keytbl = p;
269         }
270         else if (modenum == CANNA_MODE_TankouhoMode &&
271 	          (ModeTbl[CANNA_MODE_ChikujiTanMode]->flags
272                    & CANNA_KANJIMODE_TABLE_SHARED)) {
273 	  ModeTbl[CANNA_MODE_ChikujiTanMode]->keytbl = p;
274         }
275       }
276       if (key >= 0 && key < 255) {
277         if (mode->keytbl[key] == CANNA_FN_UseOtherKeymap &&
278              fnum != CANNA_FN_UseOtherKeymap)
279           freeMultiSequence(key,(KanjiMode)mode->keytbl);
280         mode->keytbl[key] = fnum;
281         if (fnum == CANNA_FN_FuncSequence) {
282           regist_act_hash(mode->keytbl,key,actbuff);
283         }
284         if (fnum == CANNA_FN_UseOtherKeymap) {
285           retval = regist_key_hash(mode->keytbl,keybuff,actbuff);
286           if (retval) {
287             return retval;
288           }
289         }
290       }
291       else if (key == CANNA_KEY_Undefine) {
292         undefineKeyfunc(mode->keytbl, fnum);
293       }
294     }
295   }
296   return 0;
297 }
298 
299 static int
changeKeyOnSomeCondition(mode,key,fnum,actbuff,keybuff)300 changeKeyOnSomeCondition(mode, key, fnum, actbuff, keybuff)
301 KanjiMode mode;
302 int key, fnum;
303 unsigned char *actbuff, *keybuff;
304 {
305   int retval = 0;
306 
307   if (mode && /* ���Υ⡼�ɤ�¸�ߤ���ʤ� */
308       mode->func((uiContext)0/*dummy*/, mode,
309                    KEY_CHECK, 0/*dummy*/, fnum)) {
310     /* �ؿ������Υ⡼�ɤ�ͭ���ʤ� */
311     if ( !(mode->flags & CANNA_KANJIMODE_TABLE_SHARED) ) {
312       /* �ơ��֥뤬��ͭ����Ƥ��ʤ��ʤ� */
313       if (mode->keytbl) { /* �����ơ��֥뤬¸�ߤ���� */
314 	if (mode->keytbl[key] == CANNA_FN_UseOtherKeymap &&
315 	    fnum != CANNA_FN_UseOtherKeymap)
316 	  freeMultiSequence(key,(KanjiMode)mode->keytbl);
317 	mode->keytbl[key] = fnum;
318 	if (fnum == CANNA_FN_FuncSequence) {
319 	  regist_act_hash(mode->keytbl,key,actbuff);
320 	}
321 	if (fnum == CANNA_FN_UseOtherKeymap) {
322 	  retval = regist_key_hash(mode->keytbl,keybuff,actbuff);
323 	}
324       }
325     }
326   }
327   return retval;
328 }
329 
330 /*
331  * ���ƤΥ⡼�ɤΡ����륭�����Ф��ƴؿ��������Ƥ����
332  *
333  */
334 
changeKeyfuncOfAll(key,fnum,actbuff,keybuff)335 changeKeyfuncOfAll(key, fnum, actbuff, keybuff)
336 int key, fnum;
337 unsigned char *actbuff, *keybuff;
338 {
339   extern extraFunc *extrafuncp;
340   extraFunc *ep;
341   KanjiMode mode;
342   int i, retval = 0;
343 
344   if (key >= 0 && key < 255) {
345     if (defaultmap[key] == CANNA_FN_UseOtherKeymap &&
346 	      fnum != CANNA_FN_UseOtherKeymap)
347       freeMultiSequence(key,(KanjiMode)defaultmap);
348     if (alphamap[key] == CANNA_FN_UseOtherKeymap &&
349 	      fnum != CANNA_FN_UseOtherKeymap)
350       freeMultiSequence(key,(KanjiMode)alphamap);
351     if (emptymap[key] == CANNA_FN_UseOtherKeymap &&
352 	      fnum != CANNA_FN_UseOtherKeymap)
353       freeMultiSequence(key,(KanjiMode)emptymap);
354     defaultmap[key] = fnum;
355     alphamap[key]   = fnum;
356     emptymap[key]   = fnum;
357     if (fnum == CANNA_FN_FuncSequence) {
358       regist_act_hash(defaultmap,key,actbuff);
359       regist_act_hash(alphamap,key,actbuff);
360       regist_act_hash(emptymap,key,actbuff);
361     }
362     if (fnum == CANNA_FN_UseOtherKeymap) {
363       if (regist_key_hash(defaultmap,keybuff,actbuff) == NG ||
364             regist_key_hash(alphamap,keybuff,actbuff) == NG ||
365             regist_key_hash(emptymap,keybuff,actbuff) == NG) {
366         return -1;
367       }
368     }
369     for (i = 0 ; i < CANNA_MODE_MAX_REAL_MODE ; i++) {
370       mode = ModeTbl[i];
371       retval = changeKeyOnSomeCondition(mode, key, fnum, actbuff, keybuff);
372       if (retval < 0) {
373         return retval;
374       }
375     }
376     for (ep = extrafuncp ; ep ; ep = ep->next) {
377       /* defmode �Ǥ����ƤΥ⡼�ɤ��Ф��Ƥ�� */
378       if (ep->keyword == EXTRA_FUNC_DEFMODE) {
379 	retval = changeKeyOnSomeCondition(ep->u.modeptr->emode, key, fnum,
380                                             actbuff, keybuff);
381         if (retval < 0) {
382           return retval;
383         }
384       }
385     }
386   }
387   else if (key == CANNA_KEY_Undefine) {
388     undefineKeyfunc(defaultmap, (unsigned)fnum);
389     undefineKeyfunc(alphamap, (unsigned)fnum);
390     undefineKeyfunc(emptymap, (unsigned)fnum);
391     for (i = 0 ; i < CANNA_MODE_MAX_REAL_MODE ; i++) {
392       mode = ModeTbl[i];
393       if (mode && /* ���Υ⡼�ɤ�¸�ߤ���ʤ� */
394 	  mode->func((uiContext)0/*dummy*/, mode,
395                        KEY_CHECK, 0/*dummy*/, fnum)) {
396 	/* �ؿ������Υ⡼�ɤ�ͭ���ʤ� */
397 	if ( !(mode->flags & CANNA_KANJIMODE_TABLE_SHARED) ) {
398 	  /* �ơ��֥뤬��ͭ����Ƥ��ʤ��ʤ� */
399 	  if (mode->keytbl) { /* �����ơ��֥뤬¸�ߤ���� */
400 	    undefineKeyfunc(mode->keytbl, (unsigned)fnum);
401 	  }
402 	}
403       }
404     }
405   }
406   return retval;
407 }
408 
409 static void
undefineKeyfunc(keytbl,fnum)410 undefineKeyfunc(keytbl, fnum)
411 unsigned char *keytbl;
412 unsigned fnum;
413 {
414   int i;
415 
416   for (i = 0 ; i < ' ' ; i++) {
417     if (keytbl[i] == fnum) {
418       keytbl[i] = CANNA_FN_Undefined;
419     }
420   }
421   for (i = ' ' ; i < 0x7f ; i++) {
422     if (keytbl[i] == fnum) {
423       keytbl[i] = CANNA_FN_FunctionalInsert;
424     }
425   }
426   for (i = 0x7f ; i < 0xa0 ; i++) {
427     if (keytbl[i] == fnum) {
428       keytbl[i] = CANNA_FN_Undefined;
429     }
430   }
431   for (i = 0xa0 ; i < 0xe0 ; i++) {
432     if (keytbl[i] == fnum) {
433       keytbl[i] = CANNA_FN_FunctionalInsert;
434     }
435   }
436   for (i = 0xe0 ; i < 0x100 ; i++) {
437     if (keytbl[i] == fnum) {
438       keytbl[i] = CANNA_FN_Undefined;
439     }
440   }
441 }
442 
443 static unsigned int
createHashKey(data1,data2,which_seq)444 createHashKey(data1, data2, which_seq)
445 unsigned char *data1;
446 unsigned char data2;
447 int which_seq;
448 {
449   unsigned int hashKey;
450 
451   hashKey = (int)(((POINTERINT)data1 + (POINTERINT)data2) % which_seq);
452   return hashKey;
453 }
454 
455 /* ��ǽ������������Ф� */
456 unsigned char *
actFromHash(tbl_ptr,key)457 actFromHash(tbl_ptr, key)
458 unsigned char *tbl_ptr;
459 unsigned char key;
460 {
461   unsigned int hashKey;
462   struct seq_struct *p;
463 
464   hashKey = createHashKey(tbl_ptr, key, ACTHASHTABLESIZE);
465   for (p = seq_hash[hashKey] ; p ; p = p->next) {
466     if (p->to_tbl == tbl_ptr && p->as_key == key) {
467       return p->kinou_seq;
468     }
469   }
470 #ifndef CODED_MESSAGE
471   debug_message("actFromHash:������������ߤĤ����ޤ���Ǥ�����\n",0,0,0);
472 #else
473   debug_message("actFromHash:\245\255\241\274\245\267\245\261\245\363\245\271"
474 	"\244\362\244\337\244\304\244\261\244\351\244\354\244\336\244\273"
475 	"\244\363\244\307\244\267\244\277\241\243\n",0,0,0);
476 #endif
477   return (unsigned char *)NULL; /* �������륭������������¸�ߤ��ʤ� */
478 }
479 
480 /* �ϥå���ơ��֥����Ͽ */
481 static void
regist_act_hash(tbl_ptr,key,buff)482 regist_act_hash(tbl_ptr, key, buff)
483 unsigned char *tbl_ptr;
484 unsigned char key;
485 unsigned char *buff;
486 {
487   unsigned int hashKey;
488   struct seq_struct *p, **pp;
489 
490   hashKey = createHashKey(tbl_ptr, key, ACTHASHTABLESIZE);
491   for (pp = &seq_hash[hashKey] ; (p = *pp) != (struct seq_struct *)0 ;
492        pp = &(p->next)) {
493     if (p->to_tbl == tbl_ptr && p->as_key == key) {
494       if (p->kinou_seq)
495 	free(p->kinou_seq);
496       p->kinou_seq = (unsigned char *)malloc(strlen((char *)buff)+1);
497       if (p->kinou_seq)
498 	strcpy((char *)p->kinou_seq,(char *)buff);
499       return;
500     }
501   }
502   p = *pp = (struct seq_struct *)malloc(sizeof(struct seq_struct));
503   if(p) {
504     p->to_tbl = tbl_ptr;
505     p->as_key = key;
506     p->kinou_seq = (unsigned char *)malloc(strlen((char *)buff)+1);
507     if(p->kinou_seq)
508       strcpy((char *)p->kinou_seq,(char *)buff);
509     p->next = (struct seq_struct *)NULL;
510   }
511 }
512 
513 /* �ϥå���ơ��֥뤫���� */
514 static void
remove_hash(tbl_ptr,key,which_seq)515 remove_hash(tbl_ptr, key, which_seq)
516 unsigned char *tbl_ptr;
517 unsigned char key;
518 int which_seq;
519 {
520   unsigned int hashKey;
521   struct seq_struct *p, **pp;
522 
523   hashKey = createHashKey(tbl_ptr, key, which_seq);
524   for (pp = &seq_hash[hashKey] ; (p = *pp) != (struct seq_struct *)0 ;
525        pp = &(p->next)) {
526     if (p->to_tbl == tbl_ptr && p->as_key == key) {
527       *pp = p->next;
528       free(p);
529     }
530   }
531 }
532 
533 static void
freeChain(p)534 freeChain(p)
535 struct seq_struct *p;
536 {
537   struct seq_struct *nextp;
538 
539   while (p) {
540     free(p->kinou_seq);
541     nextp = p->next;
542     free(p);
543     p = nextp;
544   }
545 }
546 
547 static void
clearAllFuncSequence()548 clearAllFuncSequence()
549 {
550   int i;
551 
552   for (i = 0 ; i < ACTHASHTABLESIZE ; i++) {
553     freeChain(seq_hash[i]);
554     seq_hash[i] = 0;
555   }
556 }
557 
558 static void
freeKeySeqMode(m)559 freeKeySeqMode(m)
560 KanjiMode m;
561 {
562   if (m) {
563     if (m->keytbl) {
564       free(m->keytbl);
565     }
566     free(m);
567   }
568 }
569 
570 static void
freeMap(m)571 freeMap(m)
572 struct map *m;
573 {
574   struct map *n;
575 
576   while (m) {
577     freeKeySeqMode(m->mode);
578     n = m->next;
579     free(m);
580     m = n;
581   }
582 }
583 
584 static void
clearAllKeySequence()585 clearAllKeySequence()
586 {
587   int i;
588 
589   for (i = 0 ; i < KEYHASHTABLESIZE ; i++) {
590     freeMap(otherMap[i]);
591     otherMap[i] = 0;
592   }
593 }
594 
595 static
specialen(block)596 specialen(block)
597 unsigned char *block;
598 {
599   int i;
600   for (i = 0 ; block[i] != 255 ;) {
601     i++;
602   }
603   debug_message("specialen:\304\271\244\265\244\317%d\244\311\244\271\241\243\n",i,0,0);
604                 /* specialen:Ĺ����%d�ɤ��� */
605   return i;
606 }
607 
608 static
to_write_act(depth,keysize,actsize,singleAct)609 to_write_act(depth,keysize,actsize,singleAct)
610 int depth;
611 int keysize;
612 int actsize;
613 unsigned singleAct;
614 {
615   if (depth == (keysize -2)) {
616     if (actsize > 1){
617       debug_message("to_write_act:CANNA_FN_FuncSequence\244\307\244\271\241\243\n",0,0,0);
618                                                      /* �Ǥ��� */
619       return CANNA_FN_FuncSequence;
620     }
621     if (actsize == 1) {
622       debug_message("to_write_act:singleAct%d\244\307\244\271\241\243\n",singleAct,0,0);
623                                               /* �Ǥ��� */
624       return (int)singleAct;
625     }
626     else { /* ͭ�����ʤ��� */
627       return 0;
628     }
629   } else if (depth < (keysize -2)){
630     debug_message("to_write_act:CANNA_FN_UseOtherKeymap\244\307\244\271\241\243\n",0,0,0);
631                                               /* �Ǥ��� */
632     return CANNA_FN_UseOtherKeymap;
633   }
634   else { /* ͭ�����ʤ��� */
635     return 0;
636   }
637 }
638 
639 static struct map *
regist_map(tbl,keybuff,actbuff,depth)640 regist_map(tbl, keybuff, actbuff, depth)
641 KanjiMode tbl;
642 unsigned char *keybuff;
643 unsigned char *actbuff;
644 int      depth;
645 {
646   unsigned int hashKey;
647   int sequencelen, keybuffsize, actbuffsize, offs;
648   struct map *p,**pp;
649   unsigned char *q, prevfunc;
650 
651   actbuffsize = strlen((char *)actbuff);
652   keybuffsize = specialen(keybuff);
653   hashKey =
654     createHashKey((unsigned char *)tbl, keybuff[depth], KEYHASHTABLESIZE);
655   debug_message("regist_map:hashKey = %d \244\307\244\271\241\243\n",hashKey,0,0);
656                                          /* �Ǥ��� */
657   for (pp = &otherMap[hashKey]; (p = *pp) != (struct map *)0 ;
658        pp = &(p->next)) {
659     if (p->key == keybuff[depth] && p->tbl == tbl) {
660       for (q = p->mode->keytbl; *q != 255; q += 2) {
661 	if (*q == keybuff[depth+1]) {  /* ����Ʊ��������¸�ߤ����� */
662 	  ++q;
663 	  prevfunc = *q; /* ���Υ����κ��ޤǤε�ǽ���äƤ��� */
664 	  *q = to_write_act(depth,keybuffsize,actbuffsize,actbuff[0]);
665 	  if(prevfunc == CANNA_FN_UseOtherKeymap &&
666 	     *q != CANNA_FN_UseOtherKeymap) {
667             freeMultiSequence(keybuff[depth + 1], p->mode);
668           }
669 	  if (*q == CANNA_FN_FuncSequence) {
670 	    regist_act_hash((unsigned char *)p->mode, keybuff[depth+1],
671 			    actbuff);
672 	  }
673 	  debug_message("regist_map:\264\373\244\313\306\261\244\270\245\255\241\274\244\254\302\270\272\337:q=%d\n",*q,0,0);
674                         /* ����Ʊ��������¸�� */
675 	  return p;
676 	}
677       }
678       /* �����ޤǤΡ�����������Ϥ��ä������Υ���:keybuff[depth +1]�Ͻ��� */
679       sequencelen = specialen(p->mode->keytbl);
680       offs = q - p->mode->keytbl;
681       if (p->mode->keytbl) {
682 	p->mode->keytbl =
683 	  (unsigned char *)realloc(p->mode->keytbl,sequencelen +3);
684         if (!p->mode->keytbl) {
685           return (struct map *)0;
686         }
687         p->mode->keytbl[sequencelen] = keybuff[depth +1];
688         p->mode->keytbl[++sequencelen] =
689         to_write_act(depth,keybuffsize,actbuffsize,actbuff[0]);
690         p->mode->keytbl[++sequencelen] = (BYTE)-1;
691       }
692       if (p->mode->keytbl[offs] == CANNA_FN_FuncSequence) {
693 	regist_act_hash((unsigned char *)p->mode, keybuff[depth+1], actbuff);
694       }
695       debug_message("regist_map:\244\275\244\263\244\336\244\307\244\316"
696 	"\241\242\245\255\241\274\244\316\315\372\316\362\244\317\244\242"
697 	"\244\303\244\277\244\254\244\263\244\316\245\255\241\274%u\244\317"
698 	"\275\351\244\341\244\306\n",
699 		    p->mode->keytbl[sequencelen-3],0,0);
700                 /* �����ޤǤΡ�����������Ϥ��ä������Υ���%u�Ͻ��� */
701       debug_message("regist_map:sequencelen��%d�Ǥ���\n",sequencelen,0,0);
702       return p;
703     }
704   }
705   /* ������������Ƥʤ��ΤϤ��������˺��� */
706   p = *pp = (struct map *)malloc(sizeof(struct map));
707   if (p) {
708     p->tbl = tbl;
709     p->key = keybuff[depth];
710     p->mode = (KanjiMode)malloc(sizeof(KanjiModeRec));
711     if (p->mode) {
712       p->mode->func = multiSequenceFunc;
713       p->mode->flags = 0;
714       p->mode->keytbl = (unsigned char *)malloc(3);
715       if (p->mode->keytbl) {
716 	p->mode->keytbl[0] = keybuff[depth +1];
717 	p->mode->keytbl[1] = to_write_act(depth,keybuffsize,actbuffsize,actbuff[0]);
718 	debug_message("regist_map:p->mode->keytbl[1]\244\317%d\244\307\244\271\241\243\n",p->mode->keytbl[1],0,0);
719                                                   /* ��%d�Ǥ��� */
720 	p->mode->keytbl[2] = (BYTE)-1;
721 
722         p->next = (struct map *)NULL;
723         if (p->mode->keytbl[1] == CANNA_FN_FuncSequence) {
724           regist_act_hash((unsigned char *)p->mode, keybuff[depth+1], actbuff);
725         }
726         return p;
727       }
728       free((char *)p->mode);
729     }
730     free((char *)p);
731   }
732   return (struct map *)0;
733 }
734 
735 struct map *
mapFromHash(tbl,key,ppp)736 mapFromHash(tbl, key, ppp)
737 KanjiMode tbl;
738 unsigned char key;
739 struct map ***ppp;
740 {
741   unsigned int hashKey;
742   struct map *p, **pp;
743 
744   hashKey = createHashKey((unsigned char *)tbl, key, KEYHASHTABLESIZE);
745   debug_message("mapFromHash:hashKey��%d\n",hashKey,0,0);
746   for(pp = otherMap + hashKey ; (p = *pp) != (struct map *)0 ;
747       pp = &(p->next)) {
748     if (p->tbl == tbl && p->key == key) {
749       debug_message("mapFromHash:map\244\254\244\337\244\304\244\253\244\352"
750 	"\244\336\244\267\244\277\241\243\n",0,0,0);
751                             /* ���ߤĤ���ޤ����� */
752       if (ppp) {
753 	*ppp = pp;
754       }
755       return p;
756     }
757   }
758 #ifndef CODED_MESSAGE
759   debug_message("mapFromHash:map���ߤĤ���ޤ���\n",0,0,0);
760 #else
761   debug_message("mapFromHash:map\244\254\244\337\244\304\244\253\244\352"
762 	"\244\336\244\273\244\363\241\243\n",0,0,0);
763 #endif
764   return (struct map *)NULL;
765 }
766 
767 static int
regist_key_hash(tbl_ptr,keybuff,actbuff)768 regist_key_hash(tbl_ptr,keybuff, actbuff)
769 unsigned char *tbl_ptr;
770 unsigned char *keybuff;
771 unsigned char *actbuff;
772 {
773   struct map *map_ptr;
774   int keybuffsize, i;
775 
776   keybuffsize = specialen(keybuff);
777   map_ptr = regist_map((KanjiMode)tbl_ptr, keybuff, actbuff, 0);
778   if (!map_ptr) {
779     return NG;
780   }
781   for (i = 1; i <= (keybuffsize -2); i++) {
782     map_ptr = regist_map(map_ptr->mode, keybuff, actbuff, i);
783     if (!map_ptr) {
784       return NG;
785     }
786   }
787   debug_message("regist_key_hash:keybuffsize\244\317%d��actbuffsize"
788 	"\244\317��%d��i\244\317%d\244\307\244\271\241\243\n",
789 		keybuffsize,strlen(actbuff),i);
790                                      /* �� */ /* �� */ /* �� */ /* �Ǥ��� */
791   return 0;
792 }
793 
794 static
795 int
copyMultiSequence(key,old_tbl,new_tbl)796 copyMultiSequence(key, old_tbl, new_tbl)
797      unsigned char	key;
798      KanjiMode		old_tbl, new_tbl;
799 {
800   unsigned char hashKey;
801   unsigned char *old_sequence, *new_sequence;
802   int i, sequencelen;
803   struct map *p, **pp;
804   struct map *old_map;
805 
806   old_map = mapFromHash(old_tbl, key, (struct map ***)0);
807   old_sequence = old_map->mode->keytbl;
808   sequencelen = specialen(old_sequence);
809   hashKey = createHashKey((unsigned char *)new_tbl, key, KEYHASHTABLESIZE);
810   for (pp = &otherMap[hashKey]; (p = *pp) != (struct map *)0 ;
811        pp = &(p->next)) {
812     if (p->key == key && p->tbl == new_tbl) {
813       return 0;
814     }
815   }
816   p = *pp = (struct map *)malloc(sizeof(struct map));
817   if (p) {
818     p->tbl = new_tbl;
819     p->key = key;
820     p->mode = (KanjiMode)malloc(sizeof(KanjiModeRec));
821     if (p->mode) {
822       p->mode->func = multiSequenceFunc;
823       p->mode->flags = 0;
824       p->next = (struct map *)NULL;
825       p->mode->keytbl = (unsigned char *)malloc(sequencelen+1);
826       if (p->mode->keytbl) {
827 	for (i = 0, new_sequence = p->mode->keytbl; i <= sequencelen; i++) {
828 	  new_sequence[i] = old_sequence[i];
829 	  if (i%2 == 1) {
830 	    if (old_sequence[i] == CANNA_FN_UseOtherKeymap) {
831 	      if (copyMultiSequence(old_sequence[i-1],
832 				    old_map->mode, p->mode) < 0) {
833 		free((char *)p->mode->keytbl);
834 		free((char *)p->mode);
835 		free((char *)p);
836 		*pp = (struct map *)0;
837 		return(-1);
838 	      }
839 	    } else if (old_sequence[i] == CANNA_FN_FuncSequence)
840 	      regist_act_hash((unsigned char *)p->mode, old_sequence[i-1],
841 			      actFromHash((unsigned char *)old_map->mode,
842 					  old_sequence[i-1]));
843 	  }
844 	}
845 	return 0;
846       } else {
847 	free((char *)p->mode);
848 	free((char *)p);
849 	*pp = (struct map *)0;
850 	return(-1);
851       }
852     } else {
853       free((char *)p);
854       *pp = (struct map *)0;
855       return(-1);
856     }
857   } else
858     return(-1);
859 }
860 
861 static void
freeMultiSequence(key,tbl)862 freeMultiSequence(key, tbl)
863 unsigned char key;
864 KanjiMode tbl;
865 {
866   unsigned char *sequence;
867   int i, sequencelen;
868   struct map *map, **ptr;
869 
870   map = mapFromHash(tbl, key, &ptr);
871   if (!map)
872     return;
873   *ptr = map->next;
874   sequence = map->mode->keytbl;
875   sequencelen = specialen(sequence);
876 
877   for (i = 0; i <= sequencelen; i++) {
878     if (i%2 == 1) {
879       if (sequence[i] == CANNA_FN_UseOtherKeymap)
880 	freeMultiSequence(sequence[i-1], map->mode);
881       if (sequence[i] == CANNA_FN_FuncSequence)
882 	remove_hash((unsigned char *)map->mode, sequence[i-1],
883 		    ACTHASHTABLESIZE);
884     }
885   }
886   debug_message("\241\374\153\145\171\133\45\144\135\244\316\155\141\160\260"
887 	"\312\262\274\244\362\245\325\245\352\241\274\244\267\244\306\244\244"
888 	"\244\353\244\276\n",key,0,0);
889     /* ��key[%d]��map�ʲ���ե꡼���Ƥ��뤾 */
890   if (map->mode && sequence)
891     free(sequence);
892   if (map->mode)
893     free(map->mode);
894   free(map);
895 }
896 
askQuitKey(key)897 askQuitKey(key)
898 unsigned key;
899 {
900   if (defaultmap[key] == CANNA_FN_Quit) {
901     return 1; /* ������ä�key��quit���ä��� */
902   }
903   return 0; /* ������ä�key��quit�Ǥʤ��ä��� */
904 }
905