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 m_s_map_id[] = "@(#) 102.1 $Id: multi.c 14875 2005-11-12 21:25:31Z bonefish $"; 29#endif /* lint */ 30 31#include "canna.h" 32#include <canna/mfdef.h> 33 34#define NONE CANNA_FN_Undefined 35 36static unsigned char *showChar(int c); 37static int _DoFuncSequence(uiContext d, BYTE *keytbl, BYTE key); 38 39extern int askQuitKey(); 40extern int checkGLineLen(); 41extern int NothingChangedWithBeep(); 42 43static unsigned char *keyHistory; 44 45struct map { 46 KanjiMode tbl; 47 unsigned char key; 48 KanjiMode mode; 49 struct map *next; 50}; 51 52extern struct map *mapFromHash(); 53 54static unsigned char * 55showChar(int c) 56{ 57 static unsigned char Gkey[9]; 58 static char *keyCharMap[] = { 59 "space", "DEL", "Nfer", "Xfer", "Up", 60 "Left", "Right", "Down", "Insert", "Rollup", 61 "Rolldown", "Home", "HELP", "KeyPad", "S-nfer", 62 "S-xfer", "S-up", "S-left", "S-right", "S-down", 63 "C-nfer", "C-xfer", "C-up", "C-left", "C-right", 64 "C-down", "F1", "F2", "F3", "F4", 65 "F5", "F6", "F7", "F8", "F9", 66 "F10", "PF1", "PF2", "PF3", "PF4", 67 "PF5", "PF6", "PF7", "PF8", "PF9", 68 "PF10", 69 }; 70 71 if (c < 0x20) { 72 strcpy((char *)Gkey, "C-"); 73 if (c == 0x00 || (c > 0x1a && c < 0x20 )) 74 Gkey[2] = c + 0x40; 75 else 76 Gkey[2] = c + 0x60; 77 Gkey[3] = '\0'; 78 } 79 else if (c > ' ' && c <= '~' ) { 80 Gkey[0] = c; 81 Gkey[1] = '\0'; 82 } 83 else if (c > 0xa0 && c < 0xdf) { 84 Gkey[0] = 0x8e; 85 Gkey[1] = c; 86 Gkey[2] = '\0'; 87 } 88 else if (c == 0x20) 89 strcpy((char *)Gkey, keyCharMap[0]); 90 else if (c > 0x7e && c < 0x8c) 91 strcpy((char *)Gkey, keyCharMap[c -0x7f +1]); 92 else if (c > 0x8f && c < 0x9c) 93 strcpy((char *)Gkey, keyCharMap[c -0x90 +14]); 94 else if (c > 0xdf && c < 0xea) 95 strcpy((char *)Gkey, keyCharMap[c -0xe0 +26]); 96 else if (c > 0xef && c < 0xfa) 97 strcpy((char *)Gkey, keyCharMap[c -0xf0 +36]); 98 else 99 return 0; 100 return Gkey; 101} 102 103int UseOtherKeymap(uiContext d) 104{ 105 struct map *p; 106 unsigned char showKey[10]; 107 108 strcpy((char *)showKey, (char *)showChar(d->ch)); 109 p = mapFromHash((KanjiMode)d->current_mode->keytbl, 110 d->ch, (struct map ***)0); 111 if (p == (struct map *)NULL) 112 return NothingChangedWithBeep(d); 113 p->mode->ftbl = (struct funccfunc *)d->current_mode; 114 keyHistory = (unsigned char *)malloc(strlen((char *)showKey) + 1); 115 if (keyHistory) { 116 strcpy((char *)keyHistory,(char *)showKey); 117 makeGLineMessageFromString(d, (char *)keyHistory); 118 if (p->mode->keytbl == (BYTE *)NULL) { 119 free(keyHistory); 120 return NothingChangedWithBeep(d); 121 } 122 d->current_mode = p->mode; 123 } 124 return NothingForGLine(d); 125} 126 127static 128int _DoFuncSequence(uiContext d, BYTE *keytbl, BYTE key) 129{ 130 int res, total_res, ginfo = 0; 131 int prevEchoLen = -1, prevRevPos, prevRevLen; 132 int prevGEchoLen, prevGRevPos, prevGRevLen; 133 WCHAR_T *prevEcho, *prevGEcho; 134 BYTE *p; 135 WCHAR_T *malloc_echo = (WCHAR_T *)0, *malloc_gline = (WCHAR_T *)0; 136 137 if (key == 0) { 138 key = (BYTE)d->ch; 139 } 140 if (keytbl == (BYTE *)NULL) 141 keytbl = d->current_mode->keytbl; 142 143 p = actFromHash(keytbl, key); 144 145 if (p == (BYTE *)NULL) { 146 return 0; 147 } 148 149 total_res = 0; 150 for(; *p ; p++) { 151 /* £²²óÌܰʹߤ˰ʲ¼¤Î¥Ç¡¼¥¿¤¬¼º¤ï¤ì¤Æ¤¤¤ë¾ì¹ç¤¬¤¢¤ë¤Î¤ÇÆþ¤ìľ¤¹¡£ */ 152 d->ch = (unsigned)(*(d->buffer_return) = (WCHAR_T)key); 153 d->nbytes = 1; 154 res = _doFunc(d, (int)*p); /* À¸¤Î doFunc ¤ò¸Æ¤Ö¡£ */ 155 156 if (d->kanji_status_return->length >= 0) { 157 prevEcho = d->kanji_status_return->echoStr; 158 prevEchoLen = d->kanji_status_return->length; 159 prevRevPos = d->kanji_status_return->revPos; 160 prevRevLen = d->kanji_status_return->revLen; 161 if (d->genbuf <= prevEcho && prevEcho < d->genbuf + ROMEBUFSIZE) { 162 /* ¥Ç¡¼¥¿¤Ï d->genbuf ¤Ë¤¢¤ë¤Í */ 163 if (!malloc_echo && 164 !(malloc_echo = 165 (WCHAR_T *)malloc(ROMEBUFSIZE * sizeof(WCHAR_T)))) { 166 res = -1; /* ¥¨¥é¡¼¤¬¤â¤È¤â¤ÈÊ֤äÆÍ褿¤È¤¤¤¦¤³¤È¤Ë¤¹¤ë */ 167 } 168 else { 169 prevEcho = malloc_echo; 170 WStrncpy(prevEcho, d->kanji_status_return->echoStr, prevEchoLen); 171 prevEcho[prevEchoLen] = (WCHAR_T)0; 172 d->kanji_status_return->echoStr = prevEcho; 173 } 174 } 175 } 176 if (d->kanji_status_return->info & KanjiGLineInfo) { 177 ginfo = 1; 178 prevGEcho = d->kanji_status_return->gline.line; 179 prevGEchoLen = d->kanji_status_return->gline.length; 180 prevGRevPos = d->kanji_status_return->gline.revPos; 181 prevGRevLen = d->kanji_status_return->gline.revLen; 182 if (d->genbuf <= prevGEcho && prevGEcho < d->genbuf + ROMEBUFSIZE) { 183 /* ¥Ç¡¼¥¿¤Ï d->genbuf ¤Ë¤¢¤ë¤Í */ 184 if (!malloc_gline && 185 !(malloc_gline = 186 (WCHAR_T *)malloc(ROMEBUFSIZE * sizeof(WCHAR_T)))) { 187 res = -1; /* ¥¨¥é¡¼¤¬¤â¤È¤â¤ÈÊ֤äÆÍ褿¤È¤¤¤¦¤³¤È¤Ë¤¹¤ë */ 188 } 189 else { 190 prevGEcho = malloc_gline; 191 WStrncpy(prevGEcho, d->kanji_status_return->gline.line, 192 prevGEchoLen); 193 prevGEcho[prevGEchoLen] = (WCHAR_T)0; 194 d->kanji_status_return->gline.line = prevGEcho; 195 d->kanji_status_return->info &= ~KanjiGLineInfo; 196 } 197 } 198 } 199 if (res < 0) { 200 break; 201 } 202 if (res > 0) { 203 total_res += res; 204 d->buffer_return += res; 205 d->n_buffer -= res; 206 } 207 } 208 total_res = _afterDoFunc(d, total_res); 209 d->flags |= MULTI_SEQUENCE_EXECUTED; 210 if (malloc_echo) { 211 WStrncpy(d->genbuf, prevEcho, prevEchoLen); 212 d->genbuf[prevEchoLen] = (WCHAR_T)0; 213 free(malloc_echo); /* ¿ʬ malloc_echo ¤¬ prevEcho ¤«¤â */ 214 prevEcho = d->genbuf; 215 } 216 d->kanji_status_return->echoStr = prevEcho; 217 d->kanji_status_return->length = prevEchoLen; 218 d->kanji_status_return->revPos = prevRevPos; 219 d->kanji_status_return->revLen = prevRevLen; 220 if (ginfo) { 221 if (malloc_gline) { 222 WStrncpy(d->genbuf, prevGEcho, prevGEchoLen); 223 d->genbuf[prevGEchoLen] = (WCHAR_T)0; 224 free(malloc_gline); /* ¿ʬ malloc_gline ¤¬ prevGEcho ¤«¤â */ 225 prevGEcho = d->genbuf; 226 } 227 d->kanji_status_return->gline.line = prevGEcho; 228 d->kanji_status_return->gline.length = prevGEchoLen; 229 d->kanji_status_return->gline.revPos = prevGRevPos; 230 d->kanji_status_return->gline.revLen = prevGRevLen; 231 d->kanji_status_return->info |= KanjiGLineInfo; 232 } 233 return total_res; 234} 235 236int DoFuncSequence(uiContext d) 237{ 238 return _DoFuncSequence(d, (BYTE *)NULL, (BYTE)NULL); 239} 240 241int 242multiSequenceFunc(uiContext d, KanjiMode mode, int whattodo, int key, int fnum) 243{ 244 int i; 245 unsigned char *p; 246 struct map *m; 247 248 if (whattodo != KEY_CALL) 249 return 0; 250 251 if (fnum == CANNA_FN_Kakutei || fnum == CANNA_FN_Quit || askQuitKey(key)) { 252 /* Kakutei ¤Ï KC_KAKUTEI ¤Ø¤ÎÂбþ */ 253 free(keyHistory); 254 GlineClear(d); 255 d->current_mode = (KanjiMode)(mode->ftbl); 256 if (d->current_mode->flags & CANNA_KANJIMODE_EMPTY_MODE) { 257 d->kanji_status_return->info |= KanjiEmptyInfo; 258 } 259 /* Nop ¤ò¹Ô¤¦ */ 260 (void)doFunc(d, CANNA_FN_Nop); 261 d->flags |= MULTI_SEQUENCE_EXECUTED; 262 return 0; 263 } 264 for (i= 0, p = mode->keytbl; *p != 255; p += 2,i+=2) { 265 debug_message("multiSequenceFunc:\263\254\301\330[%d]\n",i,0,0); 266 /* ³¬ÁØ */ 267 if (*p == key) { /* ¤³¤Î¥¡¼¤ÏÅÐÏ¿¤µ¤ì¤Æ¤¤¤¿¡£ */ 268 keyHistory = 269 (unsigned char *)realloc(keyHistory, strlen((char *)keyHistory) + strlen((char *)showChar(key)) +2); 270 if (keyHistory) { 271 strcat((char *)keyHistory," "); 272 strcat((char *)keyHistory,(char *)showChar(key)); 273 274 makeGLineMessageFromString(d, (char *)keyHistory); 275 if (*++p == CANNA_FN_UseOtherKeymap) { /* ¤Þ¤À¥¡¼¥·¥±¥ó¥¹¤Î³¤¤¬Â¸ºß */ 276 m = mapFromHash(mode, key, (struct map ***)0); 277 m->mode->ftbl = mode->ftbl; 278 d->current_mode = m->mode; 279 return NothingForGLine(d); 280 } 281 free(keyHistory); 282 } 283 GlineClear(d); 284 d->current_mode = (KanjiMode)(mode->ftbl); /* µ¡Ç½¤ò¼Â¹Ô */ 285 if (*p == CANNA_FN_FuncSequence) { 286 return _DoFuncSequence(d, (unsigned char *)mode, key); 287 } 288 return (*d->current_mode->func)(d, d->current_mode, KEY_CALL, 0, *p); 289 } 290 } 291 return NothingForGLineWithBeep(d); /* ÅÐÏ¿¤·¤Æ¤¤¤Ê¤¤¥¡¼¤ò²¡¤·¤¿ */ 292} 293