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/************************************************************************/ 24/* THIS SOURCE CODE IS MODIFIED FOR TKO BY T.MURAI 1997 25/************************************************************************/ 26 27#if !defined(lint) && !defined(__CODECENTER__) 28static char rcs_id[] = "@(#) 102.1 $Id: keydef.c 14875 2005-11-12 21:25:31Z bonefish $"; 29#endif /* lint */ 30 31#include "canna.h" 32#include <canna/mfdef.h> 33#include <canna/keydef.h> 34 35extern KanjiModeRec alpha_mode, empty_mode, yomi_mode; 36extern KanjiModeRec jishu_mode, ce_mode, cy_mode, cb_mode; 37extern KanjiModeRec tankouho_mode, ichiran_mode, onoff_mode; 38extern KanjiModeRec khal_mode, khkt_mode, kzal_mode, kzhr_mode, kzkt_mode; 39extern KanjiModeRec kigo_mode; 40extern KanjiModeRec tourokureibun_mode; 41extern KanjiModeRec bunsetsu_mode; 42extern KanjiModeRec cy_mode, cb_mode; 43 44//extern multiSequenceFunc 45// (struct _uiContext *, struct _kanjiMode *, int, int, int); 46 47#define NONE 0 48#define ACTHASHTABLESIZE 64 49#define KEYHASHTABLESIZE 16 50 51#define SINGLE 0 52#define MULTI 1 53#define OTHER 2 54 55static unsigned char *duplicatekmap(unsigned char *kmap); 56static int changeKeyOnSomeCondition(KanjiMode mode, int key, int fnum, unsigned char *actbuff, unsigned char *keybuff); 57static void undefineKeyfunc(unsigned char *keytbl, unsigned fnum); 58//static unsigned int createHashKey(unsigned char *data1, unsigned char data2, int which_seq); 59static void regist_act_hash(unsigned char *tbl_ptr, unsigned char key, unsigned char *buff); 60static void remove_hash(unsigned char *tbl_ptr, unsigned char key, int which_seq); 61static void freeChain(struct seq_struct *p); 62static void clearAllFuncSequence(void); 63static void freeKeySeqMode(KanjiMode m); 64static void freeMap(struct map *m); 65static void clearAllKeySequence(void); 66static int specialen(unsigned char *block); 67static int to_write_act(int depth, int keysize, int actsize, unsigned singleAct); 68static struct map *regist_map(KanjiMode tbl, unsigned char *keybuff, unsigned char *actbuff, int depth); 69static int regist_key_hash(unsigned char *tbl_ptr, unsigned char *keybuff, unsigned char *actbuff); 70static int copyMultiSequence(unsigned char key, KanjiMode old_tbl, KanjiMode new_tbl); 71static void freeMultiSequence(unsigned char key, KanjiMode tbl); 72 73struct seq_struct{ 74 unsigned char *to_tbl; 75 unsigned char as_key; 76 unsigned char *kinou_seq; 77 struct seq_struct *next; 78}; 79 80static struct seq_struct *seq_hash[ACTHASHTABLESIZE]; 81 82struct map{ 83 KanjiMode tbl; 84 unsigned char key; 85 KanjiMode mode; 86 struct map *next; 87}; 88 89static struct map *otherMap[KEYHASHTABLESIZE]; 90 91static KanjiMode ModeTbl[CANNA_MODE_MAX_REAL_MODE] = { 92 &alpha_mode, /* AlphaMode ¥¢¥ë¥Õ¥¡¥Ù¥Ã¥È¥â¡¼¥É */ 93 &empty_mode, /* EmptyMode ÆɤßÆþÎϤ¬¤Ê¤¤¾õÂÖ */ 94 &kigo_mode, /* KigoMode ¸õÊä°ìÍ÷¤òɽ¼¨¤·¤Æ¤¤¤ë¾õÂÖ */ 95 &yomi_mode, /* YomiMode ÆɤßÆþÎϤ·¤Æ¤¤¤ë¾õÂÖ */ 96 &jishu_mode, /* JishuMode ʸ»ú¼ïÊÑ´¹¤·¤Æ¤¤¤ë¾õÂÖ */ 97 &tankouho_mode, /* TankouhoMode ñ°ì¤Î¸õÊä¤òɽ¼¨¤·¤Æ¤¤¤ë¾õÂÖ */ 98 &ichiran_mode, /* IchiranMode ¸õÊä°ìÍ÷¤òɽ¼¨¤·¤Æ¤¤¤ë¾õÂÖ */ 99 &tourokureibun_mode, /* TourokuReibunMode ñ¸ìÅÐÏ¿¤ÎÎãʸɽ¼¨¾õÂÖ */ 100 &onoff_mode, /* OnOffMode On/Off¤Î°ìÍ÷¤Îɽ¼¨¾õÂÖ */ 101 &bunsetsu_mode, /* AdjustBunsetsuMode ʸÀ´̥⡼¥É */ 102 &cy_mode, /* ChikujiYomiMode Ã༡¤Î»þ¤ÎÆɤßÉôʬ */ 103 &cb_mode, /* ChikujiHenkanMode Ã༡¤Î»þ¤ÎÊÑ´¹¤ÎÉôʬ */ 104}; 105 106 107static unsigned char * 108duplicatekmap(unsigned char *kmap) 109{ 110 unsigned char *res; 111 int i; 112 113 res = (unsigned char *)calloc(256, sizeof(unsigned char)); 114 if (res) { 115 for (i = 0 ; i < 256 ; i++) { 116 res[i] = kmap[i]; 117 } 118 } 119 return res; 120} 121 122static unsigned char *defaultkeytables[CANNA_MODE_MAX_REAL_MODE]; 123static unsigned char defaultsharing[CANNA_MODE_MAX_REAL_MODE]; 124static unsigned char *defaultmap; 125unsigned char *alphamap, *emptymap; 126 127/* cfuncdef 128 129 initKeyTables() -- ¥¡¼¥Æ¡¼¥Ö¥ë¤ò½é´ü²½¤¹¤ë´Ø¿ô¡£ 130 131 ¥Ç¥Õ¥©¥ë¥È¤Î¥¡¼¥Æ¡¼¥Ö¥ë¤òµÏ¿¤·¤Æ¤ª¤¡¢¼Â»ÈÍѤΥơ¼¥Ö¥ë¤ò ¥Ç¥Õ¥©¥ë 132 ¥È¥Æ¡¼¥Ö¥ë¤«¤é¥³¥Ô¡¼¤¹¤ë½èÍý¤ò¹Ô¤¦¡£ 133 134*/ 135 136int initKeyTables(void) 137{ 138 int i; 139 unsigned char *tbl; 140 extern unsigned char default_kmap[], alpha_kmap[], empty_kmap[]; 141 142 defaultmap = duplicatekmap(default_kmap); 143 if (defaultmap) { 144 alphamap = duplicatekmap(alpha_kmap); 145 if (alphamap) { 146 emptymap = duplicatekmap(empty_kmap); 147 if (emptymap) { 148 for (i = 0 ; i < CANNA_MODE_MAX_REAL_MODE ; i++) { 149 if (ModeTbl[i]) { 150 defaultsharing[i] = ModeTbl[i]->flags; 151 tbl = defaultkeytables[i] = ModeTbl[i]->keytbl; 152 if (tbl == default_kmap) { 153 ModeTbl[i]->keytbl = defaultmap; 154 } 155 else if (tbl == alpha_kmap) { 156 ModeTbl[i]->keytbl = alphamap; 157 } 158 else if (tbl == empty_kmap) { 159 ModeTbl[i]->keytbl = emptymap; 160 } 161 } 162 } 163 return 0; 164 } 165 free(alphamap); 166 } 167 free(defaultmap); 168 } 169 return NG; 170} 171 172void 173restoreDefaultKeymaps(void) 174{ 175 int i; 176 177 for (i = 0 ; i < CANNA_MODE_MAX_REAL_MODE ; i++) { 178 if (ModeTbl[i]) { 179 if ( !(ModeTbl[i]->flags & CANNA_KANJIMODE_TABLE_SHARED) ) { 180 free(ModeTbl[i]->keytbl); 181 } 182 ModeTbl[i]->keytbl = defaultkeytables[i]; 183 ModeTbl[i]->flags = defaultsharing[i]; 184 } 185 } 186 free(defaultmap); 187 free(alphamap); 188 free(emptymap); 189 clearAllFuncSequence(); 190 clearAllKeySequence(); 191} 192 193 194/* 195 * ¤¢¤ë¥â¡¼¥É¤Î¥¡¼¤ËÂФ·¤Æ´Ø¿ô¤ò³ä¤êÅö¤Æ¤ë½èÍý 196 * 197 */ 198 199/* 200 201 £±£¶¿Ê¤Î»þ¤Ï£´Ê¸»úÌܤòÆþ¤ì¤¿»þ¤Î¥â¡¼¥É¤Ë¤âÀßÄꤹ¤ë¡£ 202 203 */ 204 205extern int nothermodes; 206 207int changeKeyfunc(int modenum, int key, int fnum, unsigned char *actbuff, unsigned char *keybuff) 208{ 209 int i, retval = 0; 210 unsigned char *p, *q; 211 KanjiMode mode; 212 newmode *nmode; 213 214 /* ¤Á¤ç¤Ã¤È¾®ºÙ¹© */ 215 if (modenum == CANNA_MODE_HenkanNyuryokuMode) { 216 retval = changeKeyfunc(CANNA_MODE_EmptyMode, key, fnum, actbuff, keybuff); 217 if (retval < 0) { 218 return retval; 219 } 220 modenum = CANNA_MODE_YomiMode; 221 } 222 223 if (modenum < 0) { 224 return 0; 225 } 226 else if (modenum < CANNA_MODE_MAX_REAL_MODE) { 227 mode = ModeTbl[modenum]; 228 } 229 else if (modenum < CANNA_MODE_MAX_IMAGINARY_MODE) { 230 return 0; 231 } 232 else if (modenum < CANNA_MODE_MAX_IMAGINARY_MODE + nothermodes) { 233 nmode = findExtraKanjiMode(modenum); 234 if (!nmode) { 235 return 0; 236 } 237 else { 238 mode = nmode->emode; 239 } 240 } 241 else { 242 return 0; 243 } 244 245 if (mode && mode->func((uiContext)0/*dummy*/, mode, 246 KEY_CHECK, 0/*dummy*/, fnum)) { 247 /* ¤½¤Îµ¡Ç½¤¬¤½¤Î¥â¡¼¥É¤Ë¤ª¤¤¤Æ͸ú¤Êµ¡Ç½¤Ç¤¢¤ì¤Ð */ 248 if (mode->keytbl) { /* ¥¡¼¥Æ¡¼¥Ö¥ë¤¬Â¸ºß¤¹¤ì¤Ð */ 249 /* ¤³¤ì¤ÏÀäÂФ˸ºß¤¹¤ë¤Î¤Ç¤Ï¡© */ 250 if (mode->flags & CANNA_KANJIMODE_TABLE_SHARED) { 251 /* ¥¡¼¥Þ¥Ã¥×¤¬Â¾¤Î¥â¡¼¥É¤È¶¦Í¤µ¤ì¤Æ¤¤¤ë¤Ê¤é */ 252 p = (unsigned char *)calloc(256, sizeof(unsigned char)); 253 if (!p) { 254 return -1; 255 } 256 bcopy(mode->keytbl, p, 256 * sizeof(unsigned char)); 257 for (i = 0; i < 256; i++) { 258 if (mode->keytbl[i] == CANNA_FN_FuncSequence) { 259 q = actFromHash(mode->keytbl,i); 260 if (q) { /* ³ºÅö¤¹¤ë¥¡¼¥·¡¼¥±¥ó¥¹¤¬¤¢¤Ã¤¿¤é */ 261 regist_act_hash(p, i, q); 262 } 263 } 264 if (mode->keytbl[i] == CANNA_FN_UseOtherKeymap) { 265 debug_message("changeKeyfunc:\245\306\241\274\245\326\245\353" 266 "\260\334\306\260\72\244\263\244\316\244\310\244\255\244\316" 267 "\245\255\241\274\244\317%d\n",i,0,0); 268 /* ¥Æ¡¼¥Ö¥ë°ÜÆ°:¤³¤Î¤È¤¤Î¥¡¼¤Ï */ 269 (void)copyMultiSequence(i, (KanjiMode)mode->keytbl, 270 (KanjiMode)p); 271 } 272 } 273 mode->keytbl = p; 274 mode->flags &= ~CANNA_KANJIMODE_TABLE_SHARED; 275 if (modenum == CANNA_MODE_YomiMode && 276 (ModeTbl[CANNA_MODE_ChikujiYomiMode]->flags 277 & CANNA_KANJIMODE_TABLE_SHARED)) { 278 ModeTbl[CANNA_MODE_ChikujiYomiMode]->keytbl = p; 279 } 280 else if (modenum == CANNA_MODE_TankouhoMode && 281 (ModeTbl[CANNA_MODE_ChikujiTanMode]->flags 282 & CANNA_KANJIMODE_TABLE_SHARED)) { 283 ModeTbl[CANNA_MODE_ChikujiTanMode]->keytbl = p; 284 } 285 } 286 if (key >= 0 && key < 255) { 287 if (mode->keytbl[key] == CANNA_FN_UseOtherKeymap && 288 fnum != CANNA_FN_UseOtherKeymap) 289 freeMultiSequence(key,(KanjiMode)mode->keytbl); 290 mode->keytbl[key] = fnum; 291 if (fnum == CANNA_FN_FuncSequence) { 292 regist_act_hash(mode->keytbl,key,actbuff); 293 } 294 if (fnum == CANNA_FN_UseOtherKeymap) { 295 retval = regist_key_hash(mode->keytbl,keybuff,actbuff); 296 if (retval) { 297 return retval; 298 } 299 } 300 } 301 else if (key == CANNA_KEY_Undefine) { 302 undefineKeyfunc(mode->keytbl, fnum); 303 } 304 } 305 } 306 return 0; 307} 308 309static int 310changeKeyOnSomeCondition(KanjiMode mode, int key, int fnum, unsigned char *actbuff, unsigned char *keybuff) 311{ 312 int retval = 0; 313 314 if (mode && /* ¤½¤Î¥â¡¼¥É¤¬Â¸ºß¤¹¤ë¤Ê¤é */ 315 mode->func((uiContext)0/*dummy*/, mode, 316 KEY_CHECK, 0/*dummy*/, fnum)) { 317 /* ´Ø¿ô¤¬¤½¤Î¥â¡¼¥É¤Ç͸ú¤Ê¤é */ 318 if ( !(mode->flags & CANNA_KANJIMODE_TABLE_SHARED) ) { 319 /* ¥Æ¡¼¥Ö¥ë¤¬¶¦Í¤µ¤ì¤Æ¤¤¤Ê¤¤¤Ê¤é */ 320 if (mode->keytbl) { /* ¥¡¼¥Æ¡¼¥Ö¥ë¤¬Â¸ºß¤¹¤ì¤Ð */ 321 if (mode->keytbl[key] == CANNA_FN_UseOtherKeymap && 322 fnum != CANNA_FN_UseOtherKeymap) 323 freeMultiSequence(key,(KanjiMode)mode->keytbl); 324 mode->keytbl[key] = fnum; 325 if (fnum == CANNA_FN_FuncSequence) { 326 regist_act_hash(mode->keytbl,key,actbuff); 327 } 328 if (fnum == CANNA_FN_UseOtherKeymap) { 329 retval = regist_key_hash(mode->keytbl,keybuff,actbuff); 330 } 331 } 332 } 333 } 334 return retval; 335} 336 337/* 338 * Á´¤Æ¤Î¥â¡¼¥É¤Î¡¢¤¢¤ë¥¡¼¤ËÂФ·¤Æ´Ø¿ô¤ò³ä¤êÅö¤Æ¤ë½èÍý 339 * 340 */ 341 342int changeKeyfuncOfAll(int key, int fnum, unsigned char *actbuff, unsigned char *keybuff) 343{ 344 extern extraFunc *extrafuncp; 345 extraFunc *ep; 346 KanjiMode mode; 347 int i, retval = 0; 348 349 if (key >= 0 && key < 255) { 350 if (defaultmap[key] == CANNA_FN_UseOtherKeymap && 351 fnum != CANNA_FN_UseOtherKeymap) 352 freeMultiSequence(key,(KanjiMode)defaultmap); 353 if (alphamap[key] == CANNA_FN_UseOtherKeymap && 354 fnum != CANNA_FN_UseOtherKeymap) 355 freeMultiSequence(key,(KanjiMode)alphamap); 356 if (emptymap[key] == CANNA_FN_UseOtherKeymap && 357 fnum != CANNA_FN_UseOtherKeymap) 358 freeMultiSequence(key,(KanjiMode)emptymap); 359 defaultmap[key] = fnum; 360 alphamap[key] = fnum; 361 emptymap[key] = fnum; 362 if (fnum == CANNA_FN_FuncSequence) { 363 regist_act_hash(defaultmap,key,actbuff); 364 regist_act_hash(alphamap,key,actbuff); 365 regist_act_hash(emptymap,key,actbuff); 366 } 367 if (fnum == CANNA_FN_UseOtherKeymap) { 368 if (regist_key_hash(defaultmap,keybuff,actbuff) == NG || 369 regist_key_hash(alphamap,keybuff,actbuff) == NG || 370 regist_key_hash(emptymap,keybuff,actbuff) == NG) { 371 return -1; 372 } 373 } 374 for (i = 0 ; i < CANNA_MODE_MAX_REAL_MODE ; i++) { 375 mode = ModeTbl[i]; 376 retval = changeKeyOnSomeCondition(mode, key, fnum, actbuff, keybuff); 377 if (retval < 0) { 378 return retval; 379 } 380 } 381 for (ep = extrafuncp ; ep ; ep = ep->next) { 382 /* defmode ¤Ç¤ÎÁ´¤Æ¤Î¥â¡¼¥É¤ËÂФ·¤Æ¤ä¤ë */ 383 if (ep->keyword == EXTRA_FUNC_DEFMODE) { 384 retval = changeKeyOnSomeCondition(ep->u.modeptr->emode, key, fnum, 385 actbuff, keybuff); 386 if (retval < 0) { 387 return retval; 388 } 389 } 390 } 391 } 392 else if (key == CANNA_KEY_Undefine) { 393 undefineKeyfunc(defaultmap, (unsigned)fnum); 394 undefineKeyfunc(alphamap, (unsigned)fnum); 395 undefineKeyfunc(emptymap, (unsigned)fnum); 396 for (i = 0 ; i < CANNA_MODE_MAX_REAL_MODE ; i++) { 397 mode = ModeTbl[i]; 398 if (mode && /* ¤½¤Î¥â¡¼¥É¤¬Â¸ºß¤¹¤ë¤Ê¤é */ 399 mode->func((uiContext)0/*dummy*/, mode, 400 KEY_CHECK, 0/*dummy*/, fnum)) { 401 /* ´Ø¿ô¤¬¤½¤Î¥â¡¼¥É¤Ç͸ú¤Ê¤é */ 402 if ( !(mode->flags & CANNA_KANJIMODE_TABLE_SHARED) ) { 403 /* ¥Æ¡¼¥Ö¥ë¤¬¶¦Í¤µ¤ì¤Æ¤¤¤Ê¤¤¤Ê¤é */ 404 if (mode->keytbl) { /* ¥¡¼¥Æ¡¼¥Ö¥ë¤¬Â¸ºß¤¹¤ì¤Ð */ 405 undefineKeyfunc(mode->keytbl, (unsigned)fnum); 406 } 407 } 408 } 409 } 410 } 411 return retval; 412} 413 414static void 415undefineKeyfunc(unsigned char *keytbl, unsigned fnum) 416{ 417 int i; 418 419 for (i = 0 ; i < ' ' ; i++) { 420 if (keytbl[i] == fnum) { 421 keytbl[i] = CANNA_FN_Undefined; 422 } 423 } 424 for (i = ' ' ; i < 0x7f ; i++) { 425 if (keytbl[i] == fnum) { 426 keytbl[i] = CANNA_FN_FunctionalInsert; 427 } 428 } 429 for (i = 0x7f ; i < 0xa0 ; i++) { 430 if (keytbl[i] == fnum) { 431 keytbl[i] = CANNA_FN_Undefined; 432 } 433 } 434 for (i = 0xa0 ; i < 0xe0 ; i++) { 435 if (keytbl[i] == fnum) { 436 keytbl[i] = CANNA_FN_FunctionalInsert; 437 } 438 } 439 for (i = 0xe0 ; i < 0x100 ; i++) { 440 if (keytbl[i] == fnum) { 441 keytbl[i] = CANNA_FN_Undefined; 442 } 443 } 444} 445 446inline 447unsigned int 448createHashKey(unsigned char *data1, unsigned char data2, unsigned long which_seq) 449{ 450 unsigned long hashKey; 451 452 hashKey = (*data1 + data2) % which_seq; 453 return hashKey; 454} 455 456/* µ¡Ç½¥·¡¼¥±¥ó¥¹¤ò³ä¤ê½Ð¤¹ */ 457unsigned char * 458actFromHash(unsigned char *tbl_ptr, unsigned char key) 459{ 460 unsigned int hashKey; 461 struct seq_struct *p; 462 463 hashKey = createHashKey(tbl_ptr, key, ACTHASHTABLESIZE); 464 for (p = seq_hash[hashKey] ; p ; p = p->next) { 465 if (p->to_tbl == tbl_ptr && p->as_key == key) { 466 return p->kinou_seq; 467 } 468 } 469#ifndef WIN 470 debug_message("actFromHash:¥¡¼¥·¥±¥ó¥¹¤ò¤ß¤Ä¤±¤é¤ì¤Þ¤»¤ó¤Ç¤·¤¿¡£\n",0,0,0); 471#else 472 debug_message("actFromHash:\245\255\241\274\245\267\245\261\245\363\245\271" 473 "\244\362\244\337\244\304\244\261\244\351\244\354\244\336\244\273" 474 "\244\363\244\307\244\267\244\277\241\243\n",0,0,0); 475#endif 476 return (unsigned char *)NULL; /* ³ºÅö¤¹¤ë¥¡¼¥·¡¼¥±¥ó¥¹¤Ï¸ºß¤·¤Ê¤¤ */ 477} 478 479/* ¥Ï¥Ã¥·¥å¥Æ¡¼¥Ö¥ë¤ËÅÐÏ¿ */ 480static void 481regist_act_hash(unsigned char *tbl_ptr, unsigned char key, unsigned char *buff) 482{ 483 unsigned int hashKey; 484 struct seq_struct *p, **pp; 485 486 hashKey = createHashKey(tbl_ptr, key, ACTHASHTABLESIZE); 487 for (pp = &seq_hash[hashKey] ; (p = *pp) != (struct seq_struct *)0 ; 488 pp = &(p->next)) { 489 if (p->to_tbl == tbl_ptr && p->as_key == key) { 490 if (p->kinou_seq) 491 free(p->kinou_seq); 492 p->kinou_seq = (unsigned char *)malloc(strlen((char *)buff)+1); 493 if (p->kinou_seq) 494 strcpy((char *)p->kinou_seq,(char *)buff); 495 return; 496 } 497 } 498 p = *pp = (struct seq_struct *)malloc(sizeof(struct seq_struct)); 499 if(p) { 500 p->to_tbl = tbl_ptr; 501 p->as_key = key; 502 p->kinou_seq = (unsigned char *)malloc(strlen((char *)buff)+1); 503 if(p->kinou_seq) 504 strcpy((char *)p->kinou_seq,(char *)buff); 505 p->next = (struct seq_struct *)NULL; 506 } 507} 508 509/* ¥Ï¥Ã¥·¥å¥Æ¡¼¥Ö¥ë¤«¤éºï½ü */ 510static void 511remove_hash(unsigned char *tbl_ptr, unsigned char key, int which_seq) 512{ 513 unsigned int hashKey; 514 struct seq_struct *p, **pp; 515 516 hashKey = createHashKey(tbl_ptr, key, which_seq); 517 for (pp = &seq_hash[hashKey] ; (p = *pp) != (struct seq_struct *)0 ; 518 pp = &(p->next)) { 519 if (p->to_tbl == tbl_ptr && p->as_key == key) { 520 *pp = p->next; 521 free(p); 522 } 523 } 524} 525 526static void 527freeChain(struct seq_struct *p) 528{ 529 struct seq_struct *nextp; 530 531 while (p) { 532 free(p->kinou_seq); 533 nextp = p->next; 534 free(p); 535 p = nextp; 536 } 537} 538 539static void 540clearAllFuncSequence(void) 541{ 542 int i; 543 544 for (i = 0 ; i < ACTHASHTABLESIZE ; i++) { 545 freeChain(seq_hash[i]); 546 seq_hash[i] = 0; 547 } 548} 549 550static void 551freeKeySeqMode(KanjiMode m) 552{ 553 if (m) { 554 if (m->keytbl) { 555 free(m->keytbl); 556 } 557 free(m); 558 } 559} 560 561static void 562freeMap(struct map *m) 563{ 564 struct map *n; 565 566 while (m) { 567 freeKeySeqMode(m->mode); 568 n = m->next; 569 free(m); 570 m = n; 571 } 572} 573 574static void 575clearAllKeySequence(void) 576{ 577 int i; 578 579 for (i = 0 ; i < KEYHASHTABLESIZE ; i++) { 580 freeMap(otherMap[i]); 581 otherMap[i] = 0; 582 } 583} 584 585static 586int specialen(unsigned char *block) 587{ 588 int i; 589 for (i = 0 ; block[i] != 255 ;) { 590 i++; 591 } 592 debug_message("specialen:\304\271\244\265\244\317%d\244\311\244\271\241\243\n",i,0,0); 593 /* specialen:Ťµ¤Ï%d¤É¤¹¡£ */ 594 return i; 595} 596 597static 598int to_write_act(int depth, int keysize, int actsize, unsigned singleAct) 599{ 600 if (depth == (keysize -2)) { 601 if (actsize > 1){ 602 debug_message("to_write_act:CANNA_FN_FuncSequence\244\307\244\271\241\243\n",0,0,0); 603 /* ¤Ç¤¹¡£ */ 604 return CANNA_FN_FuncSequence; 605 } 606 if (actsize == 1) { 607 debug_message("to_write_act:singleAct%d\244\307\244\271\241\243\n",singleAct,0,0); 608 /* ¤Ç¤¹¡£ */ 609 return (int)singleAct; 610 } 611 else { /* ͤêÆÀ¤Ê¤¤¡© */ 612 return 0; 613 } 614 } else if (depth < (keysize -2)){ 615 debug_message("to_write_act:CANNA_FN_UseOtherKeymap\244\307\244\271\241\243\n",0,0,0); 616 /* ¤Ç¤¹¡£ */ 617 return CANNA_FN_UseOtherKeymap; 618 } 619 else { /* ͤêÆÀ¤Ê¤¤¡© */ 620 return 0; 621 } 622} 623 624static struct map * 625regist_map(KanjiMode tbl, unsigned char *keybuff, unsigned char *actbuff, int depth) 626{ 627 unsigned int hashKey; 628 int sequencelen, keybuffsize, actbuffsize, offs; 629 struct map *p,**pp; 630 unsigned char *q, prevfunc; 631 632 actbuffsize = strlen((char *)actbuff); 633 keybuffsize = specialen(keybuff); 634 hashKey = 635 createHashKey((unsigned char *)tbl, keybuff[depth], KEYHASHTABLESIZE); 636 debug_message("regist_map:hashKey = %d \244\307\244\271\241\243\n",hashKey,0,0); 637 /* ¤Ç¤¹¡£ */ 638 for (pp = &otherMap[hashKey]; (p = *pp) != (struct map *)0 ; 639 pp = &(p->next)) { 640 if (p->key == keybuff[depth] && p->tbl == tbl) { 641 for (q = p->mode->keytbl; *q != 255; q += 2) { 642 if (*q == keybuff[depth+1]) { /* ´û¤ËƱ¤¸¥¡¼¤¬Â¸ºß¤·¤¿¡£ */ 643 ++q; 644 prevfunc = *q; /* ¤½¤Î¥¡¼¤Îº£¤Þ¤Ç¤Îµ¡Ç½¤ò¼è¤Ã¤Æ¤ª¤¯ */ 645 *q = to_write_act(depth,keybuffsize,actbuffsize,actbuff[0]); 646 if(prevfunc == CANNA_FN_UseOtherKeymap && 647 *q != CANNA_FN_UseOtherKeymap) { 648 freeMultiSequence(keybuff[depth + 1], p->mode); 649 } 650 if (*q == CANNA_FN_FuncSequence) { 651 regist_act_hash((unsigned char *)p->mode, keybuff[depth+1], 652 actbuff); 653 } 654 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); 655 /* ´û¤ËƱ¤¸¥¡¼¤¬Â¸ºß */ 656 return p; 657 } 658 } 659 /* ¤½¤³¤Þ¤Ç¤Î¡¢¥¡¼¤ÎÍúÎò¤Ï¤¢¤Ã¤¿¤¬¤³¤Î¥¡¼:keybuff[depth +1]¤Ï½é¤á¤Æ */ 660 sequencelen = specialen(p->mode->keytbl); 661 offs = q - p->mode->keytbl; 662 if (p->mode->keytbl) { 663 p->mode->keytbl = 664 (unsigned char *)realloc(p->mode->keytbl,sequencelen +3); 665 if (!p->mode->keytbl) { 666 return (struct map *)0; 667 } 668 p->mode->keytbl[sequencelen] = keybuff[depth +1]; 669 p->mode->keytbl[++sequencelen] = 670 to_write_act(depth,keybuffsize,actbuffsize,actbuff[0]); 671 p->mode->keytbl[++sequencelen] = (BYTE)-1; 672 } 673 if (p->mode->keytbl[offs] == CANNA_FN_FuncSequence) { 674 regist_act_hash((unsigned char *)p->mode, keybuff[depth+1], actbuff); 675 } 676 debug_message("regist_map:\244\275\244\263\244\336\244\307\244\316" 677 "\241\242\245\255\241\274\244\316\315\372\316\362\244\317\244\242" 678 "\244\303\244\277\244\254\244\263\244\316\245\255\241\274%u\244\317" 679 "\275\351\244\341\244\306\n", 680 p->mode->keytbl[sequencelen-3],0,0); 681 /* ¤½¤³¤Þ¤Ç¤Î¡¢¥¡¼¤ÎÍúÎò¤Ï¤¢¤Ã¤¿¤¬¤³¤Î¥¡¼%u¤Ï½é¤á¤Æ */ 682 debug_message("regist_map:sequencelen¤Ï%d¤Ç¤¹¡£\n",sequencelen,0,0); 683 return p; 684 } 685 } 686 /* ²áµî¤ÎÍúÎò¤ÏÁ´¤Æ¤Ê¤·¤Î¤Ï¤º¡¢¿·µ¬¤ËºîÀ® */ 687 p = *pp = (struct map *)malloc(sizeof(struct map)); 688 if (p) { 689 p->tbl = tbl; 690 p->key = keybuff[depth]; 691 p->mode = (KanjiMode)malloc(sizeof(KanjiModeRec)); 692 if (p->mode) { 693 p->mode->func = multiSequenceFunc; 694 p->mode->flags = 0; 695 p->mode->keytbl = (unsigned char *)malloc(3); 696 if (p->mode->keytbl) { 697 p->mode->keytbl[0] = keybuff[depth +1]; 698 p->mode->keytbl[1] = to_write_act(depth,keybuffsize,actbuffsize,actbuff[0]); 699 debug_message("regist_map:p->mode->keytbl[1]\244\317%d\244\307\244\271\241\243\n",p->mode->keytbl[1],0,0); 700 /* ¤Ï%d¤Ç¤¹¡£ */ 701 p->mode->keytbl[2] = (BYTE)-1; 702 703 p->next = (struct map *)NULL; 704 if (p->mode->keytbl[1] == CANNA_FN_FuncSequence) { 705 regist_act_hash((unsigned char *)p->mode, keybuff[depth+1], actbuff); 706 } 707 return p; 708 } 709 free(p->mode); 710 } 711 free(p); 712 } 713 return (struct map *)0; 714} 715 716struct map * 717mapFromHash(KanjiMode tbl, unsigned char key, struct map ***ppp) 718{ 719 unsigned int hashKey; 720 struct map *p, **pp; 721 722 hashKey = createHashKey((unsigned char *)tbl, key, KEYHASHTABLESIZE); 723 debug_message("mapFromHash:hashKey¤Ï%d\n",hashKey,0,0); 724 for(pp = otherMap + hashKey ; (p = *pp) != (struct map *)0 ; 725 pp = &(p->next)) { 726 if (p->tbl == tbl && p->key == key) { 727 debug_message("mapFromHash:map\244\254\244\337\244\304\244\253\244\352" 728 "\244\336\244\267\244\277\241\243\n",0,0,0); 729 /* ¤¬¤ß¤Ä¤«¤ê¤Þ¤·¤¿¡£ */ 730 if (ppp) { 731 *ppp = pp; 732 } 733 return p; 734 } 735 } 736#ifndef WIN 737 debug_message("mapFromHash:map¤¬¤ß¤Ä¤«¤ê¤Þ¤»¤ó¡£\n",0,0,0); 738#else 739 debug_message("mapFromHash:map\244\254\244\337\244\304\244\253\244\352" 740 "\244\336\244\273\244\363\241\243\n",0,0,0); 741#endif 742 return (struct map *)NULL; 743} 744 745static int 746regist_key_hash(unsigned char *tbl_ptr, unsigned char *keybuff, unsigned char *actbuff) 747{ 748 struct map *map_ptr; 749 int keybuffsize, i; 750 751 keybuffsize = specialen(keybuff); 752 map_ptr = regist_map((KanjiMode)tbl_ptr, keybuff, actbuff, 0); 753 if (!map_ptr) { 754 return NG; 755 } 756 for (i = 1; i <= (keybuffsize -2); i++) { 757 map_ptr = regist_map(map_ptr->mode, keybuff, actbuff, i); 758 if (!map_ptr) { 759 return NG; 760 } 761 } 762 debug_message("regist_key_hash:keybuffsize\244\317%d¡¡actbuffsize" 763 "\244\317¤Ï%d¡¡i\244\317%d\244\307\244\271\241\243\n", 764 keybuffsize,strlen(actbuff),i); 765 /* ¤Ï */ /* ¤Ï */ /* ¤Ï */ /* ¤Ç¤¹¡£ */ 766 return 0; 767} 768 769static 770int 771copyMultiSequence(unsigned char key, KanjiMode old_tbl, KanjiMode new_tbl) 772{ 773 unsigned char hashKey; 774 unsigned char *old_sequence, *new_sequence; 775 int i, sequencelen; 776 struct map *p, **pp; 777 struct map *old_map; 778 779 old_map = mapFromHash(old_tbl, key, (struct map ***)0); 780 old_sequence = old_map->mode->keytbl; 781 sequencelen = specialen(old_sequence); 782 hashKey = createHashKey((unsigned char *)new_tbl, key, KEYHASHTABLESIZE); 783 for (pp = &otherMap[hashKey]; (p = *pp) != (struct map *)0 ; 784 pp = &(p->next)) { 785 if (p->key == key && p->tbl == new_tbl) { 786 return 0; 787 } 788 } 789 p = *pp = (struct map *)malloc(sizeof(struct map)); 790 if (p) { 791 p->tbl = new_tbl; 792 p->key = key; 793 p->mode = (KanjiMode)malloc(sizeof(KanjiModeRec)); 794 if (p->mode) { 795 p->mode->func = multiSequenceFunc; 796 p->mode->flags = 0; 797 p->next = (struct map *)NULL; 798 p->mode->keytbl = (unsigned char *)malloc(sequencelen+1); 799 if (p->mode->keytbl) { 800 for (i = 0, new_sequence = p->mode->keytbl; i <= sequencelen; i++) { 801 new_sequence[i] = old_sequence[i]; 802 if (i%2 == 1) { 803 if (old_sequence[i] == CANNA_FN_UseOtherKeymap) { 804 if (copyMultiSequence(old_sequence[i-1], 805 old_map->mode, p->mode) < 0) { 806 free(p->mode->keytbl); 807 free(p->mode); 808 free(p); 809 *pp = (struct map *)0; 810 return(-1); 811 } 812 } else if (old_sequence[i] == CANNA_FN_FuncSequence) 813 regist_act_hash((unsigned char *)p->mode, old_sequence[i-1], 814 actFromHash((unsigned char *)old_map->mode, 815 old_sequence[i-1])); 816 } 817 } 818 return 0; 819 } else { 820 free(p->mode); 821 free(p); 822 *pp = (struct map *)0; 823 return(-1); 824 } 825 } else { 826 free(p); 827 *pp = (struct map *)0; 828 return(-1); 829 } 830 } else 831 return(-1); 832} 833 834static void 835freeMultiSequence(unsigned char key, KanjiMode tbl) 836{ 837 unsigned char *sequence; 838 int i, sequencelen; 839 struct map *map, **ptr; 840 841 map = mapFromHash(tbl, key, &ptr); 842 if (!map) 843 return; 844 *ptr = map->next; 845 sequence = map->mode->keytbl; 846 sequencelen = specialen(sequence); 847 848 for (i = 0; i <= sequencelen; i++) { 849 if (i%2 == 1) { 850 if (sequence[i] == CANNA_FN_UseOtherKeymap) 851 freeMultiSequence(sequence[i-1], map->mode); 852 if (sequence[i] == CANNA_FN_FuncSequence) 853 remove_hash((unsigned char *)map->mode, sequence[i-1], 854 ACTHASHTABLESIZE); 855 } 856 } 857 debug_message("\241\374\153\145\171\133\45\144\135\244\316\155\141\160\260" 858 "\312\262\274\244\362\245\325\245\352\241\274\244\267\244\306\244\244" 859 "\244\353\244\276\n",key,0,0); 860 /* ¡ükey[%d]¤Îmap°Ê²¼¤ò¥Õ¥ê¡¼¤·¤Æ¤¤¤ë¤¾ */ 861 if (map->mode && sequence) 862 free(sequence); 863 if (map->mode) 864 free(map->mode); 865 free(map); 866} 867 868int askQuitKey(unsigned key) 869{ 870 if (defaultmap[key] == CANNA_FN_Quit) { 871 return 1; /* ¼õ¤±¼è¤Ã¤¿key¤Ïquit¤À¤Ã¤¿¡£ */ 872 } 873 return 0; /* ¼õ¤±¼è¤Ã¤¿key¤Ïquit¤Ç¤Ê¤«¤Ã¤¿¡£ */ 874} 875