comparison lib/Xsj3clib/func.c @ 0:92745d501b9a

initial import from kinput2-v3.1
author Yoshiki Yazawa <yaz@honeyplanet.jp>
date Mon, 08 Mar 2010 04:44:30 +0900
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:92745d501b9a
1 #ifndef lint
2 static char *rcsid = "$Id: func.c,v 2.3 1993/09/21 09:42:57 nao Exp $";
3 #endif
4 /*
5 * Copyright 1991 Sony Corporation
6 *
7 * Permission to use, copy, modify, distribute, and sell this software and its
8 * documentation for any purpose is hereby granted without fee, provided that
9 * the above copyright notice appear in all copies and that both that
10 * copyright notice and this permission notice appear in supporting
11 * documentation, and that the name of Sony not be used in advertising or
12 * publicity pertaining to distribution of the software without specific,
13 * written prior permission. Sony makes no representations about the
14 * suitability of this software for any purpose. It is provided "as is"
15 * without express or implied warranty.
16 *
17 * SONY DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SONY
19 * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
20 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
21 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
22 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23 */
24 /*
25 * Author: Naoshi Suzuki, SONY Corporation. (nao@sm.sony.co.jp)
26 */
27
28 #include <ctype.h>
29 #include "common.h"
30 #include "sj3ctype.h"
31 #include "util.h"
32 #include "func.h"
33
34 extern Xsj3cCVServerIF serverIF[SERVER_NUM];
35 extern void Xsj3cRCInit();
36 extern int _Xsj3cRomaConv();
37 extern int _Xsj3cKanaConv();
38 extern Xsj3cCand _Xsj3cCandidateInit();
39 extern void _Xsj3cFlushDictMsg();
40 extern Xsj3cDictData _Xsj3cCreateDictData();
41
42 Xsj3cEvent _Xsj3cConvert();
43 Xsj3cEvent _Xsj3cUnConvert();
44 Xsj3cEvent _Xsj3cFix();
45 Xsj3cEvent _Xsj3cReturn();
46
47 Xsj3cEvent _Xsj3cModeHAlpha();
48 Xsj3cEvent _Xsj3cModeZAlpha();
49 Xsj3cEvent _Xsj3cModeHKata();
50 Xsj3cEvent _Xsj3cModeZKata();
51 Xsj3cEvent _Xsj3cModeHira();
52 Xsj3cEvent _Xsj3cToHAlpha();
53 Xsj3cEvent _Xsj3cToZAlpha();
54 Xsj3cEvent _Xsj3cToHKata();
55 Xsj3cEvent _Xsj3cToZKata();
56 Xsj3cEvent _Xsj3cToHira();
57 Xsj3cEvent _Xsj3cZenkaku();
58 Xsj3cEvent _Xsj3cHankaku();
59 Xsj3cEvent _Xsj3cToUpper();
60 Xsj3cEvent _Xsj3cToLower();
61 Xsj3cEvent _Xsj3cModeSJIS();
62 Xsj3cEvent _Xsj3cModeEUC();
63 Xsj3cEvent _Xsj3cModeJIS();
64 Xsj3cEvent _Xsj3cModeKuten();
65 Xsj3cEvent _Xsj3cCodeRollDown();
66 Xsj3cEvent _Xsj3cModeRollDown();
67 Xsj3cEvent _Xsj3cModeRollUp();
68 Xsj3cEvent _Xsj3cNextMode();
69 Xsj3cEvent _Xsj3cPrevMode();
70 Xsj3cEvent _Xsj3cModeToggle();
71
72 Xsj3cEvent _Xsj3cForward();
73 Xsj3cEvent _Xsj3cBackward();
74 Xsj3cEvent _Xsj3cTop();
75 Xsj3cEvent _Xsj3cEnd();
76 Xsj3cEvent _Xsj3cUp();
77 Xsj3cEvent _Xsj3cDown();
78 Xsj3cEvent _Xsj3cFirst();
79 Xsj3cEvent _Xsj3cLast();
80 Xsj3cEvent _Xsj3cNextPage();
81 Xsj3cEvent _Xsj3cPrevPage();
82 Xsj3cEvent _Xsj3cNext();
83 Xsj3cEvent _Xsj3cPrev();
84 Xsj3cEvent _Xsj3cSelect();
85 Xsj3cEvent _Xsj3cCancel();
86
87 Xsj3cEvent _Xsj3cExpand();
88 Xsj3cEvent _Xsj3cShrink();
89
90 Xsj3cEvent _Xsj3cBackSpace();
91 Xsj3cEvent _Xsj3cDelete();
92 Xsj3cEvent _Xsj3cDelAfter();
93
94 Xsj3cEvent _Xsj3cStart();
95 Xsj3cEvent _Xsj3cReConnect();
96 Xsj3cEvent _Xsj3cReConvert();
97 Xsj3cEvent _Xsj3cEdit();
98
99 Xsj3cEvent _Xsj3cDRegBegin();
100 Xsj3cEvent _Xsj3cDClearBegin();
101
102 Xsj3cEvent _Xsj3cSymbolBegin();
103
104 Xsj3cEvent _Xsj3cQuote();
105 Xsj3cEvent _Xsj3cBell();
106 Xsj3cEvent _Xsj3cKana();
107 Xsj3cEvent _Xsj3cSjrc();
108 Xsj3cEvent _Xsj3cKill();
109 Xsj3cEvent _Xsj3cNull();
110 Xsj3cEvent _Xsj3cIgnore();
111
112 Xsj3cEvent _Xsj3cUnConvSeg();
113
114 static Xsj3cEvent _Xsj3cDeleteSeg();
115 static Xsj3cEvent _Xsj3cDeleteChar();
116 static Xsj3cEvent _Xsj3cBackSpaceChar();
117 static Xsj3cEvent _Xsj3cExpandNoConv();
118 static Xsj3cEvent _Xsj3cShrinkNoConv();
119
120 /*
121 * _Xsj3cConvert() [henkan/convert]
122 *
123 * <InputMode> Do kana-kanji conversion.
124 * <ConvedMode> If character mode of current segment is zenkaku-hiragana,
125 * pop up candidate panel, else convert to zenkaku-hiragana.
126 * <NoInputMode/SelectMode/DictMode> Rings bell.
127 *
128 * BeginConversionLast none: Set current segment out of segments.
129 * BeginConversionLast off: Set current segment to the first segment.
130 * BeginConversionLast on: Set current segment to the last segment.
131 * DisplayModeChange on: Change the display mode string.
132 * HenkanSegment all: Convert all segments.
133 * HenkanSegment after: Convert segments after current segment.
134 * HenkanSegment one: Convert current segment.
135 * BeforeSelectConversion on: Convert current segment to hiragana
136 * and need one more step to display candidates.
137 * BeforeConversion on: Convert current segment to hiragana before
138 * Kana-Kanji conversion.
139 * BeforeSelectCount: Work like "next/wrap" before popup candidate panel
140 * at [ConvedMode].
141 * LastDoubleConversion on: Before Kana-Kanji conversion, convert current
142 * segment to current character mode.
143 */
144 Xsj3cEvent
145 _Xsj3cConvert(buf)
146 Xsj3cBuf buf;
147 {
148 unsigned char knjbuf[KANJIBUFSIZ];
149 unsigned char kanabuf[KANJIBUFSIZ];
150 Xsj3cEvent ret = KEY_NULL;
151 SJ3_BUNSETU bun[BUNBUFSIZ];
152 int i, value;
153 register int conved, begin, end;
154
155 if (buf->segnum && buf->curseg >= buf->segnum) {
156 buf->curseg = buf->segnum - 1;
157 if (buf->input[buf->curseg] &&
158 (buf->input[buf->curseg]->status & SEG_CONVED))
159 buf->convmode = ConvedModeMask;
160 else
161 buf->convmode = InputModeMask;
162 ret = KEY_TEXT_CHANGE;
163 }
164 if ((buf->convmode & (InputModeMask|ConvedModeMask))
165 && buf->curseg < buf->segnum) {
166 if (buf->convmode & ConvedModeMask) {
167 if (buf->selectconv &&
168 buf->input[buf->curseg]->cursegmode != MODE_HIRA) {
169 ret |= _Xsj3cModeChange(buf, MODE_HIRA, ON);
170 buf->convedsegnum--;
171 buf->input[buf->curseg]->status = SEG_NOCONV;
172 } else {
173 if (buf->selectcount > 0) {
174 int cur;
175 if (!buf->candidate)
176 Xsj3cGetCandidateNum(buf, &cur);
177 if (buf->selectcount < buf->candnum) {
178 if (buf->n_select < buf->selectcount) {
179 buf->n_select++;
180 return(_Xsj3cNext(buf));
181 }
182 }
183 }
184 buf->convmode = SelectModeMask;
185 ret |= KEY_CAND_START;
186 if (buf->dispmodechange) {
187 buf->dispmode = MODE_CAND;
188 ret |= KEY_MODE_CHANGE;
189 }
190 buf->selectstatus = SELECT_CAND;
191 buf->n_select = 0;
192 return (ret);
193 }
194 } else if (buf->beforeconv) {
195 register wchar *p;
196 p = buf->input[buf->curseg]->yomi;
197 while (*p != '\0') {
198 if (!ishira(*p, serverIF[buf->server].lang)) {
199 ret |= _Xsj3cModeChange(buf, MODE_HIRA, ON);
200 break;
201 }
202 p++;
203 }
204 } else if (buf->lastdoubleconv && *buf->rkdouble != '\0') {
205 register unsigned char *p, q;
206 i = buf->input[buf->curseg]->num - 1;
207 q = buf->input[buf->curseg]->yomi[i] & 0xff;
208 p = buf->rkdouble;
209 while (*p != '\0') {
210 if (*p == q) {
211 ret |= _Xsj3cModeChange(buf,
212 buf->input[buf->curseg]->cursegmode, ON);
213 break;
214 }
215 p++;
216 }
217 }
218 ret |= KEY_TEXT_CHANGE;
219 switch (buf->henkanseg) {
220 case ALL:
221 begin = 0;
222 end = buf->segnum;
223 break;
224 case AFTER:
225 begin = buf->curseg;
226 end = buf->segnum;
227 break;
228 case ONE:
229 default:
230 begin = buf->curseg;
231 end = buf->curseg + 1;
232 break;
233 }
234
235 conved = buf->convedsegnum;
236 if (!buf->input[begin]->num) {
237 return (ret);
238 }
239 for (i = begin; i < end; i += value) {
240 if (buf->input[i]->status == SEG_CONVED) {
241 value = 1;
242 continue;
243 }
244 if (buf->input[i]->num > INPUT_YOMI_MAX || !buf->input[i]->num) {
245 Xsj3cWarning("Too long or short segment[%d].", i);
246 ret |= KEY_BELL;
247 value = 1;
248 continue;
249 }
250 buf->input[i]->n_roma = 0;
251 buf->input[i]->n_kana = -1;
252 *buf->input[i]->str = '\0';
253 buf->input[i]->sp = buf->input[i]->str;
254 *buf->input[i]->oldstr = '\0';
255 _Xsj3cwPStomPS(buf, kanabuf, buf->input[i]->yomi);
256 value = serverIF[buf->server].func[FUNC_CONV]
257 (kanabuf, bun, knjbuf, KANJIBUFSIZ);
258 if (value <= 0) {
259 if (value < 0)
260 Xsj3cWarning("sj3serv is down. reconnect please");
261 else
262 Xsj3cWarning("Too long segment[%d]. Could not convert.", i);
263 ret |= KEY_BELL;
264 value = 1;
265 continue;
266 }
267 _Xsj3cStoreKanji(buf, bun, i, value, OFF);
268 buf->convedsegnum += value;
269 buf->segnum += (--value);
270 }
271 if (buf->henkanseg != ONE || !conved) {
272 switch (buf->beginlastseg) {
273 case NONE:
274 buf->curseg = buf->segnum;
275 break;
276 case ON:
277 buf->curseg = buf->segnum - 1;
278 break;
279 case OFF:
280 buf->curseg = 0;
281 break;
282 default:
283 buf->curseg = 0;
284 break;
285 }
286 }
287 if (buf->dispmodechange) {
288 buf->dispmode = (buf->convedsegnum == buf->segnum ? MODE_KANJI :
289 (buf->convedsegnum ? MODE_EDIT : buf->inputmode));
290 ret |= KEY_MODE_CHANGE;
291 }
292 return ret;
293 } else {
294 #ifdef THROUGH_CONT
295 return (KEY_BELL);
296 #else /* THROUGH_CONT */
297 if (buf->cntrlsame)
298 return (KEY_BELL);
299 else
300 return (KEY_TEXT_CHANGE|KEY_BELL); /* dummy */
301 #endif /* THROUGH_CONT */
302 }
303 }
304
305 /*
306 * _Xsj3cUnConvert() [muhen/unconvert]
307 *
308 * <InputMode/ConvedMode> Unconvert segments.
309 * <SelectMode> pop down the panel candidate(symbol/hinsi) panel and
310 * unconvert segments.
311 * <DictMode> Pop down Auxpanel and unconvert segments.
312 * <NoInputMode> Does nothing.
313 *
314 * DisplayModeChange on: Change the display mode string.
315 * MuhenkanCursorLast on: Set cursor position to bottom of segment.
316 * MuhenkanCursorLast off: Set cursor position to top of segment.
317 * MuhenkanSegment all: Unconvert all segments.
318 * MuhenkanSegment after: Unconvert segments after current segment.
319 * MuhenkanSegment one: Unconvert current segment.
320 */
321 Xsj3cEvent
322 _Xsj3cUnConvert(buf)
323 Xsj3cBuf buf;
324 {
325 Xsj3cEvent ret = KEY_NULL;
326
327 if (buf->convmode & SelectModeMask) {
328 ret |= KEY_SELECT_ABORT;
329 if (buf->selectstatus == SELECT_HINSI) {
330 ret |= KEY_DICT_END;
331 }
332 } else if (buf->convmode & DictModeMask) {
333 ret |= KEY_DICT_END;
334 } else if (buf->convmode & NoInputModeMask) {
335 #ifdef THROUGH_CONT
336 return (KEY_NULL);
337 #else /* THROUGH_CONT */
338 if (buf->cntrlsame)
339 return (KEY_NULL);
340 else
341 return (KEY_TEXT_CHANGE); /* dummy */
342 #endif /* THROUGH_CONT */
343 }
344 buf->convmode = InputModeMask;
345 ret |= _Xsj3cUnConvSeg(buf, buf->muhenseg, buf->muhencurlast);
346 _Xsj3cStoreYomi(buf, buf->input[buf->curseg], 0);
347 return (ret);
348 }
349
350 /*
351 * _Xsj3cUnConvSeg()
352 * Change current segment back to non converted
353 * and set converion mode to InputMode.
354 */
355 Xsj3cEvent
356 _Xsj3cUnConvSeg(buf, muhenseg, muhencurlast)
357 Xsj3cBuf buf;
358 Xsj3cFlag muhenseg, muhencurlast;
359 {
360 register int i, begin, end, unconved = 0;
361 Xsj3cEvent ret = KEY_TEXT_CHANGE;
362
363 buf->n_select = 0;
364 if (buf->candidate)
365 Xsj3cEndCandidate(buf, OFF);
366 switch (muhenseg) {
367 case ALL:
368 begin = 0;
369 end = buf->segnum;
370 break;
371 case AFTER:
372 begin = buf->curseg;
373 end = buf->segnum;
374 break;
375 case ONE:
376 default:
377 begin = buf->curseg;
378 end = buf->curseg + 1;
379 break;
380 }
381 for (i = begin; i < end; i++) {
382 if (buf->input[begin]->status == SEG_NOCONV)
383 unconved++;
384 else
385 break;
386 }
387 if (unconved == (end - begin)) {
388 #ifdef THROUGH_CONT
389 return (KEY_NULL);
390 #else /* THROUGH_CONT */
391 if (buf->cntrlsame)
392 return (KEY_NULL);
393 else
394 return (KEY_TEXT_CHANGE); /* dummy */
395 #endif /* THROUGH_CONT */
396 }
397 for (i = begin + 1; i < end; i++) {
398 _Xsj3cWcat(buf->input[begin]->yomi, buf->input[i]->yomi);
399 buf->input[begin]->num += buf->input[i]->num;
400 }
401 buf->input[begin]->cur = buf->input[begin]->num;
402 for (i = begin + 1; i < end; i++) {
403 Xsj3cFreeSegment(buf->input[i]);
404 buf->input[i] = NULL;
405 }
406 Xsj3cFreeSegment(buf->input[buf->segnum]);
407 buf->input[buf->segnum] = NULL;
408 buf->segnum -= (end - begin - 1);
409 buf->curseg = begin;
410 buf->convedsegnum -= (end - begin);
411 if (!buf->convedsegnum) {
412 if (buf->gakusyuu)
413 _Xsj3cClearDcid(buf);
414 if (buf->dispmodechange) {
415 buf->dispmode = buf->inputmode;
416 ret |= KEY_MODE_CHANGE;
417 }
418 } else if (buf->dispmodechange) {
419 buf->dispmode = ((buf->segnum
420 && buf->convedsegnum == buf->segnum) ? MODE_KANJI :
421 (buf->convedsegnum ? MODE_EDIT : buf->inputmode));
422 ret |= KEY_MODE_CHANGE;
423 }
424 buf->input[begin]->change = OFF;
425 buf->input[begin]->status = SEG_NOCONV;
426 if (!(buf->movebyseg & SEG_NOCONV))
427 buf->input[begin]->edit = SEG_EDIT;
428 if (muhencurlast)
429 buf->input[begin]->cur = buf->input[begin]->num;
430 else
431 buf->input[begin]->cur = 0;
432 return (ret);
433 }
434
435 /*
436 * _Xsj3cFix() [kettei/flush/fix]
437 *
438 * <InputMode/ConvedMode> Fix all segments.
439 * the candidate(symbol) panel.
440 * <SelectMode> Select reversed candidate(symbol/hinsi)
441 * in the candidate(symbol/hinsi) panel and pop down the panel.
442 * <DictMode> (DICT_INPUT) Decide current yomi character string.
443 * (DICT_CONFIRM) Confirm to register/eliminate word.
444 * (DICT_END) Pop down Auxpanel
445 * <NoInputMode> Does nothing.
446 *
447 * DisplayModeChange on: Change the display mode string.
448 */
449 Xsj3cEvent
450 _Xsj3cFix(buf)
451 Xsj3cBuf buf;
452 {
453 switch (buf->convmode) {
454 case SelectModeMask:
455 if (buf->selectstatus == SELECT_HINSI) {
456 buf->dict->status = DICT_CONFIRM;
457 if (buf->dispmodechange) {
458 buf->dispmode =
459 (buf->dict->mode == REG_STATE ? MODE_TOROKU : MODE_SYOUKYO);
460 return (KEY_SELECT_END|KEY_DICT_CHANGE|KEY_MODE_CHANGE);
461 } else
462 return (KEY_SELECT_END|KEY_DICT_CHANGE);
463 } else {
464 if (buf->dispmodechange) {
465 buf->dispmode = buf->inputmode;
466 return (KEY_TEXT_FIXED|KEY_TEXT_CHANGE
467 |KEY_SELECT_END|KEY_MODE_CHANGE);
468 } else
469 return (KEY_TEXT_FIXED|KEY_TEXT_CHANGE|KEY_SELECT_END);
470 }
471 case DictModeMask:
472 switch (buf->dict->status) {
473 case DICT_INPUT:
474 if (buf->dict->seg->num > 0) {
475 if (buf->dict->seg->num > DICT_YOMI_MAX) {
476 buf->dict->status = DICT_END;
477 buf->curhinsi = -1;
478 buf->dict->value = SJ3_LONG_YOMI_STR;
479 _Xsj3cFlushDictMsg(buf);
480 return(KEY_DICT_CHANGE);
481 } else {
482 if (buf->dict->mode == REG_STATE) {
483 buf->dict->status = DICT_HINSI;
484 buf->selectstatus = SELECT_HINSI;
485 buf->convmode = SelectModeMask;
486 _Xsj3cFlushDictMsg(buf);
487 if (buf->dispmodechange) {
488 buf->dispmode = MODE_HINSI;
489 return (KEY_HINSI_START|KEY_MODE_CHANGE);
490 } else
491 return (KEY_HINSI_START);
492 } else {
493 buf->dict->status = DICT_CONFIRM;
494 _Xsj3cFlushDictMsg(buf);
495 return (KEY_DICT_CHANGE);
496 }
497 }
498 } else {
499 buf->dict->status = DICT_END;
500 buf->curhinsi = -1;
501 buf->dict->value = SJ3_NO_YOMI_STR;
502 _Xsj3cFlushDictMsg(buf);
503 return(KEY_DICT_CHANGE);
504 }
505 case DICT_CONFIRM:
506 buf->dict->status = DICT_END;
507 return (buf->dict->mode == REG_STATE ?
508 KEY_DICT_REGISTER : KEY_DICT_CLEAR);
509 case DICT_END:
510 if (buf->dispmodechange) {
511 buf->dispmode
512 = (buf->convedsegnum == buf->segnum ? MODE_KANJI :
513 (buf->convedsegnum ? MODE_EDIT : buf->inputmode));
514 return(KEY_DICT_END|KEY_TEXT_CHANGE|KEY_MODE_CHANGE);
515 } else
516 return(KEY_DICT_END|KEY_TEXT_CHANGE);
517 default:
518 #ifdef THROUGH_CONT
519 return (KEY_BELL);
520 #else /* THROUGH_CONT */
521 if (buf->cntrlsame)
522 return (KEY_BELL);
523 else
524 return (KEY_TEXT_CHANGE|KEY_BELL); /* dummy */
525 #endif /* THROUGH_CONT */
526 }
527 case NoInputModeMask:
528 #ifdef THROUGH_CONT
529 return (KEY_NULL);
530 #else /* THROUGH_CONT */
531 if (buf->cntrlsame)
532 return (KEY_NULL);
533 else
534 return (KEY_TEXT_CHANGE); /* dummy */
535 #endif /* THROUGH_CONT */
536 case InputModeMask:
537 case ConvedModeMask:
538 default:
539 if (buf->dispmodechange) {
540 buf->dispmode = buf->inputmode;
541 return (KEY_TEXT_FIXED|KEY_TEXT_CHANGE|KEY_MODE_CHANGE);
542 } else
543 return (KEY_TEXT_FIXED|KEY_TEXT_CHANGE);
544 }
545 }
546
547 /*
548 * _Xsj3cReturn() [return]
549 *
550 * <NoInputMode/InputMode> Put the carriage return after current position
551 * and fix all segments.
552 * <ConvedMode> Put the carriage return after current segment
553 * and fix all segments.
554 * <SelectMode> Select reversed candidate(symbol/hinsi)
555 * in the candidate(symbol/hinsi) panel and pop down the panel.
556 * <DictMode> (DICT_INPUT) Decide current yomi character string.
557 * (DICT_CONFIRM) Confirm to register/eliminate word.
558 * (DICT_END) Pop down Auxpanel
559 *
560 * DisplayModeChange on: Change the display mode string.
561 */
562 Xsj3cEvent
563 _Xsj3cReturn(buf)
564 Xsj3cBuf buf;
565 {
566 unsigned char ch[2];
567 int change_pos;
568 register int i;
569
570 switch (buf->convmode) {
571 case NoInputModeMask:
572 buf->convmode = InputModeMask;
573 case InputModeMask:
574 if (buf->segnum == buf->curseg)
575 buf->segnum++;
576 ch[0] = '\r';
577 ch[1] = '\0';
578 change_pos = buf->input[buf->curseg]->cur;
579 _Xsj3cInsertChar(buf, buf->input[buf->curseg], ch, 1);
580 _Xsj3cStoreYomi(buf, buf->input[buf->curseg], change_pos);
581 if (buf->dispmodechange) {
582 buf->dispmode = buf->inputmode;
583 return (KEY_TEXT_FIXED|KEY_TEXT_CHANGE|KEY_MODE_CHANGE);
584 } else
585 return (KEY_TEXT_FIXED|KEY_TEXT_CHANGE);
586 case ConvedModeMask:
587 i = buf->input[buf->curseg]->dnum;
588 buf->input[buf->curseg]->disp[i++] = '\n';
589 buf->input[buf->curseg]->disp[i] = '\0';
590 buf->input[buf->curseg]->dnum++;
591 if (buf->dispmodechange) {
592 buf->dispmode = buf->inputmode;
593 return (KEY_TEXT_FIXED|KEY_TEXT_CHANGE|KEY_MODE_CHANGE);
594 } else
595 return (KEY_TEXT_FIXED|KEY_TEXT_CHANGE);
596 case DictModeMask:
597 switch (buf->dict->status) {
598 case DICT_INPUT:
599 if (buf->dict->seg->num) {
600 if (buf->dict->seg->num > DICT_YOMI_MAX) {
601 buf->dict->status = DICT_END;
602 buf->curhinsi = -1;
603 buf->dict->value = SJ3_LONG_YOMI_STR;
604 _Xsj3cFlushDictMsg(buf);
605 return(KEY_DICT_CHANGE);
606 } else {
607 if (buf->dict->mode == REG_STATE) {
608 buf->dict->status = DICT_HINSI;
609 buf->selectstatus = SELECT_HINSI;
610 buf->convmode = SelectModeMask;
611 _Xsj3cFlushDictMsg(buf);
612 if (buf->dispmodechange) {
613 buf->dispmode = MODE_HINSI;
614 return (KEY_HINSI_START|KEY_MODE_CHANGE);
615 } else
616 return (KEY_HINSI_START);
617 } else {
618 buf->dict->status = DICT_CONFIRM;
619 _Xsj3cFlushDictMsg(buf);
620 return (KEY_DICT_CHANGE);
621 }
622 }
623 } else {
624 buf->dict->status = DICT_END;
625 buf->curhinsi = -1;
626 buf->dict->value = SJ3_NO_YOMI_STR;
627 _Xsj3cFlushDictMsg(buf);
628 return(KEY_DICT_CHANGE);
629 }
630 case DICT_CONFIRM:
631 buf->dict->status = DICT_END;
632 return (buf->dict->mode == REG_STATE ?
633 KEY_DICT_REGISTER : KEY_DICT_CLEAR);
634 case DICT_END:
635 if (buf->dispmodechange) {
636 buf->dispmode
637 = (buf->convedsegnum == buf->segnum ? MODE_KANJI :
638 (buf->convedsegnum ? MODE_EDIT : buf->inputmode));
639 return(KEY_DICT_END|KEY_TEXT_CHANGE|KEY_MODE_CHANGE);
640 } else
641 return(KEY_DICT_END|KEY_TEXT_CHANGE);
642 default:
643 #ifdef THROUGH_CONT
644 return (KEY_BELL);
645 #else /* THROUGH_CONT */
646 if (buf->cntrlsame)
647 return (KEY_BELL);
648 else
649 return (KEY_TEXT_CHANGE|KEY_BELL); /* dummy */
650 #endif /* THROUGH_CONT */
651 }
652 case SelectModeMask:
653 if (buf->selectstatus == SELECT_HINSI) {
654 buf->dict->status = DICT_CONFIRM;
655 if (buf->dispmodechange) {
656 buf->dispmode =
657 (buf->dict->mode == REG_STATE ? MODE_TOROKU : MODE_SYOUKYO);
658 return (KEY_SELECT_END|KEY_DICT_CHANGE|KEY_MODE_CHANGE);
659 } else
660 return (KEY_SELECT_END|KEY_DICT_CHANGE);
661 } else {
662 if (buf->dispmodechange) {
663 buf->dispmode = (buf->convedsegnum == buf->segnum ? MODE_KANJI :
664 (buf->convedsegnum ? MODE_EDIT : buf->inputmode));
665 return (KEY_SELECT_END|KEY_MODE_CHANGE);
666 } else
667 return (KEY_SELECT_END);
668 }
669 default:
670 #ifdef THROUGH_CONT
671 return (KEY_BELL);
672 #else /* THROUGH_CONT */
673 if (buf->cntrlsame)
674 return (KEY_BELL);
675 else
676 return (KEY_TEXT_CHANGE|KEY_BELL); /* dummy */
677 #endif /* THROUGH_CONT */
678 }
679 }
680
681 /*
682 * _Xsj3cModeHAlpha() [halpha]
683 *
684 * <NoInputMode/InputMode/ConvedMode/DictMode> Change character mode
685 * to "hankaku-ascii".
686 * <SelectMode> Ring bell.
687 *
688 * ModeConversion on: Convert character mode of current segment
689 * to "hankaku-ascii".
690 * ModeConversion off: Change character mode of input mode.
691 */
692 Xsj3cEvent
693 _Xsj3cModeHAlpha(buf)
694 Xsj3cBuf buf;
695 {
696 Xsj3cFlag conv;
697
698 if (!buf->segnum) {
699 if (buf->modeconv[MODE_HALPHA] >> 2) {
700 #ifdef THROUGH_CONT
701 return (KEY_NULL);
702 #else /* THROUGH_CONT */
703 if (buf->cntrlsame)
704 return (KEY_NULL);
705 else
706 return (KEY_TEXT_CHANGE); /* dummy */
707 #endif /* THROUGH_CONT */
708 } else
709 conv = OFF;
710 } else if (buf->input[buf->curseg] &&
711 buf->input[buf->curseg]->status & buf->modeconv[MODE_HALPHA]) {
712 conv = ON;
713 } else {
714 conv = OFF;
715 }
716 return (_Xsj3cModeChange(buf, MODE_HALPHA, conv));
717 }
718
719 /*
720 * _Xsj3cModeZAlpha() [zalpha]
721 *
722 * <NoInputMode/InputMode/ConvedMode/DictMode> Change character mode
723 * to "zenkaku-ascii".
724 * <SelectMode> Ring bell.
725 *
726 * ModeConversion on: Convert character mode of current segment
727 * to "zenkaku-ascii".
728 * ModeConversion off: Change character mode of input mode.
729 */
730 Xsj3cEvent
731 _Xsj3cModeZAlpha(buf)
732 Xsj3cBuf buf;
733 {
734 Xsj3cFlag conv;
735
736 if (!buf->segnum) {
737 if (buf->modeconv[MODE_ZALPHA] >> 2) {
738 #ifdef THROUGH_CONT
739 return (KEY_NULL);
740 #else /* THROUGH_CONT */
741 if (buf->cntrlsame)
742 return (KEY_NULL);
743 else
744 return (KEY_TEXT_CHANGE); /* dummy */
745 #endif /* THROUGH_CONT */
746 } else
747 conv = OFF;
748 } else if (buf->input[buf->curseg] &&
749 buf->input[buf->curseg]->status & buf->modeconv[MODE_ZALPHA]) {
750 conv = ON;
751 } else {
752 conv = OFF;
753 }
754 return (_Xsj3cModeChange(buf, MODE_ZALPHA, conv));
755 }
756
757 /*
758 * _Xsj3cModeHKata() [hkatakana]
759 *
760 * <NoInputMode/InputMode/ConvedMode/DictMode> Change character mode
761 * to "hankaku-katakana".
762 * <SelectMode> Ring bell.
763 *
764 * ModeConversion on: Convert character mode of current segment
765 * to "hankaku-katakana".
766 * ModeConversion off: Change character mode of input mode.
767 */
768 Xsj3cEvent
769 _Xsj3cModeHKata(buf)
770 Xsj3cBuf buf;
771 {
772 Xsj3cFlag conv;
773
774 if (!buf->segnum) {
775 if (buf->modeconv[MODE_HKATA] >> 2) {
776 #ifdef THROUGH_CONT
777 return (KEY_NULL);
778 #else /* THROUGH_CONT */
779 if (buf->cntrlsame)
780 return (KEY_NULL);
781 else
782 return (KEY_TEXT_CHANGE); /* dummy */
783 #endif /* THROUGH_CONT */
784 } else
785 conv = OFF;
786 } else if (buf->input[buf->curseg] &&
787 buf->input[buf->curseg]->status & buf->modeconv[MODE_HKATA]) {
788 conv = ON;
789 } else {
790 conv = OFF;
791 }
792 return (_Xsj3cModeChange(buf, MODE_HKATA, conv));
793 }
794
795 /*
796 * _Xsj3cModeZKata() [zkatakana]
797 *
798 * <NoInputMode/InputMode/ConvedMode/DictMode> Change character mode
799 * to "zenkaku-katakana".
800 * <SelectMode> Ring bell.
801 *
802 * ModeConversion on: Convert character mode of current segment
803 * to "zenkaku-katakana".
804 * ModeConversion off: Change character mode of input mode.
805 */
806 Xsj3cEvent
807 _Xsj3cModeZKata(buf)
808 Xsj3cBuf buf;
809 {
810 Xsj3cFlag conv;
811
812 if (!buf->segnum) {
813 if (buf->modeconv[MODE_ZKATA] >> 2) {
814 #ifdef THROUGH_CONT
815 return (KEY_NULL);
816 #else /* THROUGH_CONT */
817 if (buf->cntrlsame)
818 return (KEY_NULL);
819 else
820 return (KEY_TEXT_CHANGE); /* dummy */
821 #endif /* THROUGH_CONT */
822 } else
823 conv = OFF;
824 } else if (buf->input[buf->curseg] &&
825 buf->input[buf->curseg]->status & buf->modeconv[MODE_ZKATA]) {
826 conv = ON;
827 } else {
828 conv = OFF;
829 }
830 return (_Xsj3cModeChange(buf, MODE_ZKATA, conv));
831 }
832
833
834 /*
835 * _Xsj3cModeHira() [hiragana]
836 *
837 * <NoInputMode/InputMode/ConvedMode/DictMode> Change character mode
838 * to "hiragana".
839 * <SelectMode> Ring bell.
840 *
841 * ModeConversion on: Convert character mode of current segment to "hiragana".
842 * ModeConversion off: Change character mode of input mode.
843 */
844 Xsj3cEvent
845 _Xsj3cModeHira(buf)
846 Xsj3cBuf buf;
847 {
848 Xsj3cFlag conv;
849
850 if (!buf->segnum) {
851 if (buf->modeconv[MODE_HIRA] >> 2) {
852 #ifdef THROUGH_CONT
853 return (KEY_NULL);
854 #else /* THROUGH_CONT */
855 if (buf->cntrlsame)
856 return (KEY_NULL);
857 else
858 return (KEY_TEXT_CHANGE); /* dummy */
859 #endif /* THROUGH_CONT */
860 } else
861 conv = OFF;
862 } else if (buf->input[buf->curseg] &&
863 buf->input[buf->curseg]->status & buf->modeconv[MODE_HIRA]) {
864 conv = ON;
865 } else {
866 conv = OFF;
867 }
868 return (_Xsj3cModeChange(buf, MODE_HIRA, conv));
869 }
870
871 /*
872 * _Xsj3cToHAlpha() [tohalpha]
873 *
874 * <NoInputTo/InputMode/ConvedMode/DictMode> Convert character mode
875 * to "hankaku-ascii".
876 * <SelectTo> Ring bell.
877 */
878 Xsj3cEvent
879 _Xsj3cToHAlpha(buf)
880 Xsj3cBuf buf;
881 {
882 return (_Xsj3cModeChange(buf, MODE_HALPHA, ON));
883 }
884
885 /*
886 * _Xsj3cToZAlpha() [tozalpha]
887 *
888 * <NoInputTo/InputMode/ConvedMode/DictMode> Convert character mode
889 * to "zenkaku-ascii".
890 * <SelectTo> Ring bell.
891 */
892 Xsj3cEvent
893 _Xsj3cToZAlpha(buf)
894 Xsj3cBuf buf;
895 {
896 return (_Xsj3cModeChange(buf, MODE_ZALPHA, ON));
897 }
898
899 /*
900 * _Xsj3cToHKata() [tohkatakana]
901 *
902 * <NoInputTo/InputMode/ConvedMode/DictMode> Convert character mode
903 * to "hankaku-katakana".
904 * <SelectTo> Ring bell.
905 */
906 Xsj3cEvent
907 _Xsj3cToHKata(buf)
908 Xsj3cBuf buf;
909 {
910 return (_Xsj3cModeChange(buf, MODE_HKATA, ON));
911 }
912
913 /*
914 * _Xsj3cToZKata() [tozkatakana]
915 *
916 * <NoInputTo/InputMode/ConvedMode/DictMode> Convert character mode
917 * to "zenkaku-katakana".
918 * <SelectTo> Ring bell.
919 */
920 Xsj3cEvent
921 _Xsj3cToZKata(buf)
922 Xsj3cBuf buf;
923 {
924 return (_Xsj3cModeChange(buf, MODE_ZKATA, ON));
925 }
926
927
928 /*
929 * _Xsj3cToHira() [tohiragana]
930 *
931 * <NoInputTo/InputMode/ConvedMode/DictMode> Convert character mode
932 * to "hiragana".
933 * <SelectTo> Ring bell.
934 */
935 Xsj3cEvent
936 _Xsj3cToHira(buf)
937 Xsj3cBuf buf;
938 {
939 return (_Xsj3cModeChange(buf, MODE_HIRA, ON));
940 }
941
942 /*
943 * _Xsj3cToZenkaku() [zenkaku]
944 *
945 * <NoInputTo/InputMode/ConvedMode/DictMode> Convert current segment
946 * character mode to zenkaku.
947 * <SelectTo> Ring bell.
948 */
949 Xsj3cEvent
950 _Xsj3cZenkaku(buf)
951 Xsj3cBuf buf;
952 {
953 return (_Xsj3cModeChange(buf, MODE_ZENKAKU, ON));
954 }
955
956 /*
957 * _Xsj3cToHankaku() [zenkaku]
958 *
959 * <NoInputTo/InputMode/ConvedMode/DictMode> Convert current segment
960 * character mode to hankaku.
961 * <SelectTo> Ring bell.
962 */
963 Xsj3cEvent
964 _Xsj3cHankaku(buf)
965 Xsj3cBuf buf;
966 {
967 return (_Xsj3cModeChange(buf, MODE_HANKAKU, ON));
968 }
969
970 /*
971 * _Xsj3cToUpper() [toupper]
972 *
973 * <NoInputTo/InputMode/ConvedMode/DictMode> Convert current segment
974 * character mode to upper case.
975 * <SelectTo> Ring bell.
976 */
977 Xsj3cEvent
978 _Xsj3cToUpper(buf)
979 Xsj3cBuf buf;
980 {
981 return (_Xsj3cModeChange(buf, MODE_UPPER, ON));
982 }
983
984 /*
985 * _Xsj3cToLower() [tolower]
986 *
987 * <NoInputTo/InputMode/ConvedMode/DictMode> Convert current segment
988 * character mode to lower case.
989 * <SelectTo> Ring bell.
990 */
991 Xsj3cEvent
992 _Xsj3cToLower(buf)
993 Xsj3cBuf buf;
994 {
995 return (_Xsj3cModeChange(buf, MODE_LOWER, ON));
996 }
997
998 /*
999 * _Xsj3cModeSJIS() [sjis]
1000 *
1001 * <NoInputMode/InputMode/ConvedMode/DictMode> If now input
1002 * code is not "Shift-JIS", change to Shift-JIS code input mode,
1003 * else change to initialized input mode.
1004 * <SelectMode> Ring bell.
1005 */
1006 Xsj3cEvent
1007 _Xsj3cModeSJIS(buf)
1008 Xsj3cBuf buf;
1009 {
1010 if (buf->convmode & SelectModeMask)
1011 return (KEY_BELL);
1012 if (buf->inputmode != MODE_SJIS) {
1013 buf->dispmode = buf->inputmode = MODE_SJIS;
1014 return (_Xsj3cModeClear(buf));
1015 } else {
1016 buf->dispmode = buf->inputmode = buf->inmoderot[0];
1017 return (_Xsj3cModeClear(buf));
1018 }
1019 }
1020
1021 /*
1022 * _Xsj3cModeEUC() [euc]
1023 *
1024 * <NoInputMode/InputMode/ConvedMode/DictMode> If now input code is not "EUC",
1025 * change to EUC code input mode, else change to initialized input mode.
1026 * <SelectMode> Ring bell.
1027 */
1028 Xsj3cEvent
1029 _Xsj3cModeEUC(buf)
1030 Xsj3cBuf buf;
1031 {
1032 if (buf->convmode & SelectModeMask)
1033 return (KEY_BELL);
1034 if (buf->inputmode != MODE_EUC) {
1035 buf->dispmode = buf->inputmode = MODE_EUC;
1036 return (_Xsj3cModeClear(buf));
1037 } else {
1038 buf->dispmode = buf->inputmode = buf->inmoderot[0];
1039 return (_Xsj3cModeClear(buf));
1040 }
1041 }
1042
1043 /*
1044 * _Xsj3cModeJIS() [jis]
1045 *
1046 * <NoInputMode/InputMode/ConvedMode/DictMode> If now input code is not "JIS",
1047 * change to JIS code input mode, else change to initialized input mode.
1048 * <SelectMode> Ring bell.
1049 */
1050 Xsj3cEvent
1051 _Xsj3cModeJIS(buf)
1052 Xsj3cBuf buf;
1053 {
1054 if (buf->convmode & SelectModeMask)
1055 return (KEY_BELL);
1056 if (buf->inputmode != MODE_JIS) {
1057 buf->dispmode = buf->inputmode = MODE_JIS;
1058 return (_Xsj3cModeClear(buf));
1059 } else {
1060 buf->dispmode = buf->inputmode = buf->inmoderot[0];
1061 return (_Xsj3cModeClear(buf));
1062 }
1063 }
1064
1065 /*
1066 * _Xsj3cModeKuten() [kuten]
1067 *
1068 * <NoInputMode/InputMode/ConvedMode/DictMode> If now input code is not "kuten",
1069 * change to kuten code input mode, else change to initialized input mode.
1070 * <SelectMode> Ring bell.
1071 */
1072 Xsj3cEvent
1073 _Xsj3cModeKuten(buf)
1074 Xsj3cBuf buf;
1075 {
1076 if (buf->convmode & SelectModeMask)
1077 return (KEY_BELL);
1078 if (buf->inputmode != MODE_KUTEN) {
1079 buf->dispmode = buf->inputmode = MODE_KUTEN;
1080 return (_Xsj3cModeClear(buf));
1081 } else {
1082 buf->dispmode = buf->inputmode = buf->inmoderot[0];
1083 return (_Xsj3cModeClear(buf));
1084 }
1085 }
1086
1087 /*
1088 * _Xsj3cCodeRollDown() [code]
1089 *
1090 * <NoInputMode/InputMode/ConvedMode/DictMode> Rotate down input code.
1091 * <SelectMode> Ring bell.
1092 */
1093 Xsj3cEvent
1094 _Xsj3cCodeRollDown(buf)
1095 Xsj3cBuf buf;
1096 {
1097 register int i;
1098
1099 if (buf->convmode & ~SelectModeMask) {
1100 i = 0;
1101 while (i < buf->coderotnum) {
1102 if (buf->inputmode == buf->defcode[i++]) {
1103 buf->dispmode = buf->inputmode = buf->defcode[i];
1104 break;
1105 }
1106 }
1107 if (i >= buf->coderotnum) {
1108 buf->dispmode = buf->inputmode = buf->defcode[0];
1109 }
1110 return (_Xsj3cModeClear(buf));
1111 } else {
1112 return (KEY_BELL);
1113 }
1114 }
1115
1116 /*
1117 * _Xsj3cModeRollDown() [toggle/modedown]
1118 *
1119 * <NoInputMode/InputMode/ConvedMode/DictMode>
1120 * Rotate down character mode to next mode.
1121 * <SelectMode> Ring bell.
1122 *
1123 * ModeConversion on: Convert character mode of current segment to next.
1124 * ModeConversion off: Rotate character mode of input mode.
1125 */
1126 Xsj3cEvent
1127 _Xsj3cModeRollDown(buf)
1128 Xsj3cBuf buf;
1129 {
1130 register int i;
1131 Xsj3csMode premode, postmode;
1132 Xsj3cFlag conv;
1133
1134 if (!buf->segnum) {
1135 if (buf->modeconv[MODE_ROLLDOWN] >> 2) {
1136 #ifdef THROUGH_CONT
1137 return (KEY_NULL);
1138 #else /* THROUGH_CONT */
1139 if (buf->cntrlsame)
1140 return (KEY_NULL);
1141 else
1142 return (KEY_TEXT_CHANGE); /* dummy */
1143 #endif /* THROUGH_CONT */
1144 } else
1145 conv = OFF;
1146 } else if (buf->input[buf->curseg] &&
1147 buf->input[buf->curseg]->status & buf->modeconv[MODE_ROLLDOWN]) {
1148 conv = ON;
1149 } else {
1150 conv = OFF;
1151 }
1152 if (conv) {
1153 return (_Xsj3cNextMode(buf));
1154 } else {
1155 premode = buf->inputmode;
1156 i = 0;
1157 while (i < buf->inmoderotnum) {
1158 if (premode == buf->inmoderot[i++]) {
1159 postmode = buf->inmoderot[i];
1160 break;
1161 }
1162 }
1163 if (i >= buf->inmoderotnum)
1164 postmode = buf->inmoderot[0];
1165 return(_Xsj3cModeChange(buf, postmode, OFF));
1166 }
1167 }
1168
1169 /*
1170 * _Xsj3cModeRollUp() [toggleback/modeup]
1171 *
1172 * <NoInputMode/InputMode/ConvedMode/DictMode>
1173 * Rotate up character mode to previous mode.
1174 * <SelectMode> Ring bell.
1175 *
1176 * ModeConversion on: Convert character mode of current segment to next.
1177 * ModeConversion off: Rotate character mode of input mode.
1178 */
1179 Xsj3cEvent
1180 _Xsj3cModeRollUp(buf)
1181 Xsj3cBuf buf;
1182 {
1183 register int i;
1184 Xsj3csMode premode, postmode;
1185 Xsj3cFlag conv;
1186
1187 if (!buf->segnum) {
1188 if (buf->modeconv[MODE_ROLLDOWN] >> 2) {
1189 #ifdef THROUGH_CONT
1190 return (KEY_NULL);
1191 #else /* THROUGH_CONT */
1192 if (buf->cntrlsame)
1193 return (KEY_NULL);
1194 else
1195 return (KEY_TEXT_CHANGE); /* dummy */
1196 #endif /* THROUGH_CONT */
1197 } else
1198 conv = OFF;
1199 } else if (buf->input[buf->curseg] &&
1200 buf->input[buf->curseg]->status & buf->modeconv[MODE_ROLLDOWN]) {
1201 conv = ON;
1202 } else {
1203 conv = OFF;
1204 }
1205 if (conv) {
1206 return (_Xsj3cPrevMode(buf));
1207 } else {
1208 premode = buf->inputmode;
1209 i = buf->inmoderotnum - 1;
1210 while (i < buf->inmoderotnum) {
1211 if (premode == buf->inmoderot[i--]) {
1212 postmode = buf->inmoderot[i];
1213 break;
1214 }
1215 }
1216 if (i < 0)
1217 postmode = buf->inmoderot[buf->inmoderotnum - 1];
1218 return(_Xsj3cModeChange(buf, postmode, OFF));
1219 }
1220 }
1221
1222 /*
1223 * _Xsj3cNextMode() [nextmode]
1224 *
1225 * <NoInputMode/InputMode/ConvedMode/DictMode>
1226 * Change current segment character mode to next mode.
1227 * <SelectMode> Ring bell.
1228 */
1229 Xsj3cEvent
1230 _Xsj3cNextMode(buf)
1231 Xsj3cBuf buf;
1232 {
1233 register int i;
1234 Xsj3csMode premode, postmode, aftermode = MODE_HIRA;
1235 Xsj3cEvent ret;
1236
1237 if (buf->convmode & NoInputModeMask) {
1238 #ifdef THROUGH_CONT
1239 return (KEY_NULL);
1240 #else /* THROUGH_CONT */
1241 if (buf->cntrlsame)
1242 return (KEY_NULL);
1243 else
1244 return (KEY_TEXT_CHANGE); /* dummy */
1245 #endif /* THROUGH_CONT */
1246 }
1247 premode = buf->input[buf->curseg]->cursegmode;
1248 i = 0;
1249 while (i < buf->outmoderotnum) {
1250 if (premode == buf->outmoderot[i++]) {
1251 postmode = buf->outmoderot[i];
1252 break;
1253 }
1254 }
1255 if (i >= buf->outmoderotnum) {
1256 aftermode = premode;
1257 premode = _Xsj3cCheckMode(buf, buf->input[buf->curseg]);
1258 i = 0;
1259 while (i < buf->outmoderotnum) {
1260 if (premode == buf->outmoderot[i++]) {
1261 postmode = buf->outmoderot[i];
1262 break;
1263 }
1264 }
1265 if (i >= buf->outmoderotnum)
1266 postmode = buf->outmoderot[0];
1267 }
1268 ret = _Xsj3cModeChange(buf, postmode, ON);
1269 if ((aftermode == MODE_UPPER || aftermode == MODE_LOWER)
1270 && (postmode == MODE_ZALPHA || postmode == MODE_HALPHA)) {
1271 ret |= _Xsj3cModeChange(buf, aftermode, ON);
1272 }
1273 return (ret);
1274 }
1275
1276 /*
1277 * _Xsj3cPrevMode() [prevmode]
1278 *
1279 * <NoInputMode/InputMode/ConvedMode/DictMode>
1280 * Change current segment character mode to previous mode.
1281 * <SelectMode> Ring bell.
1282 */
1283 Xsj3cEvent
1284 _Xsj3cPrevMode(buf)
1285 Xsj3cBuf buf;
1286 {
1287 register int i;
1288 Xsj3csMode premode, postmode, aftermode = MODE_HIRA;
1289 Xsj3cEvent ret;
1290
1291 if (buf->convmode & NoInputModeMask) {
1292 #ifdef THROUGH_CONT
1293 return (KEY_NULL);
1294 #else /* THROUGH_CONT */
1295 if (buf->cntrlsame)
1296 return (KEY_NULL);
1297 else
1298 return (KEY_TEXT_CHANGE); /* dummy */
1299 #endif /* THROUGH_CONT */
1300 }
1301 premode = buf->input[buf->curseg]->cursegmode;
1302 i = buf->outmoderotnum - 1;
1303 while (i >= 0) {
1304 if (premode == buf->outmoderot[i--]) {
1305 postmode = buf->outmoderot[i];
1306 break;
1307 }
1308 }
1309 if (i < 0) {
1310 aftermode = premode;
1311 premode = _Xsj3cCheckMode(buf, buf->input[buf->curseg]);
1312 i = buf->outmoderotnum - 1;
1313 while (i >= 0) {
1314 if (premode == buf->outmoderot[i--]) {
1315 postmode = buf->outmoderot[i];
1316 break;
1317 }
1318 }
1319 if (i < 0)
1320 postmode = buf->outmoderot[buf->outmoderotnum - 1];
1321 }
1322 ret = _Xsj3cModeChange(buf, postmode, ON);
1323 if ((aftermode == MODE_UPPER || aftermode == MODE_LOWER)
1324 && (postmode == MODE_ZALPHA || postmode == MODE_HALPHA)) {
1325 ret |= _Xsj3cModeChange(buf, aftermode, ON);
1326 }
1327 return(ret);
1328 }
1329
1330 /*
1331 * _Xsj3cModeToggle() [muhenkan]
1332 *
1333 * Emulating of sj2/sj3/sjx's muhenkan stroke.
1334 * <NoInputMode/InputMode> Change input character mode to "MuhenkanMode".
1335 * <ConvedMode/DictMode> Converts current segment character input mode first to
1336 * hiragana, second to zenkaku-katakana , third to "MuhenkanInEdit".
1337 * <SelectMode> Does nothing.
1338 *
1339 * MuhenkanMode mode: Mode of toggling in InputMode after input chacter mode
1340 * is changed to hiragana.
1341 * MuhenkanInEdit mode: Mode of toggling in ConvedMode after segment is
1342 * converted to hiragana and zenkaku-katakana.
1343 * MuhenkanToggle off: Stop toggling in InputMode.
1344 */
1345 Xsj3cEvent
1346 _Xsj3cModeToggle(buf)
1347 Xsj3cBuf buf;
1348 {
1349 register int i;
1350 register wchar (*conv)();
1351 unsigned char *mbs;
1352 Xsj3cEvent ret;
1353 Xsj3cSeg seg = buf->input[buf->curseg];
1354
1355 if (buf->convmode & ~(SelectModeMask|DictModeMask)) {
1356 if (buf->convmode & ConvedModeMask ||((buf->convmode & InputModeMask)
1357 && (seg->edit & SEG_NOEDIT))) {
1358 if ((mbs = (unsigned char *)malloc(seg->size * 2 * sizeof(wchar)))
1359 == NULL)
1360 Xsj3cError("Cannot allocate for mode conversion buffer");
1361
1362 switch (seg->cursegmode) {
1363 case MODE_HIRA:
1364 if (seg->num != seg->dnum) {
1365 ret = _Xsj3cModeChange(buf, MODE_HIRA, ON);
1366 } else {
1367 if (conv =
1368 CodeConvFunc[serverIF[buf->server].lang][out_lang]) {
1369 register wchar w1, w2;
1370 for (i = 0;i < seg->dnum; i++) {
1371 w1 = seg->yomi[i];
1372 if (iskan1(w1 >> 8, serverIF[buf->server].lang) &&
1373 iskan2(w1 & 0xff, serverIF[buf->server].lang))
1374 w2 = conv(w1);
1375 else
1376 w2 = w1;
1377 if (w2 != seg->disp[i])
1378 break;
1379 }
1380 } else {
1381 for (i = 0;i < seg->dnum;i++) {
1382 if (seg->disp[i] != seg->yomi[i])
1383 break;
1384 }
1385 }
1386 if (i < seg->dnum)
1387 ret = _Xsj3cModeChange(buf, MODE_HIRA, ON);
1388 else {
1389 ret = _Xsj3cModeChange(buf, MODE_ZKATA, ON);
1390 }
1391 }
1392 break;
1393 case MODE_ZKATA:
1394 ret = _Xsj3cModeChange(buf, buf->togglemode, ON);
1395 break;
1396 default:
1397 ret = _Xsj3cModeChange(buf, MODE_HIRA, ON);
1398 break;
1399 }
1400 free(mbs);
1401 return(ret);
1402 } else {
1403 if (buf->inputmode == MODE_HIRA)
1404 return (_Xsj3cModeChange(buf, buf->muhenmode, OFF));
1405 else if (buf->dotoggle)
1406 return (_Xsj3cModeChange(buf, MODE_HIRA, OFF));
1407 else {
1408 #ifdef THROUGH_CONT
1409 return (KEY_NULL);
1410 #else /* THROUGH_CONT */
1411 if (buf->cntrlsame)
1412 return (KEY_NULL);
1413 else
1414 return (KEY_TEXT_CHANGE); /* dummy */
1415 #endif /* THROUGH_CONT */
1416 }
1417 }
1418 } else {
1419 return (KEY_BELL);
1420 }
1421 }
1422
1423 /*
1424 * _Xsj3cForward() [right/forward]
1425 *
1426 * <InputMode/ConvedMode> Move to next segment or next character position.
1427 * <DictMode> Move reversed segment to next segment if not expanded.
1428 * <SelectMode> Move to right candidate(symbol/hinsi)
1429 * in the candidate(symbol/hinsi) panel.
1430 * <NoInputMode> Does nothing.
1431 *
1432 * MovebySegment on: Move by segment.
1433 * MovebySegment off: Move by character.
1434 * BeginConversionLast none: Allow to move out of segments.
1435 * MoveSegmentLoop on: Loop back to the first segment.
1436 */
1437 Xsj3cEvent
1438 _Xsj3cForward(buf)
1439 Xsj3cBuf buf;
1440 {
1441 Xsj3cEvent ret = KEY_TEXT_CHANGE;
1442
1443 switch (buf->convmode) {
1444 case ConvedModeMask:
1445 buf->n_select = 0;
1446 if (buf->candidate)
1447 Xsj3cEndCandidate(buf, ON);
1448 case InputModeMask:
1449 buf->input[buf->curseg]->n_roma = 0;
1450 buf->input[buf->curseg]->n_kana = -1;
1451 *buf->input[buf->curseg]->oldstr = '\0';
1452 *buf->input[buf->curseg]->str = '\0';
1453 buf->input[buf->curseg]->sp = buf->input[buf->curseg]->str;
1454 if (buf->input[buf->curseg]->status & buf->movebyseg
1455 && (buf->input[buf->curseg]->edit & SEG_NOEDIT)) {
1456 if (buf->beginlastseg == NONE) {
1457 if (buf->curseg < buf->segnum)
1458 buf->curseg++;
1459 else if (buf->moveloop)
1460 buf->curseg = 0;
1461 } else {
1462 if (buf->curseg < buf->segnum - 1)
1463 buf->curseg++;
1464 else if (buf->moveloop)
1465 buf->curseg = 0;
1466 }
1467 } else {
1468 if (buf->curseg < buf->segnum
1469 && buf->input[buf->curseg]->status == SEG_CONVED)
1470 ret |= _Xsj3cUnConvSeg(buf, ONE, OFF);
1471 _Xsj3cStoreYomi(buf, buf->input[buf->curseg], 0);
1472 if (buf->input[buf->curseg]->cur < buf->input[buf->curseg]->num) {
1473 buf->input[buf->curseg]->cur++;
1474 } else {
1475 if (buf->beginlastseg == NONE) {
1476 if (buf->curseg < buf->segnum) {
1477 buf->curseg++;
1478 if (buf->curseg < buf->segnum)
1479 buf->input[buf->curseg]->cur = 0;
1480 } else if (buf->moveloop) {
1481 buf->curseg = 0;
1482 buf->input[buf->curseg]->cur = 0;
1483 }
1484 } else {
1485 if (buf->curseg < buf->segnum - 1) {
1486 buf->curseg++;
1487 buf->input[buf->curseg]->cur = 0;
1488 } else if (buf->moveloop) {
1489 buf->curseg = 0;
1490 buf->input[buf->curseg]->cur = 0;
1491 }
1492 }
1493 }
1494 }
1495 return ret;
1496 case DictModeMask:
1497 if (buf->dict->n_dict) {
1498 return (KEY_BELL);
1499 } else {
1500 if (buf->curseg < buf->segnum - 1 )
1501 buf->curseg++;
1502 else
1503 buf->curseg = buf->segnum - 1;
1504 return (ret);
1505 }
1506 case SelectModeMask:
1507 return (KEY_SELECT_RIGHT);
1508 case NoInputModeMask:
1509 default:
1510 #ifdef THROUGH_CONT
1511 return (KEY_NULL);
1512 #else /* THROUGH_CONT */
1513 if (buf->cntrlsame)
1514 return (KEY_NULL);
1515 else
1516 return (KEY_TEXT_CHANGE); /* dummy */
1517 #endif /* THROUGH_CONT */
1518 }
1519 }
1520
1521 /*
1522 * _Xsj3cBackward() [left/backward]
1523 *
1524 * <InputMode/ConvedMode> Move to previous segment or
1525 * previous character position.
1526 * <DictMode> Move reversed segment to previous segment if not expanded.
1527 * <SelectMode> Move to left candidate(symbol/hinsi)
1528 * in the candidate(symbol/hinsi) panel.
1529 * <NoInputMode> Does nothing.
1530 *
1531 * MovebySegment on: Move by segment.
1532 * MovebySegment off: Move by character.
1533 * MoveSegmentLoop on: Loop back to the last segment.
1534 */
1535 Xsj3cEvent
1536 _Xsj3cBackward(buf)
1537 Xsj3cBuf buf;
1538 {
1539 Xsj3cEvent ret = KEY_TEXT_CHANGE;
1540
1541 switch (buf->convmode) {
1542 case ConvedModeMask:
1543 buf->n_select = 0;
1544 if (buf->candidate)
1545 Xsj3cEndCandidate(buf, ON);
1546 case InputModeMask:
1547 if (buf->curseg < buf->segnum) {
1548 buf->input[buf->curseg]->n_roma = 0;
1549 buf->input[buf->curseg]->n_kana = -1;
1550 *buf->input[buf->curseg]->oldstr = '\0';
1551 *buf->input[buf->curseg]->str = '\0';
1552 buf->input[buf->curseg]->sp = buf->input[buf->curseg]->str;
1553 if (buf->input[buf->curseg]->status & buf->movebyseg
1554 && (buf->input[buf->curseg]->edit & SEG_NOEDIT)) {
1555 if (buf->curseg > 0)
1556 buf->curseg--;
1557 else if (buf->moveloop) {
1558 if (buf->beginlastseg == NONE)
1559 buf->curseg = buf->segnum;
1560 else
1561 buf->curseg = buf->segnum - 1;
1562 }
1563 } else {
1564 if (buf->curseg < buf->segnum
1565 && buf->input[buf->curseg]->status == SEG_CONVED)
1566 ret |= _Xsj3cUnConvSeg(buf, ONE, ON);
1567 _Xsj3cStoreYomi(buf, buf->input[buf->curseg], 0);
1568 if (buf->input[buf->curseg]->cur > 0) {
1569 buf->input[buf->curseg]->cur--;
1570 } else {
1571 if (buf->curseg > 0) {
1572 buf->curseg--;
1573 buf->input[buf->curseg]->cur
1574 = buf->input[buf->curseg]->num;
1575 } else if (buf->moveloop) {
1576 if (buf->beginlastseg == NONE)
1577 buf->curseg = buf->segnum;
1578 else {
1579 buf->curseg = buf->segnum - 1;
1580 buf->input[buf->curseg]->cur
1581 = buf->input[buf->curseg]->num;
1582 }
1583 }
1584 }
1585 }
1586 return (ret);
1587 } else if (buf->curseg > 0) {
1588 buf->curseg--;
1589 return (ret);
1590 } else {
1591 return (KEY_NULL);
1592 }
1593 case DictModeMask:
1594 if (buf->dict->n_dict) {
1595 return (KEY_BELL);
1596 } else {
1597 if (buf->curseg > 0)
1598 buf->curseg--;
1599 else
1600 buf->curseg = 0;
1601 return (ret);
1602 }
1603 case SelectModeMask:
1604 return (KEY_SELECT_LEFT);
1605 case NoInputModeMask:
1606 default:
1607 #ifdef THROUGH_CONT
1608 return (KEY_NULL);
1609 #else /* THROUGH_CONT */
1610 if (buf->cntrlsame)
1611 return (KEY_NULL);
1612 else
1613 return (KEY_TEXT_CHANGE); /* dummy */
1614 #endif /* THROUGH_CONT */
1615 }
1616 }
1617
1618 /*
1619 * _Xsj3cTop() [top]
1620 *
1621 * <InputMode/ConvedMode> Move to the first segment or top of current segment.
1622 * <DictMode> Move reversed segment to the first segment if not expanded.
1623 * <SelectMode> Move to first candidate(symbol/hinsi)
1624 * in popuped candidate(symbol/hinsi) panel.
1625 * <NoInputMode> Does nothing.
1626 *
1627 * JumpbySegment on: Move by segment.
1628 * JumpbySegment off: Move by character.
1629 */
1630 Xsj3cEvent
1631 _Xsj3cTop(buf)
1632 Xsj3cBuf buf;
1633 {
1634 switch (buf->convmode) {
1635 case ConvedModeMask:
1636 buf->n_select = 0;
1637 if (buf->candidate)
1638 Xsj3cEndCandidate(buf, ON);
1639 case InputModeMask:
1640 if (buf->curseg < buf->segnum) {
1641 buf->input[buf->curseg]->n_roma = 0;
1642 buf->input[buf->curseg]->n_kana = -1;
1643 *buf->input[buf->curseg]->oldstr = '\0';
1644 *buf->input[buf->curseg]->str = '\0';
1645 buf->input[buf->curseg]->sp = buf->input[buf->curseg]->str;
1646 if (buf->input[buf->curseg]->status & buf->jumpbyseg
1647 && (buf->input[buf->curseg]->edit & SEG_NOEDIT)) {
1648 buf->curseg = 0;
1649 } else if (buf->curseg < buf->segnum) {
1650 buf->input[buf->curseg]->cur = 0;
1651 }
1652 return KEY_TEXT_CHANGE;
1653 } else if (buf->segnum > 0) {
1654 buf->curseg = 0;
1655 return KEY_TEXT_CHANGE;
1656 } else {
1657 return KEY_NULL;
1658 }
1659 case DictModeMask:
1660 if (buf->dict->n_dict) {
1661 return (KEY_BELL);
1662 } else {
1663 buf->curseg = 0;
1664 return (KEY_TEXT_CHANGE);
1665 }
1666 case SelectModeMask:
1667 return (KEY_SELECT_LEFTMOST);
1668 case NoInputModeMask:
1669 default:
1670 #ifdef THROUGH_CONT
1671 return (KEY_NULL);
1672 #else /* THROUGH_CONT */
1673 if (buf->cntrlsame)
1674 return (KEY_NULL);
1675 else
1676 return (KEY_TEXT_CHANGE); /* dummy */
1677 #endif /* THROUGH_CONT */
1678 }
1679 }
1680
1681 /*
1682 * _Xsj3cEnd() [end]
1683 *
1684 * <InputMode/ConvedMode> Move to the last segment or top of current segment.
1685 * <DictMode> Move reversed segment to the last segment if not expanded.
1686 * <SelectMode> Move to last candidate(symbol/hinsi)
1687 * in popuped candidate(symbol/hinsi) panel.
1688 * <NoInputMode> Does nothing.
1689 *
1690 * JumpbySegment on: Move by segment.
1691 * JumpbySegment off: Move by character.
1692 * BeginConversionLast none: Allow to move out of segments.
1693 */
1694 Xsj3cEvent
1695 _Xsj3cEnd(buf)
1696 Xsj3cBuf buf;
1697 {
1698 switch (buf->convmode) {
1699 case ConvedModeMask:
1700 buf->n_select = 0;
1701 if (buf->candidate)
1702 Xsj3cEndCandidate(buf, ON);
1703 case InputModeMask:
1704 if (buf->curseg >= buf->segnum)
1705 return KEY_NULL;
1706 buf->input[buf->curseg]->n_roma = 0;
1707 buf->input[buf->curseg]->n_kana = -1;
1708 *buf->input[buf->curseg]->oldstr = '\0';
1709 *buf->input[buf->curseg]->str = '\0';
1710 buf->input[buf->curseg]->sp = buf->input[buf->curseg]->str;
1711 if (buf->input[buf->curseg]->status & buf->jumpbyseg
1712 && (buf->input[buf->curseg]->edit & SEG_NOEDIT)) {
1713 if (buf->beginlastseg == NONE)
1714 buf->curseg = buf->segnum;
1715 else
1716 buf->curseg = buf->segnum - 1;
1717 } else {
1718 buf->input[buf->curseg]->cur = buf->input[buf->curseg]->num;
1719 }
1720 return KEY_TEXT_CHANGE;
1721 case DictModeMask:
1722 if (buf->dict->n_dict) {
1723 return (KEY_BELL);
1724 } else {
1725 buf->curseg = buf->segnum - 1;
1726 return (KEY_TEXT_CHANGE);
1727 }
1728 case SelectModeMask:
1729 return (KEY_SELECT_RIGHTMOST);
1730 case NoInputModeMask:
1731 default:
1732 #ifdef THROUGH_CONT
1733 return (KEY_NULL);
1734 #else /* THROUGH_CONT */
1735 if (buf->cntrlsame)
1736 return (KEY_NULL);
1737 else
1738 return (KEY_TEXT_CHANGE); /* dummy */
1739 #endif /* THROUGH_CONT */
1740 }
1741 }
1742
1743 /*
1744 * _Xsj3cUp() [up]
1745 *
1746 * <SelectMode> Move to above candidate(symbol/hinsi)
1747 * in the candidate(symbol/hinsi) panel.
1748 * <NoInputMode/InputMode/ConvedMode/DictMode> Rings bell.
1749 */
1750 Xsj3cEvent
1751 _Xsj3cUp(buf)
1752 Xsj3cBuf buf;
1753 {
1754 if (buf->convmode & SelectModeMask)
1755 return (KEY_SELECT_UP);
1756 else
1757 #ifdef THROUGH_CONT
1758 return (KEY_BELL);
1759 #else /* THROUGH_CONT */
1760 if (buf->cntrlsame)
1761 return (KEY_BELL);
1762 else
1763 return (KEY_TEXT_CHANGE|KEY_BELL); /* dummy */
1764 #endif /* THROUGH_CONT */
1765 }
1766
1767 /*
1768 * _Xsj3cDown() [down]
1769 *
1770 * <SelectMode> Move to below candidate(symbol/hinsi)
1771 * in the candidate(symbol/hinsi) panel.
1772 * <NoInputMode/InputMode/ConvedMode/DictMode> Rings bell.
1773 */
1774 Xsj3cEvent
1775 _Xsj3cDown(buf)
1776 Xsj3cBuf buf;
1777 {
1778 if (buf->convmode & SelectModeMask)
1779 return (KEY_SELECT_DOWN);
1780 else
1781 #ifdef THROUGH_CONT
1782 return (KEY_BELL);
1783 #else /* THROUGH_CONT */
1784 if (buf->cntrlsame)
1785 return (KEY_BELL);
1786 else
1787 return (KEY_TEXT_CHANGE|KEY_BELL); /* dummy */
1788 #endif /* THROUGH_CONT */
1789 }
1790
1791 /*
1792 * _Xsj3cFirst() [first]
1793 *
1794 * <ConvedMode> Set top candidate the current segment.
1795 * <SelectMode> Move to first candidate(symbol/hinsi)
1796 * in all candidate(symbol/hinsi) pages.
1797 * <NoInputMode/InputMode/DictMode> Rings bell.
1798 */
1799 Xsj3cEvent
1800 _Xsj3cFirst(buf)
1801 Xsj3cBuf buf;
1802 {
1803 int changed, flush;
1804
1805 if (buf->convmode & ConvedModeMask) {
1806 if (!buf->candidate)
1807 if ((buf->candidate = _Xsj3cCandidateInit(buf)) == NULL)
1808 return (KEY_NULL);
1809 Xsj3cSetCandidate(buf, 0, &changed, &flush);
1810 return KEY_TEXT_CHANGE;
1811 } else if (buf->convmode & SelectModeMask) {
1812 return (KEY_SELECT_FIRST);
1813 } else {
1814 #ifdef THROUGH_CONT
1815 return (KEY_BELL);
1816 #else /* THROUGH_CONT */
1817 if (buf->cntrlsame)
1818 return (KEY_BELL);
1819 else
1820 return (KEY_TEXT_CHANGE|KEY_BELL); /* dummy */
1821 #endif /* THROUGH_CONT */
1822 }
1823 }
1824
1825 /*
1826 * _Xsj3cLast() [last]
1827 *
1828 * <ConvedMode> Set bottom candidate the current segment.
1829 * <SelectMode> Move to last candidate(symbol/hinsi)
1830 * in all candidate(symbol/hinsi) pages.
1831 * <NoInputMode/InputMode/DictMode> Rings bell.
1832 */
1833 Xsj3cEvent
1834 _Xsj3cLast(buf)
1835 Xsj3cBuf buf;
1836 {
1837 int changed, flush;
1838
1839 if (buf->convmode & ConvedModeMask) {
1840 if (!buf->candidate)
1841 if ((buf->candidate = _Xsj3cCandidateInit(buf)) == NULL)
1842 return (KEY_NULL);
1843 Xsj3cSetCandidate(buf, buf->candnum - 1, &changed, &flush);
1844 return (KEY_TEXT_CHANGE);
1845 } else if (buf->convmode & SelectModeMask) {
1846 return (KEY_SELECT_LAST);
1847 } else {
1848 #ifdef THROUGH_CONT
1849 return (KEY_BELL);
1850 #else /* THROUGH_CONT */
1851 if (buf->cntrlsame)
1852 return (KEY_BELL);
1853 else
1854 return (KEY_TEXT_CHANGE|KEY_BELL); /* dummy */
1855 #endif /* THROUGH_CONT */
1856 }
1857 }
1858
1859 /*
1860 * _Xsj3cNextPage() [nextp]
1861 * <SelectMode> Change contents of the candidate(symbol/hinsi) panel
1862 * to the next page.
1863 * <NoInputMode/InputMode/ConvedMode/DictMode> Rings bell.
1864 */
1865 Xsj3cEvent
1866 _Xsj3cNextPage(buf)
1867 Xsj3cBuf buf;
1868 {
1869 if (buf->convmode & SelectModeMask)
1870 return (KEY_SELECT_NEXTP);
1871 else
1872 #ifdef THROUGH_CONT
1873 return (KEY_BELL);
1874 #else /* THROUGH_CONT */
1875 if (buf->cntrlsame)
1876 return (KEY_BELL);
1877 else
1878 return (KEY_TEXT_CHANGE|KEY_BELL); /* dummy */
1879 #endif /* THROUGH_CONT */
1880 }
1881
1882 /*
1883 * _Xsj3cPrevPage() [prevp]
1884 * <SelectMode> Change contents of the candidate(symbol/hinsi) panel
1885 * to the previous page.
1886 * <NoInputMode/InputMode/ConvedMode/DictMode> Rings bell.
1887 */
1888 Xsj3cEvent
1889 _Xsj3cPrevPage(buf)
1890 Xsj3cBuf buf;
1891 {
1892 if (buf->convmode & SelectModeMask)
1893 return (KEY_SELECT_PREVP);
1894 else
1895 #ifdef THROUGH_CONT
1896 return (KEY_BELL);
1897 #else /* THROUGH_CONT */
1898 if (buf->cntrlsame)
1899 return (KEY_BELL);
1900 else
1901 return (KEY_TEXT_CHANGE|KEY_BELL); /* dummy */
1902 #endif /* THROUGH_CONT */
1903 }
1904
1905 /*
1906 * _Xsj3cNext() [next]
1907 *
1908 * <ConvedMode> Set next candidate the current segment.
1909 * <SelectMode> Move to right(next) candidate(symbol/hinsi)
1910 * in the candidate(symbol/hinsi) panel.
1911 * <NoInputMode/InputMode/DictMode> Rings bell.
1912 */
1913 Xsj3cEvent
1914 _Xsj3cNext(buf)
1915 Xsj3cBuf buf;
1916 {
1917 int changed, flush;
1918
1919 if (buf->convmode & ConvedModeMask) {
1920 if (!buf->candidate)
1921 if ((buf->candidate = _Xsj3cCandidateInit(buf)) == NULL)
1922 return (KEY_NULL);
1923 if (buf->curcand == buf->candnum - 1)
1924 Xsj3cSetCandidate(buf, 0, &changed, &flush);
1925 else
1926 Xsj3cSetCandidate(buf, buf->curcand + 1, &changed, &flush);
1927 return KEY_TEXT_CHANGE;
1928 } else if (buf->convmode & SelectModeMask) {
1929 return (KEY_SELECT_RIGHT);
1930 } else {
1931 #ifdef THROUGH_CONT
1932 return (KEY_BELL);
1933 #else /* THROUGH_CONT */
1934 if (buf->cntrlsame)
1935 return (KEY_BELL);
1936 else
1937 return (KEY_TEXT_CHANGE|KEY_BELL); /* dummy */
1938 #endif /* THROUGH_CONT */
1939 }
1940 }
1941
1942 /*
1943 * _Xsj3cPrev() [prev]
1944 *
1945 * <ConvedMode> Set previous candidate the current segment.
1946 * <SelectMode> Move to left(previous) candidate(symbol/hinsi)
1947 * in the candidate(symbol/hinsi) panel.
1948 * <NoInputMode/InputMode/DictMode> Rings bell.
1949 */
1950 Xsj3cEvent
1951 _Xsj3cPrev(buf)
1952 Xsj3cBuf buf;
1953 {
1954 int changed, flush;
1955
1956 if (buf->convmode & ConvedModeMask) {
1957 if (!buf->candidate)
1958 if ((buf->candidate = _Xsj3cCandidateInit(buf)) == NULL)
1959 return (KEY_NULL);
1960 if (!buf->curcand)
1961 Xsj3cSetCandidate(buf, buf->candnum - 1, &changed, &flush);
1962 else
1963 Xsj3cSetCandidate(buf, buf->curcand - 1, &changed, &flush);
1964 return KEY_TEXT_CHANGE;
1965 } else if (buf->convmode & SelectModeMask) {
1966 return (KEY_SELECT_LEFT);
1967 } else {
1968 #ifdef THROUGH_CONT
1969 return (KEY_BELL);
1970 #else /* THROUGH_CONT */
1971 if (buf->cntrlsame)
1972 return (KEY_BELL);
1973 else
1974 return (KEY_TEXT_CHANGE|KEY_BELL); /* dummy */
1975 #endif /* THROUGH_CONT */
1976 }
1977 }
1978
1979 /*
1980 * _Xsj3cSelect() [select]
1981 *
1982 * <SelectMode> Select reversed candidate(symbol/hinsi)
1983 * in the candidate(symbol/hinsi) panel and pop down the panel.
1984 * <NoInputMode/InputMode/ConvedMode/DictMode> Rings bell.
1985 * Select now selected candidate(symbol) in the candidate(symbol) panel.
1986 */
1987 Xsj3cEvent
1988 _Xsj3cSelect(buf)
1989 Xsj3cBuf buf;
1990 {
1991 if (buf->convmode & SelectModeMask) {
1992 if (buf->selectstatus == SELECT_HINSI) {
1993 buf->dict->status = DICT_CONFIRM;
1994 if (buf->dispmodechange) {
1995 buf->dispmode =
1996 (buf->dict->mode == REG_STATE ? MODE_TOROKU : MODE_SYOUKYO);
1997 return (KEY_SELECT_END|KEY_DICT_CHANGE|KEY_MODE_CHANGE);
1998 } else
1999 return (KEY_SELECT_END|KEY_DICT_CHANGE);
2000 } else {
2001 if (buf->dispmodechange) {
2002 buf->dispmode = (buf->convedsegnum == buf->segnum ? MODE_KANJI :
2003 (buf->convedsegnum ? MODE_EDIT : buf->inputmode));
2004 return (KEY_SELECT_END|KEY_MODE_CHANGE);
2005 } else
2006 return (KEY_SELECT_END);
2007 }
2008 } else if (buf->convmode & DictModeMask) {
2009 if (buf->dict->status == DICT_CONFIRM) {
2010 buf->dict->status = DICT_END;
2011 _Xsj3cFlushDictMsg(buf);
2012 if (buf->dict->mode == REG_STATE)
2013 return(KEY_DICT_REGISTER);
2014 else
2015 return(KEY_DICT_CLEAR);
2016 } else {
2017 return (KEY_BELL);
2018 }
2019 } else {
2020 #ifdef THROUGH_CONT
2021 return (KEY_BELL);
2022 #else /* THROUGH_CONT */
2023 if (buf->cntrlsame)
2024 return (KEY_BELL);
2025 else
2026 return (KEY_TEXT_CHANGE|KEY_BELL); /* dummy */
2027 #endif /* THROUGH_CONT */
2028 }
2029 }
2030
2031 /*
2032 * _Xsj3cCancel() [cancel]
2033 *
2034 * <InputMode/ConvedMode> Clear all segments.
2035 * <SelectMode> Pop down candidate(symbol/hinsi) panel.
2036 * <DictMode> (DICT_INPUT) Pop down Auxpanel.
2037 * (DICT_CONFIRM/DICT_END) Return back to DICT_INPUT status.
2038 * <NoInputMode> Does nothing.
2039 *
2040 * DisplayModeChange on: Change the display mode string.
2041 */
2042 Xsj3cEvent
2043 _Xsj3cCancel(buf)
2044 Xsj3cBuf buf;
2045 {
2046 int i;
2047
2048 switch (buf->convmode) {
2049 case ConvedModeMask:
2050 buf->n_select = 0;
2051 if (buf->candidate)
2052 Xsj3cEndCandidate(buf, OFF);
2053 case InputModeMask:
2054 if (buf->gakusyuu)
2055 _Xsj3cClearDcid(buf);
2056 buf->convedsegnum = 0;
2057 for (i = 1; i < buf->segnum + 1; i++) {
2058 Xsj3cFreeSegment(buf->input[i]);
2059 buf->input[i] = NULL;
2060 }
2061 if (buf->input[0])
2062 Xsj3cClearSegment(buf, buf->input[0]);
2063 buf->convedsegnum = 0;
2064 buf->segnum = 0;
2065 buf->curseg = 0;
2066 if (buf->dispmodechange) {
2067 buf->dispmode = buf->inputmode;
2068 return (KEY_TEXT_CHANGE|KEY_MODE_CHANGE);
2069 } else
2070 return (KEY_TEXT_CHANGE);
2071 case SelectModeMask:
2072 if (buf->selectstatus == SELECT_HINSI) {
2073 buf->dict->status = DICT_INPUT;
2074 _Xsj3cFlushDictMsg(buf);
2075 if (buf->dispmodechange) {
2076 buf->dispmode = (buf->dict->mode == REG_STATE ?
2077 MODE_TOROKU : MODE_SYOUKYO);
2078 return (KEY_SELECT_ABORT|KEY_MODE_CHANGE);
2079 } else
2080 return (KEY_SELECT_ABORT);
2081 } else {
2082 if (buf->dispmodechange) {
2083 buf->dispmode = (buf->convedsegnum == buf->segnum ? MODE_KANJI :
2084 (buf->convedsegnum ? MODE_EDIT : buf->inputmode));
2085 return (KEY_SELECT_ABORT|KEY_MODE_CHANGE);
2086 } else
2087 return (KEY_SELECT_ABORT);
2088 }
2089 case DictModeMask:
2090 if (buf->dict->status == DICT_CONFIRM
2091 || buf->dict->status == DICT_END) {
2092 buf->dict->status = DICT_INPUT;
2093 _Xsj3cFlushDictMsg(buf);
2094 return(KEY_DICT_CHANGE);
2095 } else {
2096 if (buf->dispmodechange) {
2097 buf->dispmode = (buf->convedsegnum == buf->segnum ? MODE_KANJI:
2098 (buf->convedsegnum ? MODE_EDIT : buf->inputmode));
2099 return (KEY_DICT_END|KEY_TEXT_CHANGE|KEY_MODE_CHANGE);
2100 } else {
2101 return (KEY_DICT_END|KEY_TEXT_CHANGE);
2102 }
2103 }
2104 case NoInputModeMask:
2105 #ifdef THROUGH_CONT
2106 return (KEY_NULL);
2107 #else /* THROUGH_CONT */
2108 if (buf->cntrlsame)
2109 return (KEY_NULL);
2110 else
2111 return (KEY_TEXT_CHANGE); /* dummy */
2112 #endif /* THROUGH_CONT */
2113 default:
2114 return (KEY_TEXT_CHANGE);
2115 }
2116 }
2117
2118 /*
2119 * _Xsj3cExpand() [kakucyou/expand]
2120 *
2121 * <InputMode/ConvedMode> Expand the current segment by getting in
2122 * the first character of the next segment.
2123 * <DictMode> Increase the reversed segments by adding the next segment.
2124 * <NoInputMode/SelectMode> Rings bell.
2125 *
2126 * ExpandModeConversion on: Change the expanded segment's character mode.
2127 * ExpandKanjiConversion on: Do kana-kanji conversion for current
2128 * and next segment.
2129 */
2130 Xsj3cEvent
2131 _Xsj3cExpand(buf)
2132 Xsj3cBuf buf;
2133 {
2134 int nextseg = buf->curseg + 1, value = 0;
2135 Xsj3cFlag conv = 0, modematch = 0;
2136 register int i;
2137 unsigned char tmp[YBUFSIZ];
2138 unsigned char *kanabuf;
2139 unsigned char knjbuf[KANJIBUFSIZ];
2140 SJ3_BUNSETU bun[BUNBUFSIZ];
2141
2142 if (buf->convmode & DictModeMask) {
2143 return (_Xsj3cExpandNoConv(buf));
2144 } else if ((buf->convmode & SelectModeMask) || nextseg >= buf->segnum
2145 || !buf->input[nextseg]->num) {
2146 /* $B8=J8@a$,:G8e$NJ8@a$N;~$O3HD%$G$-$J$$!#(B */
2147 #ifdef THROUGH_CONT
2148 return (KEY_BELL);
2149 #else /* THROUGH_CONT */
2150 if (buf->cntrlsame)
2151 return (KEY_BELL);
2152 else
2153 return (KEY_TEXT_CHANGE|KEY_BELL); /* dummy */
2154 #endif /* THROUGH_CONT */
2155 } else if (buf->convmode & ConvedModeMask) {
2156 buf->n_select = 0;
2157 if (buf->candidate)
2158 Xsj3cEndCandidate(buf, OFF);
2159 } else if (buf->convmode & ~InputModeMask) {
2160 #ifdef THROUGH_CONT
2161 return (KEY_BELL);
2162 #else /* THROUGH_CONT */
2163 if (buf->cntrlsame)
2164 return (KEY_BELL);
2165 else
2166 return (KEY_TEXT_CHANGE|KEY_BELL); /* dummy */
2167 #endif /* THROUGH_CONT */
2168 }
2169
2170 /* temporary $B$N%P%C%U%!$r:n@.$9$k(B */
2171 if ((kanabuf = (unsigned char *)
2172 malloc(buf->input[buf->curseg]->size * sizeof(wchar))) == NULL)
2173 Xsj3cError("Cannot allocate for temporary buffer");
2174
2175 /* $B<!J8@a$NF,$N#1J8;z$r8:$8!"0l;~%P%C%U%!$K%3%T!<$9$k(B */
2176 buf->input[nextseg]->cur = 1;
2177 _Xsj3cExtractChar(buf, buf->input[nextseg], tmp, 1);
2178 if (buf->input[nextseg]->status & SEG_CONVED)
2179 buf->convedsegnum--;
2180
2181 if (buf->input[nextseg]->cursegmode == buf->input[buf->curseg]->cursegmode)
2182 modematch++;
2183 if (!buf->input[nextseg]->num) {
2184
2185 /* $B<!J8@a$,#1J8;z$7$+$J$+$C$?>l9g!"J8@a?t$r#1$D8:$8(B */
2186 /* $B99$K!"<!J8@a$NNN0h$r2rJ|$9$k!#(B */
2187 Xsj3cFreeSegment(buf->input[buf->segnum]);
2188 buf->input[buf->segnum] = NULL;
2189 buf->segnum--;
2190 Xsj3cFreeSegment(buf->input[nextseg]);
2191 buf->input[nextseg] = NULL;
2192 if (nextseg < buf->segnum) {
2193 for ( i = nextseg; i < buf->segnum; i++) {
2194 buf->input[i] = buf->input[i + 1];
2195 }
2196 }
2197 buf->input[buf->segnum] = NULL;
2198 } else {
2199
2200 /* $B<!J8@a$,#2J8;z0J>e$"$C$?>l9g(B ExpandKanjiConversion */
2201 /* on $B$N;~$O:FEY$+$J4A;zJQ49JQ49$9$k(B */
2202 if (buf->expandkconv & buf->input[nextseg]->status) {
2203 if (buf->input[nextseg]->num < INPUT_YOMI_MAX) {
2204 _Xsj3cwPStomPS(buf, kanabuf, buf->input[nextseg]->yomi);
2205 value = serverIF[buf->server].func[FUNC_CONV]
2206 (kanabuf, bun, knjbuf, KANJIBUFSIZ);
2207 } else {
2208 Xsj3cWarning("Too long segment[num = %d]",nextseg);
2209 }
2210 if (value > 0) {
2211 _Xsj3cStoreKanji(buf, bun, nextseg, value, ON);
2212 buf->segnum += (value - 1);
2213 buf->convedsegnum += value;
2214 } else {
2215 if (value < 0)
2216 Xsj3cWarning("sj3serv is down. reconnect please");
2217 _Xsj3cStoreYomi(buf, buf->input[nextseg], 0);
2218 buf->input[nextseg]->status = SEG_NOCONV;
2219 if (!(buf->movebyseg & SEG_NOCONV))
2220 buf->input[nextseg]->edit = SEG_EDIT;
2221 }
2222 } else {
2223 _Xsj3cStoreYomi(buf, buf->input[nextseg], 0);
2224 buf->input[nextseg]->status = SEG_NOCONV;
2225 if (!(buf->movebyseg & SEG_NOCONV))
2226 buf->input[nextseg]->edit = SEG_EDIT;
2227 }
2228 if (buf->gakusyuu)
2229 buf->input[nextseg]->change = ON;
2230 }
2231
2232 /* $B%+%l%s%HJ8@a$N:G8e$K<!J8@a$N#1J8;z$rB-$9(B */
2233 buf->input[buf->curseg]->cur = buf->input[buf->curseg]->num;
2234 _Xsj3cInsertChar(buf, buf->input[buf->curseg], tmp, 1);
2235
2236 if (buf->input[buf->curseg]->status & SEG_CONVED)
2237 buf->convedsegnum--;
2238
2239 /* ExpandModeConversion on $B$N;~$O9g$o$;$?ItJ,$N(B */
2240 /* $BJ8;z<o$r8=J8@a$NI=<(J8;z<o$KJQ49$9$k(B */
2241 if ((buf->expandmconv & buf->input[buf->curseg]->status) && !modematch) {
2242 Xsj3cSeg seg = buf->input[buf->curseg];
2243
2244 conv++;
2245 _Xsj3cwPStomPS(buf, kanabuf, seg->yomi);
2246 Xsj3cModeConv(buf, kanabuf, seg->cursegmode, seg->size);
2247 seg->num = _Xsj3cmPStowPSn(buf, seg->yomi, kanabuf, seg->size);
2248 if (seg->num > seg->size - YBUFSIZ) {
2249 Xsj3cResizeSegment(seg, seg->size * 2);
2250 seg->num = _Xsj3cmPStowPS(buf, seg->yomi, kanabuf);
2251 }
2252 seg->cur = seg->num;
2253 }
2254
2255 /* ExpandKanjiConversion on $B$N;~$O%+%l%s%H(B */
2256 /* $BJ8@a$r:FEY$+$J4A;zJQ49JQ49$9$k(B */
2257 if (buf->expandkconv & buf->input[buf->curseg]->status) {
2258 value = 0;
2259 if (!conv)
2260 _Xsj3cwPStomPS(buf, kanabuf, buf->input[buf->curseg]->yomi);
2261 if (buf->input[buf->curseg]->num < INPUT_YOMI_MAX) {
2262 value = serverIF[buf->server].func[FUNC_CONV]
2263 (kanabuf, bun, knjbuf, KANJIBUFSIZ);
2264 } else {
2265 Xsj3cWarning("Too long segment[num = %d]",buf->curseg);
2266 }
2267 if (value > 0) {
2268 buf->convedsegnum++;
2269 buf->input[buf->curseg]->status = SEG_CONVED;
2270 buf->input[buf->curseg]->edit = SEG_NOEDIT;
2271 buf->input[buf->curseg]->dnum
2272 = _Xsj3cmPStowOUT(buf, buf->input[buf->curseg]->disp, knjbuf);
2273 if (buf->gakusyuu)
2274 buf->input[buf->curseg]->dcid = bun[0].dcid;
2275 if (value > 1) {
2276 int changed, flush;
2277 if ((buf->candidate = _Xsj3cCandidateInit(buf)) == NULL) {
2278 Xsj3cWarning("sj3serv maybe down, or any trouble");
2279 } else {
2280 Xsj3cSetCandidate(buf, 0, &changed, &flush);
2281 }
2282 }
2283 } else {
2284 if (value < 0)
2285 Xsj3cWarning("sj3serv is down. reconnect please");
2286 _Xsj3cStoreYomi(buf, buf->input[buf->curseg], 0);
2287 buf->input[buf->curseg]->status = SEG_NOCONV;
2288 if (!(buf->movebyseg & SEG_NOCONV))
2289 buf->input[buf->curseg]->edit = SEG_EDIT;
2290 }
2291 } else {
2292 value = 1;
2293 _Xsj3cStoreYomi(buf, buf->input[buf->curseg], 0);
2294 buf->input[buf->curseg]->status = SEG_NOCONV;
2295 if (!(buf->movebyseg & SEG_NOCONV))
2296 buf->input[buf->curseg]->edit = SEG_EDIT;
2297 }
2298
2299 /* temporary $B$N%P%C%U%!$r3+J|$9$k(B */
2300 free(kanabuf);
2301
2302 /* $BJ8@aD93X=,$N$?$a$N%U%i%0$rN)$F$k(B */
2303 if (buf->gakusyuu)
2304 buf->input[buf->curseg]->change = ON;
2305
2306 if (value > 0)
2307 return KEY_TEXT_CHANGE;
2308 else
2309 return (KEY_TEXT_CHANGE|KEY_BELL);
2310 }
2311
2312 /*
2313 * _Xsj3cExpandNoConv()
2314 * Expand current segment by adding next segment.
2315 */
2316 static Xsj3cEvent
2317 _Xsj3cExpandNoConv(buf)
2318 Xsj3cBuf buf;
2319 {
2320 if (buf->curseg + buf->dict->n_dict < buf->segnum - 1) {
2321 buf->dict->n_dict++;
2322 return KEY_TEXT_CHANGE;
2323 } else {
2324 return KEY_BELL;
2325 }
2326 }
2327
2328 /*
2329 * _Xsj3cShrink()
2330 *
2331 * <InputMode/ConvedMode> Shrink the current segment by pushing
2332 * the last character to the next segment.
2333 * <DictMode> Decrease reversed segments by getting off the last segment.
2334 * <NoInputMode/SelectMode> Rings bell.
2335 *
2336 * ShrinkModeConversion on: Change the next segment's character mode.
2337 * ShrinkKanjiConversion on: Do kana-kanji conversion for
2338 * current and next segments.
2339 * ShrinkAll on: When there is only one character in current segment,
2340 * combine with the previous segment
2341 * unless current segment is the first segment.
2342 * ShrinkAll off: When there is only one character in current segment,
2343 * ring bell.
2344 */
2345 Xsj3cEvent
2346 _Xsj3cShrink(buf)
2347 Xsj3cBuf buf;
2348 {
2349 int nextseg = buf->curseg + 1;
2350 int prevseg = buf->curseg - 1, value = 0;
2351 Xsj3cFlag conv1 = 0, conv2 = 0;
2352 register int i, size;
2353 unsigned char tmp[YBUFSIZ];
2354 unsigned char *kanabuf1, *kanabuf2;
2355 unsigned char knjbuf[KANJIBUFSIZ];
2356 SJ3_BUNSETU bun[BUNBUFSIZ];
2357 Xsj3cFlag erase_seg_flg = 0;
2358
2359 if (buf->convmode & DictModeMask)
2360 return (_Xsj3cShrinkNoConv(buf));
2361 else if ((buf->convmode & (SelectModeMask|NoInputModeMask))
2362 || nextseg > buf->segnum)
2363 #ifdef THROUGH_CONT
2364 return (KEY_BELL);
2365 #else /* THROUGH_CONT */
2366 if (buf->cntrlsame)
2367 return (KEY_BELL);
2368 else
2369 return (KEY_TEXT_CHANGE|KEY_BELL); /* dummy */
2370 #endif /* THROUGH_CONT */
2371 else if (buf->input[buf->curseg]->num > 1 || (buf->shrinkall
2372 && buf->input[buf->curseg]->num > 0 && buf->curseg)) {
2373 /* $B%+%l%s%HJ8@a$,#2J8;z0J>e$"$k>l9g!"$^$?$O#1J8;z(B */
2374 /* $B$"$k>l9g$G(B .ShrinkAll on $B$G8=J8@a$,:G=i$NJ8@a$G(B */
2375 /* $B$J$$>l9g!"%+%l%s%HJ8@a$N:G8e$N#1J8;z$r<h$j=P$9(B */
2376
2377 buf->n_select = 0;
2378 if (buf->candidate)
2379 Xsj3cEndCandidate(buf, OFF);
2380 buf->input[buf->curseg]->cur = buf->input[buf->curseg]->num;
2381 _Xsj3cExtractChar(buf, buf->input[buf->curseg], tmp, 1);
2382
2383 /* .ShrinkAll on $B$G8=J8@a$,#1J8;z$7$+$J$+$C$?>l9g(B */
2384 /* $BA0J8@a$H9g@a$9$k$3$H$r;X<($9$k%U%i%0$r(B ON $B$K$9$k(B */
2385 if (!buf->input[buf->curseg]->num)
2386 erase_seg_flg++;
2387 } else {
2388 #ifdef THROUGH_CONT
2389 return (KEY_BELL);
2390 #else /* THROUGH_CONT */
2391 if (buf->cntrlsame)
2392 return (KEY_BELL);
2393 else
2394 return (KEY_TEXT_CHANGE|KEY_BELL); /* dummy */
2395 #endif /* THROUGH_CONT */
2396 }
2397
2398 /* temporary $B$N%P%C%U%!$r:n@.$9$k(B */
2399 if (buf->input[nextseg])
2400 size = buf->input[nextseg]->size;
2401 else
2402 size = KANABUFSIZ;
2403 if ((kanabuf2 = (unsigned char *)malloc(size * sizeof(wchar))) == NULL)
2404 Xsj3cError("Cannot allocate for temporary buffer");
2405
2406 if (buf->curseg)
2407 size = buf->input[prevseg]->size;
2408 else
2409 size = KANABUFSIZ;
2410 if ((kanabuf1 = (unsigned char *)malloc(size * sizeof(wchar))) == NULL)
2411 Xsj3cError("Cannot allocate for temporary buffer");
2412
2413
2414 if (buf->input[buf->curseg]->status & SEG_CONVED)
2415 buf->convedsegnum--;
2416 if (buf->shrinkall && buf->curseg && erase_seg_flg) {
2417 /* .ShrinkAll on $B$GA0J8@a$H9g@a$9$k$3$H$r;X<($9$k(B */
2418 /* $B%U%i%0$,(B ON $B$N;~!"%+%l%s%HJ8@a$+$i<h$j=P$7$?(B */
2419 /* $B#1J8;z$rA0J8@a$N:G8e$KA^F~$9$k(B */
2420
2421 buf->input[prevseg]->cur = buf->input[prevseg]->num;
2422 _Xsj3cInsertChar(buf, buf->input[prevseg], tmp, 1);
2423
2424 /* ShrinkModeConversion on $B$N;~$O9g$o$;$?ItJ,$N(B */
2425 /* $BJ8;z<o$rA0J8@a$NI=<(J8;z<o$KJQ49$9$k(B */
2426 if ((buf->shrinkmconv & buf->input[prevseg]->status)
2427 && buf->input[prevseg]->cursegmode
2428 != buf->input[buf->curseg]->cursegmode) {
2429 Xsj3cSeg seg = buf->input[prevseg];
2430
2431 conv1++;
2432 _Xsj3cwPStomPS(buf, kanabuf1, seg->yomi);
2433 Xsj3cModeConv(buf, kanabuf1, seg->cursegmode, seg->size);
2434 seg->num = _Xsj3cmPStowPSn(buf, seg->yomi, kanabuf1, seg->size);
2435 if (seg->num > buf->input[buf->curseg - 1]->size - YBUFSIZ) {
2436 Xsj3cResizeSegment(seg, seg->size * 2);
2437 seg->num = _Xsj3cmPStowPS(buf, seg->yomi, kanabuf1);
2438 }
2439 seg->cur = seg->num;
2440 }
2441
2442 /* $BJ8@a?t$r8:$8%+%l%s%HJ8@a$NNN0h$r3+J|$9$k(B */
2443 Xsj3cFreeSegment(buf->input[buf->segnum]);
2444 buf->input[buf->segnum] = NULL;
2445 buf->segnum--;
2446 Xsj3cFreeSegment(buf->input[buf->curseg]);
2447 buf->input[buf->curseg] = NULL;
2448 if (nextseg <= buf->segnum) {
2449 for ( i = buf->curseg; i < buf->segnum; i++) {
2450 buf->input[i] = buf->input[i + 1];
2451 }
2452 }
2453 buf->input[buf->segnum] = NULL;
2454 buf->curseg--;
2455 } else {
2456 /* $B%+%l%s%HJ8@a$,#2J8;z0J>e$@$C$?>l9g(B */
2457
2458 if (nextseg < buf->segnum) {
2459 /* $B%+%l%s%HJ8@a$,:G8e$NJ8@a$G$J$$;~!"(B */
2460 /* $B<h$j=P$7$?#1J8;z$r<!J8@a$N@hF,$KA^F~$9$k(B */
2461
2462 buf->input[nextseg]->cur = 0;
2463 _Xsj3cInsertChar(buf, buf->input[nextseg], tmp, 1);
2464 if (buf->input[nextseg]->status & SEG_CONVED)
2465 buf->convedsegnum--;
2466
2467 /* ShrinkModeConversion on $B$N;~$OJ,N%$7$?(B */
2468 /* $BItJ,$NJ8;z<o$r<!J8@a$NI=<(J8;z<o$KJQ49$9$k(B */
2469 if ((buf->shrinkmconv & buf->input[nextseg]->status)
2470 && buf->input[nextseg]->cursegmode
2471 != buf->input[buf->curseg]->cursegmode) {
2472 Xsj3cSeg seg = buf->input[nextseg];
2473
2474 conv2++;
2475 _Xsj3cwPStomPS(buf, kanabuf2, seg->yomi);
2476 Xsj3cModeConv(buf, kanabuf2, seg->cursegmode, seg->size);
2477 seg->num = _Xsj3cmPStowPSn(buf, seg->yomi, kanabuf2, seg->size);
2478 if (seg->num > seg->size - YBUFSIZ) {
2479 Xsj3cResizeSegment(seg, seg->size * 2);
2480 seg->num = _Xsj3cmPStowPS(buf, seg->yomi, kanabuf2);
2481 }
2482 seg->cur = seg->num;
2483 }
2484 } else {
2485 /* $B%+%l%s%HJ8@a$,:G8e$NJ8@a$N;~!"J8@a$r#1$DA}$d$7$F(B */
2486 /* $B<!J8@a$r:n@.$7!"<h$j=P$7$?#1J8;z$r%3%T!<$7$F(B */
2487 /* $B%+%l%s%HJ8@a$NB0@-$r<!J8@a$K%3%T!<$9$k(B */
2488
2489 if (!buf->input[nextseg]) {
2490 if ((buf->input[nextseg]
2491 = (Xsj3cSeg)Xsj3cCreateSegment(buf)) == NULL) {
2492 Xsj3cError("Failed to allocate segment");
2493 }
2494 } else
2495 Xsj3cClearSegment(buf, buf->input[nextseg]);
2496 _Xsj3cInsertChar(buf, buf->input[nextseg], tmp, 1);
2497 buf->input[nextseg]->change = OFF;
2498 buf->input[nextseg]->edit = buf->input[buf->curseg]->edit;
2499 buf->input[nextseg]->status = buf->input[buf->curseg]->status;
2500 if (buf->input[nextseg]->status & SEG_CONVED)
2501 buf->convedsegnum--;
2502 buf->segnum++;
2503 buf->input[nextseg]->cursegmode
2504 = buf->input[buf->curseg]->cursegmode;
2505 buf->input[nextseg]->dcid = buf->input[buf->curseg]->dcid;
2506 }
2507
2508 /* ShrinkKanjiConversion on $B$N;~$OJ,N%$7$?(B */
2509 /* $BItJ,$r9g$o$;$F<!J8@a$r:FEY$+$J4A;zJQ49$9$k(B */
2510 if (buf->shrinkkconv & buf->input[nextseg]->status) {
2511 if (!conv2)
2512 _Xsj3cwPStomPS(buf, kanabuf2, buf->input[nextseg]->yomi);
2513 if (buf->input[nextseg]->num < INPUT_YOMI_MAX) {
2514 value = serverIF[buf->server].func[FUNC_CONV]
2515 (kanabuf2, bun, knjbuf, KANJIBUFSIZ);
2516 } else {
2517 Xsj3cWarning("Too long segment[num = %d]",nextseg);
2518 }
2519 if (value > 0) {
2520 _Xsj3cStoreKanji(buf, bun, nextseg, value, ON);
2521 buf->segnum += (value - 1);
2522 buf->convedsegnum += value;
2523 } else {
2524 if (value < 0)
2525 Xsj3cWarning("sj3serv is down. reconnect please");
2526 _Xsj3cStoreYomi(buf, buf->input[nextseg], 0);
2527 buf->input[nextseg]->status = SEG_NOCONV;
2528 if (!(buf->movebyseg & SEG_NOCONV))
2529 buf->input[nextseg]->edit = SEG_EDIT;
2530 }
2531 } else {
2532 _Xsj3cStoreYomi(buf, buf->input[nextseg], 0);
2533 buf->input[nextseg]->status = SEG_NOCONV;
2534 if (!(buf->movebyseg & SEG_NOCONV))
2535 buf->input[nextseg]->edit = SEG_EDIT;
2536 }
2537 if (buf->gakusyuu)
2538 buf->input[nextseg]->change = ON;
2539 }
2540
2541 /* ExpandKanjiConversion on $B$N;~$O%+%l%s%H(B */
2542 /* $BJ8@a$r:FEY$+$J4A;zJQ49JQ49$9$k(B */
2543 if (buf->shrinkkconv & buf->input[buf->curseg]->status) {
2544 value = 0;
2545 if (!conv1)
2546 _Xsj3cwPStomPS(buf, kanabuf1, buf->input[buf->curseg]->yomi);
2547 if (buf->input[buf->curseg]->num < INPUT_YOMI_MAX) {
2548 value = serverIF[buf->server].func[FUNC_CONV]
2549 (kanabuf1, bun, knjbuf, KANJIBUFSIZ);
2550 } else {
2551 Xsj3cWarning("Too long segment[num = %d]",buf->curseg);
2552 }
2553 if (value > 0) {
2554 buf->convedsegnum++;
2555 buf->input[buf->curseg]->status = SEG_CONVED;
2556 buf->input[buf->curseg]->edit = SEG_NOEDIT;
2557 buf->input[buf->curseg]->dnum
2558 = _Xsj3cmPStowOUT(buf, buf->input[buf->curseg]->disp, knjbuf);
2559 if (buf->gakusyuu)
2560 buf->input[buf->curseg]->dcid = bun[0].dcid;
2561 } else {
2562 if (value < 0)
2563 Xsj3cWarning("sj3serv is down. reconnect please");
2564 _Xsj3cStoreYomi(buf, buf->input[buf->curseg], 0);
2565 buf->input[buf->curseg]->status = SEG_NOCONV;
2566 if (!(buf->movebyseg & SEG_NOCONV))
2567 buf->input[buf->curseg]->edit = SEG_EDIT;
2568 }
2569 } else {
2570 value = 1;
2571 _Xsj3cStoreYomi(buf, buf->input[buf->curseg], 0);
2572 buf->input[buf->curseg]->status = SEG_NOCONV;
2573 if (!(buf->movebyseg & SEG_NOCONV))
2574 buf->input[buf->curseg]->edit = SEG_EDIT;
2575 }
2576
2577 /* temporary $B$N%P%C%U%!$r3+J|$9$k(B */
2578 free(kanabuf1);
2579 free(kanabuf2);
2580
2581 /* $BJ8@aD93X=,$N$?$a$N%U%i%0$rN)$F$k(B */
2582 if (buf->gakusyuu)
2583 buf->input[buf->curseg]->change = ON;
2584
2585 if (value > 0)
2586 return KEY_TEXT_CHANGE;
2587 else
2588 return (KEY_TEXT_CHANGE|KEY_BELL);
2589 }
2590
2591 /*
2592 * _Xsj3cShrinkNoConv()
2593 * Shrink current segment by reducing last segment.
2594 */
2595 static Xsj3cEvent
2596 _Xsj3cShrinkNoConv(buf)
2597 Xsj3cBuf buf;
2598 {
2599 if (buf->dict->n_dict) {
2600 buf->dict->n_dict--;
2601 return KEY_TEXT_CHANGE;
2602 } else {
2603 return (KEY_BELL);
2604 }
2605 }
2606
2607 /*
2608 * _Xsj3cBackSpace()
2609 *
2610 * <InputMode/ConvedMode> Delete previous segment or character.
2611 * <DictMode> Delete previous character for yomi.
2612 * <SelectMode> Popdown the panel and delete previous segment or character.
2613 * <NoInputMode> Does nothing.
2614 *
2615 * DeleteBySegment on: Delete previous segment.
2616 * DeleteBySegment off: Delete previous character.
2617 * DeleteChangeSegment all: Unconvert all segments when "DeleteBySegment"
2618 * is off.
2619 * DeleteChangeSegment one: Unconvert segments after previous segment
2620 * when "DeleteBySegment" is off.
2621 * DeleteChangeSegment after: Unconvert previous segment
2622 * when "DeleteBySegment" is off.
2623 * SelectBackSpaceMove on: Move target segment to current segment.
2624 */
2625 Xsj3cEvent
2626 _Xsj3cBackSpace(buf)
2627 Xsj3cBuf buf;
2628 {
2629 Xsj3cEvent ret = KEY_NULL;
2630
2631 if (buf->convmode & SelectModeMask) {
2632 /* SelectMode $B$N;~$O8uJdA*Br!?5-9fA*Br(B */
2633 /* $B%&%#%s%I%&$r%]%C%W%@%&%s(B */
2634 ret |= KEY_SELECT_ABORT;
2635 if (buf->selectstatus == SELECT_HINSI) {
2636 buf->convmode = DictModeMask;
2637 buf->dict->status = DICT_INPUT;
2638 } else if (buf->selectstatus == SELECT_CAND) {
2639 buf->convmode = ConvedModeMask;
2640 if (buf->selectback)
2641 buf->curseg++;
2642 } else {
2643 buf->convmode = InputModeMask;
2644 if (!buf->segnum)
2645 return(ret);
2646 }
2647 } else if (buf->convmode & NoInputModeMask) {
2648 /* $BJ8@a(B(segement)$B?t$,(B 0$B$N$H$-$OL5;k$9$k(B */
2649 #ifdef THROUGH_CONT
2650 return (KEY_NULL);
2651 #else /* THROUGH_CONT */
2652 if (buf->cntrlsame)
2653 return (KEY_NULL);
2654 else
2655 return (KEY_TEXT_CHANGE); /* dummy */
2656 #endif /* THROUGH_CONT */
2657 }
2658
2659 switch(buf->convmode) {
2660 case InputModeMask:
2661 if ((buf->input[buf->curseg]->edit & SEG_NOEDIT) &&
2662 (buf->delbyseg & buf->input[buf->curseg]->status)) {
2663 if (buf->curseg > 0) {
2664 buf->curseg--;
2665 return(_Xsj3cDeleteSeg(buf, ret, buf->dellastmove));
2666 } else {
2667 return (KEY_BELL);
2668 }
2669 } else {
2670 if (buf->input[buf->curseg]->cur == 0 && buf->curseg > 0) {
2671 buf->curseg--;
2672 if ((buf->input[buf->curseg]->edit & SEG_NOEDIT) &&
2673 buf->delbyseg & buf->input[buf->curseg]->status)
2674 return(_Xsj3cDeleteSeg(buf, ret, buf->dellastmove));
2675 else {
2676 ret |= _Xsj3cUnConvSeg(buf, buf->delchange, ON);
2677 _Xsj3cStoreYomi(buf, buf->input[buf->curseg], 0);
2678 }
2679 }
2680 return(_Xsj3cBackSpaceChar(buf, buf->input[buf->curseg], ret)
2681 & ~KEY_DICT_CHANGE);
2682 }
2683 case ConvedModeMask:
2684 if (buf->curseg > 0) {
2685 buf->curseg--;
2686 } else {
2687 return (KEY_BELL);
2688 }
2689 if (buf->delbyseg & buf->input[buf->curseg]->status) {
2690 return(_Xsj3cDeleteSeg(buf, ret, buf->dellastmove));
2691 } else {
2692 ret |= _Xsj3cUnConvSeg(buf, buf->delchange, ON);
2693 _Xsj3cStoreYomi(buf, buf->input[buf->curseg], 0);
2694 return(_Xsj3cBackSpaceChar(buf, buf->input[buf->curseg], ret)
2695 & ~KEY_DICT_CHANGE);
2696 }
2697 case DictModeMask:
2698 /* DictMode $B$N;~(B */
2699 if (buf->dict->status == DICT_INPUT) {
2700 ret = _Xsj3cBackSpaceChar(buf, buf->dict->seg, ret)
2701 & ~KEY_TEXT_CHANGE;
2702 _Xsj3cFlushDictMsg(buf);
2703 return(ret);
2704 } else {
2705 return(KEY_NULL);
2706 }
2707 default:
2708 return(ret);
2709 }
2710 }
2711
2712 /*
2713 * _Xsj3cDelete()
2714 *
2715 * <InputMode/ConvedMode> Delete current segment or character.
2716 * <DictMode> Delete the character of current position.
2717 * <SelectMode> Popdown the panel and delete current segment or character.
2718 * <NoInputMode> Rings bell.
2719 *
2720 * DeleteBySegment on: Delete current segment.
2721 * DeleteBySegment off: Delete current character.
2722 * DeleteChangeSegment all: Unconvert all segments when "DeleteBySegment"
2723 * is off.
2724 * DeleteChangeSegment one: Unconvert segments after current segment
2725 * when "DeleteBySegment" is off.
2726 * DeleteChangeSegment after: Unconvert current segment
2727 * when "DeleteBySegment" is off.
2728 * DeleteLastMove on: Move current segment to previous
2729 * after deleting last segment.
2730 */
2731 Xsj3cEvent
2732 _Xsj3cDelete(buf)
2733 Xsj3cBuf buf;
2734 {
2735 Xsj3cEvent ret = KEY_NULL;
2736
2737 if (buf->convmode & SelectModeMask) {
2738 ret |= KEY_SELECT_ABORT;
2739 if (buf->selectstatus == SELECT_HINSI) {
2740 buf->convmode = DictModeMask;
2741 buf->dict->status = DICT_INPUT;
2742 } else if (buf->selectstatus == SELECT_CAND) {
2743 buf->convmode = ConvedModeMask;
2744 } else {
2745 buf->convmode = InputModeMask;
2746 if (buf->curseg >= buf->segnum) {
2747 return (ret);
2748 }
2749 }
2750 /* SelectMode $B$N;~$O8uJdA*Br!?5-9fA*Br(B */
2751 /* $B%&%#%s%I%&$r%]%C%W%@%&%s(B */
2752 } else if (buf->convmode & NoInputModeMask) {
2753 #ifdef THROUGH_CONT
2754 return (KEY_NULL);
2755 #else /* THROUGH_CONT */
2756 if (buf->cntrlsame)
2757 return (KEY_NULL);
2758 else
2759 return (KEY_TEXT_CHANGE); /* dummy */
2760 #endif /* THROUGH_CONT */
2761 } else if (buf->curseg >= buf->segnum) {
2762 /* $B$"$k$$$O%+%l%s%HJ8@aHV9f$,J8@a?t$h$j(B */
2763 /* $B>.$5$/$J$$;~$O%Y%k$rLD$i$9(B */
2764 #ifdef THROUGH_CONT
2765 return (KEY_BELL);
2766 #else /* THROUGH_CONT */
2767 if (buf->cntrlsame)
2768 return (KEY_BELL);
2769 else
2770 return (KEY_TEXT_CHANGE|KEY_BELL); /* dummy */
2771 #endif /* THROUGH_CONT */
2772 }
2773
2774 switch(buf->convmode) {
2775 case InputModeMask:
2776 if ((buf->input[buf->curseg]->edit & SEG_NOEDIT) &&
2777 (buf->delbyseg & buf->input[buf->curseg]->status)) {
2778 return(_Xsj3cDeleteSeg(buf, ret, buf->dellastmove));
2779 } else {
2780 if (buf->input[buf->curseg]->num == buf->input[buf->curseg]->cur
2781 && buf->curseg < buf->segnum - 1) {
2782 buf->curseg++;
2783 if ((buf->input[buf->curseg]->edit & SEG_NOEDIT) &&
2784 buf->delbyseg & buf->input[buf->curseg]->status)
2785 return(_Xsj3cDeleteSeg(buf, ret, buf->dellastmove));
2786 else {
2787 ret |= _Xsj3cUnConvSeg(buf, buf->delchange, OFF);
2788 _Xsj3cStoreYomi(buf, buf->input[buf->curseg], 0);
2789 }
2790 }
2791 return(_Xsj3cDeleteChar(buf, buf->input[buf->curseg], ret)
2792 & ~KEY_DICT_CHANGE);
2793 }
2794 case ConvedModeMask:
2795 if (buf->delbyseg & buf->input[buf->curseg]->status) {
2796 return(_Xsj3cDeleteSeg(buf, ret, buf->dellastmove));
2797 } else {
2798 ret |= _Xsj3cUnConvSeg(buf, buf->delchange, OFF);
2799 _Xsj3cStoreYomi(buf, buf->input[buf->curseg], 0);
2800 return(_Xsj3cDeleteChar(buf, buf->input[buf->curseg], ret)
2801 & ~KEY_DICT_CHANGE);
2802 }
2803 case DictModeMask:
2804 /* DictMode $B$N;~(B */
2805 if (buf->dict->status == DICT_INPUT) {
2806 ret = _Xsj3cDeleteChar(buf, buf->dict->seg, ret)
2807 & ~KEY_TEXT_CHANGE;
2808 _Xsj3cFlushDictMsg(buf);
2809 return(ret);
2810 } else {
2811 return(KEY_NULL);
2812 }
2813 default:
2814 return(ret);
2815 }
2816 }
2817
2818 /*
2819 * _Xsj3cBackSpaceChar()
2820 * Delete last character of string buffers.
2821 */
2822 static Xsj3cEvent
2823 _Xsj3cBackSpaceChar(buf, seg, ret)
2824 Xsj3cBuf buf;
2825 Xsj3cSeg seg;
2826 Xsj3cEvent ret;
2827 {
2828 unsigned char tmp[YBUFSIZ];
2829 wchar wcs[RBUFSIZ];
2830 int change_pos, len;
2831 register int i;
2832
2833 if (seg->cur > 0) {
2834 /* $B%+!<%=%k0LCV$h$jA0$KI=<(J8;zNs$,B8:_$9$k$H$-(B */
2835
2836 if (buf->backdisplay) {
2837
2838 /* .BackDisplay on $B$N;~(B */
2839
2840 change_pos = seg->cur - 1;
2841 if (seg->n_roma) {
2842 /* $B$R$i$,$J!?A43Q%+%?%+%J!?H>3Q%+%?%+%JF~NO%b!<%I$N(B */
2843 /* $B$H$-$G%m!<%^;z%P%C%U%!$KJ8;z$,;D$C$F$$$k$H$-(B */
2844 /* $B$^$:0lJ8;z:o=|$9$k(B */
2845 _Xsj3cExtractChar(buf, seg, tmp, 1);
2846 change_pos = seg->cur;
2847 if (*seg->oldstr != '\0' && seg->value < 0) {
2848 /* $BB`Hr%P%C%U%!$KJ8;z$,$"$C$FD>A0$N%m!<%^;z$+$J(B */
2849 /* $BJQ49$N7k2L$,JQ49ITG=$N>l9g$OB`Hr%P%C%U%!$N(B */
2850 /* $BJ8;z$r%m!<%^;z%P%C%U%!$K%3%T!<$9$k(B */
2851 strcpy(seg->str, seg->oldstr);
2852 seg->n_roma = strlen(seg->oldstr);
2853 seg->sp = seg->str;
2854 seg->sp += seg->n_roma;
2855 *(seg->sp) = '\0';
2856 *seg->oldstr = '\0';
2857 } else {
2858 /* $B%m!<%^;zF~NO$GD>A0$NJQ497k2L>uBV$,ITDj$N$H$-(B */
2859 /* $B$O$H$-$O%m!<%^;z%P%C%U%!$NH>3Q%"%k%U%!%Y%C%H(B */
2860 /* $B$r#1J8;z:o=|$7!"FI$_%P%C%U%!$dI=<(%P%C%U%!$N(B */
2861 /* $B%"%k%U%!%Y(B $B%C%H$b#1J8;z>C5n$9$k(B */
2862 seg->sp--;
2863 *seg->sp = '\0';
2864 seg->n_roma--;
2865 }
2866 } else if (seg->n_kana > 0) {
2867 /* $B$+$JF~NO$G$R$i$,$J!?A43Q%+%?%+%JF~NO%b!<%I$N;~$G(B */
2868 /* $B$+$J%P%C%U%!$KJ8;z$,;D$C$F$$$k;~$O$+$J%P%C%U%!Cf(B */
2869 /* $B$N%+%J$HFI$_%P%C%U%!!"I=<(%P%C%U%!Cf$N$R$i$,$JA4(B */
2870 /* $B3Q%+%?%+%J$r#1J8;z>C5n$7!"99$K$b$&#1J8;zA0$NA43Q(B */
2871 /* $B$+$J$rH>3Q%+%?%+%J$KJQ49$7$F$+$J%P%C%U%!$KF~$l$k(B */
2872 _Xsj3cExtractChar(buf, seg, tmp, 1);
2873 change_pos = seg->cur;
2874 seg->sp = seg->str;
2875 *seg->str = '\0';
2876 if (seg->cur > 0 &&
2877 (ishira(seg->yomi[seg->cur - 1], serverIF[buf->server].lang) ||
2878 iskata(seg->yomi[seg->cur - 1], serverIF[buf->server].lang))) {
2879 wcs[0] = seg->yomi[seg->cur - 1];
2880 wcs[1] = '\0';
2881 _Xsj3cwPStomPS(buf, tmp, wcs);
2882 _Xsj3cZKanaToHKata(buf, seg->str, tmp);
2883 if (isdakuon(*seg->str)
2884 && strlen(seg->str) == 1) {
2885 *(++seg->sp) = '\0';
2886 seg->n_kana = 1;
2887 } else {
2888 seg->n_kana = 0;
2889 }
2890 } else {
2891 seg->n_kana = 0;
2892 }
2893 } else {
2894 /* $B%m!<%^;zF~NO;~$N%m!<%^;z%P%C%U%!$d$+$JF~NO;~$N(B */
2895 /* $B$+$J%P%C%U%!$KJ8;z$,;D$C$F$$$J$$$H$-(B */
2896 if (*seg->oldstr != '\0' &&
2897 iskan1(seg->yomi[seg->cur - 1] >> 8, serverIF[buf->server].lang)
2898 && iskan2(seg->yomi[seg->cur - 1] & 0xff,
2899 serverIF[buf->server].lang)) {
2900 /* $BB`Hr%P%C%U%!$KJ8;z$,$"$C$F:o=|$9$k:G8e$N(B */
2901 /* $BJ8;z$,A43QJ8;z$N$H$-(B */
2902 if (seg->n_kana < 0) {
2903 /* $B%m!<%^;zF~NO!?%3!<%IF~NO$N>l9g!"#1J8;z:o(B */
2904 /* $B=|$7$FB`Hr%P%C%U%!$NJ8;z$r%3%T!<$9$k(B */
2905 strcpy(seg->str, seg->oldstr);
2906 seg->n_roma = strlen(seg->oldstr);
2907 _Xsj3cExtractChar(buf, seg, tmp, seg->oldlen);
2908 change_pos = seg->cur;
2909 if (buf->alphaconv && buf->inputmode != MODE_HKATA) {
2910 _Xsj3cHAlphaToZKana(buf, tmp, seg->oldstr);
2911 _Xsj3cInsertChar(buf, seg, tmp, seg->n_roma);
2912 } else {
2913 _Xsj3cInsertChar(buf, seg, seg->oldstr,
2914 seg->n_roma);
2915 }
2916 seg->sp = seg->str;
2917 seg->sp += seg->n_roma;
2918 } else {
2919 /* $B$+$JF~NO$N>l9g#1J8;z:o=|$7$FB`Hr%P%C%U%!(B */
2920 /* $BJ8;z$r%3%T!<$7$=$NJ8;z$r:FEY$+$JJQ49$9$k(B */
2921 _Xsj3cExtractChar(buf, seg, tmp, 1);
2922 change_pos = seg->cur;
2923 seg->sp = seg->str;
2924 strcpy(seg->str, seg->oldstr);
2925 if ((seg->value = _Xsj3cKanaConv(buf, seg, seg->str,
2926 tmp, buf->inputmode)) > 0) {
2927 seg->n_kana = 0;
2928 } else if (seg->value == 0) {
2929 seg->n_kana = 1;
2930 *(++seg->sp) = '\0';
2931 len = _Xsj3cmPStowPS(buf, wcs, tmp);
2932 _Xsj3cInsertWchar(seg, wcs, len);
2933 } else {
2934 seg->n_kana = 0;
2935 }
2936 }
2937 *seg->oldstr = '\0';
2938 seg->oldlen = 0;
2939 } else if (*seg->oldstr != '\0') {
2940 /* $B%3!<%IF~NO$GH>3Q$KJQ49$5$l$k;~(B */
2941 /* $B$^$?$OH>%+%J%b!<%I$N;~(B */
2942 strcpy(seg->str, seg->oldstr);
2943 seg->n_roma = strlen(seg->oldstr);
2944 _Xsj3cExtractChar(buf, seg, tmp, seg->oldlen);
2945 change_pos = seg->cur;
2946 if (buf->alphaconv && buf->inputmode != MODE_HKATA) {
2947 _Xsj3cHAlphaToZKana(buf, tmp, seg->oldstr);
2948 _Xsj3cInsertChar(buf, seg, tmp, seg->n_roma);
2949 } else {
2950 _Xsj3cInsertChar(buf, seg, seg->oldstr,
2951 seg->n_roma);
2952 }
2953 seg->sp = seg->str;
2954 seg->sp += seg->n_roma;
2955 *seg->oldstr = '\0';
2956 seg->oldlen = 0;
2957 } else {
2958 /* $BB`Hr%P%C%U%!$KJ8;z$,;D$C$F$$$J$$$H$-(B */
2959 _Xsj3cExtractChar(buf, seg, tmp, 1);
2960 change_pos = seg->cur;
2961 *seg->str = '\0';
2962 seg->sp = seg->str;
2963 if (seg->n_kana >= 0) {
2964 if (seg->cur > 0 && (ishira(seg->yomi[seg->cur - 1],
2965 serverIF[buf->server].lang) ||
2966 iskata(seg->yomi[seg->cur - 1],
2967 serverIF[buf->server].lang))) {
2968 /* $B$+$JF~NO$N$H$-$O99$K#1J8;zA0(B */
2969 /* $B$NA43Q$+$J$rH>3Q%+%?%+%J$KJQ(B */
2970 /* $B49$7$F$+$J%P%C%U%!$KF~$l$k(B */
2971 wcs[0] = seg->yomi[seg->cur - 1];
2972 wcs[1] = '\0';
2973 _Xsj3cwPStomPS(buf, tmp, wcs);
2974 _Xsj3cZKanaToHKata(buf, seg->str, tmp);
2975 if (isdakuon(*seg->str)
2976 && strlen(seg->str) == 1) {
2977 *(++seg->sp) = '\0';
2978 seg->n_kana = 1;
2979 } else {
2980 seg->n_kana = 0;
2981 *seg->str = '\0';
2982 }
2983 } else {
2984 seg->n_kana = 0;
2985 }
2986 } else {
2987 seg->n_kana = -1;
2988 }
2989 }
2990 }
2991 } else {
2992 /* .BackDisplay off $B$N;~(B */
2993
2994 _Xsj3cExtractChar(buf, seg, tmp, 1);
2995 change_pos = seg->cur;
2996 if (seg->n_roma) {
2997 /* $B%m!<%^;zF~NO$G%m!<%^;z%P%C%U%!$KJ8;z$,$"$k>l9g(B */
2998 seg->sp--;
2999 *seg->sp = '\0';
3000 seg->n_roma--;
3001 } else if (seg->n_kana >= 0) {
3002 /* $B$+$JF~NO$N$H$-$O99$K#1J8;zA0$NA43Q$+$J(B */
3003 /* $B$rH>3Q%+%?%+%J$KJQ49$7$F!"$=$l$,By2;(B */
3004 /* $B8uJd$@$C$?$i$+$J%P%C%U%!$KF~$l$k(B */
3005 *seg->str = '\0';
3006 seg->sp = seg->str;
3007 if (seg->cur > 0 && (ishira(seg->yomi[seg->cur - 1],
3008 serverIF[buf->server].lang) ||
3009 iskata(seg->yomi[seg->cur - 1],
3010 serverIF[buf->server].lang))) {
3011 wcs[0] = seg->yomi[seg->cur - 1];
3012 wcs[1] = '\0';
3013 _Xsj3cwPStomPS(buf, tmp, wcs);
3014 _Xsj3cZKanaToHKata(buf, seg->str, tmp);
3015 if (isdakuon(*seg->str)
3016 && strlen(seg->str) == 1) {
3017 *(++seg->sp) = '\0';
3018 seg->n_kana = 1;
3019 } else {
3020 seg->n_kana = 0;
3021 *seg->str = '\0';
3022 }
3023 } else {
3024 seg->n_kana = 0;
3025 }
3026 } else {
3027 *seg->str = '\0';
3028 seg->sp = seg->str;
3029 seg->n_kana = -1;
3030 }
3031 }
3032 _Xsj3cStoreYomi(buf, seg, change_pos);
3033 if (seg->num < seg->size - KANABUFSIZ - YBUFSIZ)
3034 Xsj3cResizeSegment(seg, seg->size - KANABUFSIZ);
3035 if (seg->num == 0 && (buf->convmode & ~DictModeMask)) {
3036 Xsj3cFreeSegment(buf->input[buf->segnum]);
3037 buf->input[buf->segnum] = NULL;
3038 buf->segnum--;
3039 Xsj3cFreeSegment(seg);
3040 seg = NULL;
3041 for (i = buf->curseg; i < buf->segnum; i++) {
3042 buf->input[i] = buf->input[i + 1];
3043 }
3044 buf->input[buf->segnum] = NULL;
3045 }
3046 if (buf->dispmodechange) {
3047 buf->dispmode = ((buf->segnum &&
3048 buf->convedsegnum == buf->segnum) ? MODE_KANJI :
3049 (buf->convedsegnum ? MODE_EDIT : buf->inputmode));
3050 ret |= KEY_MODE_CHANGE;
3051 }
3052 if (buf->curseg && buf->curseg == buf->segnum && buf->dellastmove)
3053 buf->curseg--;
3054
3055 return(ret|KEY_TEXT_CHANGE|KEY_DICT_CHANGE);
3056 } else {
3057 /* $B%+!<%=%k0LCV$h$jA0$KI=<(J8;zNs$,$J$$$H$-(B */
3058 #ifdef THROUGH_CONT
3059 return (KEY_BELL);
3060 #else /* THROUGH_CONT */
3061 if (buf->cntrlsame)
3062 return (KEY_BELL);
3063 else
3064 return (KEY_TEXT_CHANGE|KEY_BELL); /* dummy */
3065 #endif /* THROUGH_CONT */
3066 }
3067 }
3068
3069 /*
3070 * _Xsj3cDeleteChar()
3071 * Delete next character of string buffers.
3072 */
3073 static Xsj3cEvent
3074 _Xsj3cDeleteChar(buf, seg, ret)
3075 Xsj3cBuf buf;
3076 Xsj3cSeg seg;
3077 Xsj3cEvent ret;
3078 {
3079 unsigned char tmp[YBUFSIZ];
3080 int change_pos;
3081 register int i;
3082
3083 if (seg->cur < seg->num) {
3084 /* $B%+!<%=%k0LCV$h$j8e$m$KI=<(J8;zNs$,B8:_$9$k$H$-(B */
3085
3086 change_pos = seg->cur;
3087 seg->cur++;
3088 _Xsj3cExtractChar(buf, seg, tmp, 1);
3089 _Xsj3cStoreYomi(buf, seg, change_pos);
3090 if (seg->num < seg->size - KANABUFSIZ - YBUFSIZ)
3091 Xsj3cResizeSegment(seg, seg->size - KANABUFSIZ);
3092 if (seg->num == 0 && (buf->convmode & ~DictModeMask)) {
3093 Xsj3cFreeSegment(buf->input[buf->segnum]);
3094 buf->input[buf->segnum] = NULL;
3095 buf->segnum--;
3096 Xsj3cFreeSegment(seg);
3097 seg = NULL;
3098 for (i = buf->curseg; i < buf->segnum; i++) {
3099 buf->input[i] = buf->input[i + 1];
3100 }
3101 buf->input[buf->segnum] = NULL;
3102 if (buf->dispmodechange) {
3103 buf->dispmode = ((buf->segnum &&
3104 buf->convedsegnum == buf->segnum) ? MODE_KANJI :
3105 (buf->convedsegnum ? MODE_EDIT : buf->inputmode));
3106 ret |= KEY_MODE_CHANGE;
3107 }
3108 if (buf->curseg && buf->curseg == buf->segnum && buf->dellastmove)
3109 buf->curseg--;
3110 }
3111 return(ret|KEY_TEXT_CHANGE|KEY_DICT_CHANGE);
3112 } else {
3113 /* $B%+!<%=%k0LCV$h$j8e$m$KI=<(J8;zNs$,$J$$$H$-(B */
3114
3115 return(KEY_NULL);
3116 }
3117 }
3118
3119 /*
3120 * _Xsj3cDeleteSeg()
3121 * Delete current segment.
3122 */
3123 static Xsj3cEvent
3124 _Xsj3cDeleteSeg(buf, ret, move)
3125 Xsj3cBuf buf;
3126 Xsj3cEvent ret;
3127 Xsj3cFlag move;
3128 {
3129 register int i;
3130
3131 buf->n_select = 0;
3132 if ((buf->convmode & ConvedModeMask) && buf->candidate)
3133 Xsj3cEndCandidate(buf, OFF);
3134 if (buf->segnum <= buf->curseg) {
3135 return (ret);
3136 }
3137 Xsj3cFreeSegment(buf->input[buf->segnum]);
3138 buf->input[buf->segnum] = NULL;
3139 buf->segnum--;
3140 if (!buf->segnum) {
3141 /* $BJ8@a?t$,(B 0 $B$K$J$C$?$H$-$OJQ49MQJ8;z(B */
3142 /* $B%P%C%U%!$r%/%j%"$7$F(B InputMode $B$K$9$k(B */
3143
3144 buf->convedsegnum = 0;
3145 buf->curseg = 0;
3146 Xsj3cClearSegment(buf, buf->input[0]);
3147 } else if (buf->curseg == buf->segnum) {
3148
3149 if (buf->input[buf->curseg]->status & SEG_CONVED) {
3150 buf->convedsegnum--;
3151 if (!buf->convedsegnum && buf->gakusyuu) {
3152 _Xsj3cClearDcid(buf);
3153 }
3154 }
3155 Xsj3cFreeSegment(buf->input[buf->curseg]);
3156 buf->input[buf->curseg] = NULL;
3157 /* $BJQ49Cf$NJ8>O$N:G8e$NJ8@a$N;~$O8=J8@a$r$R$H$DA0$K$:$i$9(B */
3158 if (move)
3159 buf->curseg--;
3160 } else if (buf->curseg < buf->segnum) {
3161 /* $B:G8e$NJ8@a$G$J$$$N;~$O0J9_$NJ8@a$r(B */
3162 /* $B$R$H$D$:$DA0$K$:$i$9(B */
3163
3164 if (buf->input[buf->curseg]->status & SEG_CONVED) {
3165 buf->convedsegnum--;
3166 if (!buf->convedsegnum && buf->gakusyuu) {
3167 _Xsj3cClearDcid(buf);
3168 }
3169 }
3170 Xsj3cFreeSegment(buf->input[buf->curseg]);
3171 buf->input[buf->curseg] = NULL;
3172 for (i = buf->curseg; i < buf->segnum; i++) {
3173 buf->input[i] = buf->input[i + 1];
3174 }
3175 buf->input[buf->segnum] = NULL;
3176 }
3177 if (buf->dispmodechange) {
3178 buf->dispmode = ((buf->segnum &&
3179 buf->convedsegnum == buf->segnum) ? MODE_KANJI :
3180 (buf->convedsegnum ? MODE_EDIT : buf->inputmode));
3181 ret |= KEY_MODE_CHANGE;
3182 }
3183 ret |= KEY_TEXT_CHANGE;
3184 return(ret);
3185 }
3186
3187 /*
3188 * _Xsj3cDelAfter()
3189 *
3190 * <InputMode/ConvedMode> Delete current segment and all segments after
3191 * current segment or cursor position.
3192 * <DictMode> Delete all yomi strings.
3193 * <SelectMode> Popdown the panel and delete strings after current segment
3194 * or cursor position.
3195 * <NoInputMode> Rings bell.
3196 *
3197 * DeleteBySegment on: Delete current segment and all segments after current.
3198 * DeleteBySegment off: Delete strings after current cursor position
3199 * in current segment.
3200 * DeleteLastMove on: Move current segment to previous
3201 * after deleting last segment.
3202 */
3203 Xsj3cEvent
3204 _Xsj3cDelAfter(buf)
3205 Xsj3cBuf buf;
3206 {
3207 Xsj3cEvent ret = KEY_NULL;
3208 register int i, begin;
3209 int del_num;
3210 unsigned char *tmp;
3211
3212 if (buf->convmode & SelectModeMask) {
3213 if (buf->selectstatus == SELECT_HINSI || buf->curseg >= buf->segnum) {
3214 if (buf->selectstatus == SELECT_HINSI)
3215 buf->dict->status = DICT_INPUT;
3216 if (buf->dispmodechange) {
3217 buf->dispmode =
3218 (buf->dict->mode == REG_STATE ? MODE_TOROKU : MODE_SYOUKYO);
3219 return (KEY_SELECT_ABORT|KEY_MODE_CHANGE);
3220 } else
3221 return (KEY_SELECT_ABORT);
3222 } else {
3223 ret |= KEY_SELECT_ABORT;
3224 }
3225 /* SelectMode $B$N;~$O8uJdA*Br!?5-9fA*Br(B */
3226 /* $B%&%#%s%I%&$r%]%C%W%@%&%s(B */
3227 } else if (buf->convmode & (NoInputModeMask|DictModeMask)) {
3228 #ifdef THROUGH_CONT
3229 return (KEY_NULL);
3230 #else /* THROUGH_CONT */
3231 if (buf->cntrlsame)
3232 return (KEY_NULL);
3233 else
3234 return (KEY_TEXT_CHANGE); /* dummy */
3235 #endif /* THROUGH_CONT */
3236 } else if (buf->curseg >= buf->segnum) {
3237 /* $B$"$k$$$O%+%l%s%HJ8@aHV9f$,J8@a?t$h$j(B */
3238 /* $B>.$5$/$J$$;~$O%Y%k$rLD$i$9(B */
3239 #ifdef THROUGH_CONT
3240 return (KEY_BELL);
3241 #else /* THROUGH_CONT */
3242 if (buf->cntrlsame)
3243 return (KEY_BELL);
3244 else
3245 return (KEY_TEXT_CHANGE|KEY_BELL); /* dummy */
3246 #endif /* THROUGH_CONT */
3247 }
3248
3249 ret |= KEY_TEXT_CHANGE;
3250 if (buf->killbyseg & buf->input[buf->curseg]->status) {
3251 if (buf->input[buf->curseg]->edit & SEG_NOEDIT) {
3252 begin = buf->curseg;
3253 } else {
3254 if (!buf->input[buf->curseg]->cur) {
3255 begin = buf->curseg;
3256 } else {
3257 begin = buf->curseg + 1;
3258 if (buf->input[buf->curseg]->cur
3259 < buf->input[buf->curseg]->num) {
3260 del_num = buf->input[buf->curseg]->num
3261 - buf->input[buf->curseg]->cur;
3262 buf->input[buf->curseg]->cur = buf->input[buf->curseg]->num;
3263 if ((tmp = (unsigned char *)
3264 malloc(buf->input[buf->curseg]->size
3265 * sizeof(wchar))) == NULL)
3266 Xsj3cError("Cannot allocate for temporary buffer");
3267 _Xsj3cExtractChar(buf, buf->input[buf->curseg], tmp, del_num);
3268 free(tmp);
3269 _Xsj3cStoreYomi(buf, buf->input[buf->curseg],
3270 buf->input[buf->curseg]->cur);
3271 }
3272 }
3273 }
3274 for (i = begin; i < buf->segnum + 1; i++) {
3275 if (buf->input[i]->status & SEG_CONVED)
3276 buf->convedsegnum--;
3277 Xsj3cFreeSegment(buf->input[i]);
3278 buf->input[i] = NULL;
3279 }
3280 buf->segnum = begin;
3281 if (begin == buf->curseg && buf->dellastmove && buf->curseg)
3282 buf->curseg--;
3283 if (buf->dispmodechange) {
3284 buf->dispmode = ((buf->segnum &&
3285 buf->convedsegnum == buf->segnum) ? MODE_KANJI :
3286 (buf->convedsegnum ? MODE_EDIT : buf->inputmode));
3287 ret |= KEY_MODE_CHANGE;
3288 }
3289 if (buf->gakusyuu && !buf->convedsegnum)
3290 _Xsj3cClearDcid(buf);
3291 } else {
3292 if (buf->input[buf->curseg]->edit & SEG_NOEDIT
3293 || !buf->input[buf->curseg]->cur) {
3294 ret |= _Xsj3cDeleteSeg(buf, ret, buf->dellastmove);
3295 } else {
3296 if (buf->input[buf->curseg]->cur
3297 < buf->input[buf->curseg]->num) {
3298 del_num = buf->input[buf->curseg]->num
3299 - buf->input[buf->curseg]->cur;
3300 buf->input[buf->curseg]->cur = buf->input[buf->curseg]->num;
3301 if ((tmp = (unsigned char *)
3302 malloc(buf->input[buf->curseg]->size
3303 * sizeof(wchar))) == NULL)
3304 Xsj3cError("Cannot allocate for temporary buffer");
3305 _Xsj3cExtractChar(buf, buf->input[buf->curseg], tmp, del_num);
3306 free(tmp);
3307 _Xsj3cStoreYomi(buf, buf->input[buf->curseg],
3308 buf->input[buf->curseg]->cur);
3309 }
3310 }
3311 }
3312
3313 return(ret);
3314 }
3315
3316 /*
3317 * _Xsj3cStart()
3318 *
3319 * <NoInputMode/InputMode/ConvedMode/DictMode/SelectMode> If now on converting,
3320 * fix all segments, then end kana-kanji converting.
3321 *
3322 * FlushEndConversion on: Flush converting strings before ending.
3323 * DisplayModeChange on: Change the display mode string.
3324 */
3325 Xsj3cEvent
3326 _Xsj3cStart(buf)
3327 Xsj3cBuf buf;
3328 {
3329 Xsj3cEvent ret = KEY_HENKAN_END;
3330 register int i;
3331
3332 if (buf->dispmodechange) {
3333 buf->dispmode = buf->inputmode;
3334 }
3335 switch(buf->convmode) {
3336 case ConvedModeMask:
3337 buf->n_select = 0;
3338 if (buf->candidate)
3339 Xsj3cEndCandidate(buf, OFF);
3340 case InputModeMask:
3341 break;
3342 case SelectModeMask:
3343 if (buf->flusheconv)
3344 ret |= KEY_SELECT_END;
3345 else
3346 ret |= KEY_SELECT_ABORT;
3347 if (buf->candidate)
3348 Xsj3cEndCandidate(buf, OFF);
3349 buf->n_select = 0;
3350 break;
3351 case DictModeMask:
3352 ret |= KEY_DICT_END;
3353 break;
3354 case NoInputModeMask:
3355 return (KEY_HENKAN_END);
3356 default:
3357 /* Not supported */
3358 return (KEY_HENKAN_START);
3359 }
3360 if (buf->flusheconv) {
3361 ret |= KEY_TEXT_FIXED;
3362 } else {
3363 for (i = 1; i < buf->segnum + 1; i++) {
3364 Xsj3cFreeSegment(buf->input[i]);
3365 buf->input[i] = NULL;
3366 }
3367 if (buf->input[0])
3368 Xsj3cClearSegment(buf, buf->input[0]);
3369 buf->segnum = 0;
3370 buf->convedsegnum = 0;
3371 buf->curseg = 0;
3372 }
3373 return ret;
3374 }
3375
3376 /*
3377 * _Xsj3cReConnect()
3378 *
3379 * <NoInputMode/InputMode/ConvedMode/DictMode/SelectMode> Popdown the panel
3380 * and clear all segments, then reonnect to sj3serv.
3381 *
3382 * FlushEndConversion on: Flush converting strings before reconnecting.
3383 * DisplayModeChange on: Change the display mode string.
3384 */
3385 Xsj3cEvent
3386 _Xsj3cReConnect(buf)
3387 Xsj3cBuf buf;
3388 {
3389 Xsj3cEvent ret = KEY_TEXT_CHANGE;
3390
3391 if (buf->gakusyuu) {
3392 _Xsj3cClearDcid(buf);
3393 }
3394 switch (buf->convmode) {
3395 case ConvedModeMask:
3396 buf->n_select = 0;
3397 if (buf->candidate)
3398 Xsj3cEndCandidate(buf, OFF);
3399 case InputModeMask:
3400 case NoInputModeMask:
3401 ret = KEY_RECONNECT;
3402 break;
3403 case SelectModeMask:
3404 ret = KEY_SELECT_ABORT|KEY_RECONNECT;
3405 buf->n_select = 0;
3406 if (buf->candidate)
3407 Xsj3cEndCandidate(buf, OFF);
3408 break;
3409 case DictModeMask:
3410 ret = KEY_DICT_END|KEY_RECONNECT;
3411 break;
3412 default:
3413 ret = KEY_RECONNECT;
3414 break;
3415 }
3416 if (buf->dispmodechange) {
3417 buf->dispmode = buf->inputmode;
3418 ret |= KEY_MODE_CHANGE;
3419 }
3420 return ret;
3421 }
3422
3423 /*
3424 * _Xsj3cReConvert()
3425 *
3426 * <NoInputMode> If there is no string in input buffer,
3427 * copy from backup buffer which saved last fixed or flushed.
3428 * But there is any strings in input buffer or backup buffer is null,
3429 * ring bell.
3430 * <InputMode/UnputMode/SelectMode/DictMode> Ring bell.
3431 *
3432 * BeginConversionLast on: Set current segment to the last one.
3433 * BeginConversionLast none: Allow to move out of segments.
3434 */
3435 Xsj3cEvent
3436 _Xsj3cReConvert(buf)
3437 Xsj3cBuf buf;
3438 {
3439 register int i, conved;
3440
3441 if ((buf->convmode & NoInputModeMask) && buf->backup) {
3442 buf->segnum = buf->backsegnum;
3443 if (!buf->segnum)
3444 #ifdef THROUGH_CONT
3445 return (KEY_NULL);
3446 #else /* THROUGH_CONT */
3447 if (buf->cntrlsame)
3448 return (KEY_NULL);
3449 else
3450 return (KEY_TEXT_CHANGE); /* dummy */
3451 #endif /* THROUGH_CONT */
3452 for (i = 0, conved = 0; i < buf->segnum; i++) {
3453 if (!buf->input[i]) {
3454 if ((buf->input[i]
3455 = (Xsj3cSeg)Xsj3cCreateSegment(buf)) == NULL) {
3456 Xsj3cError("Failed to allocate segment");
3457 }
3458 } else {
3459 *buf->input[i]->oldstr = '\0';
3460 buf->input[i]->oldlen = 0;
3461 *buf->input[i]->str = '\0';
3462 buf->input[i]->sp = buf->input[i]->str;
3463 buf->input[i]->change = OFF;
3464 buf->input[i]->n_roma = 0;
3465 buf->input[i]->n_kana = -1;
3466 buf->input[i]->value = 0;
3467 }
3468 _Xsj3cWcpy(buf->input[i]->yomi, buf->backup[i]->yomi);
3469 buf->input[i]->num = buf->backup[i]->num;
3470 buf->input[i]->cur = buf->backup[i]->cur;
3471 _Xsj3cWcpy(buf->input[i]->disp, buf->backup[i]->disp);
3472 buf->input[i]->dnum = buf->backup[i]->dnum;
3473 buf->input[i]->dcid = buf->backup[i]->dcid;
3474 buf->input[i]->edit = buf->backup[i]->edit;
3475 buf->input[i]->cursegmode = buf->backup[i]->cursegmode;
3476 if ((buf->input[i]->status = buf->backup[i]->status) == SEG_CONVED)
3477 conved++;
3478 buf->input[i]->size = buf->backup[i]->size;
3479 }
3480 buf->convedsegnum = conved;
3481 switch (buf->beginlastseg) {
3482 case NONE:
3483 buf->curseg = buf->segnum;
3484 break;
3485 case ON:
3486 buf->curseg = buf->segnum - 1;
3487 break;
3488 case OFF:
3489 buf->curseg = 0;
3490 break;
3491 default:
3492 buf->curseg = 0;
3493 break;
3494 }
3495 return (KEY_TEXT_CHANGE);
3496 } else {
3497 return KEY_NULL;
3498 }
3499 }
3500
3501 /*
3502 * _Xsj3cEdit() [edit]
3503 *
3504 * <InputMode/ConvedMode> Unconvert segments.
3505 * <SelectMode> pop down the panel candidate(symbol/hinsi) panel and
3506 * unconvert current segment.
3507 * <DictMode> Pop down Auxpanel and unconvert current segment.
3508 * <NoInputMode> Does nothing.
3509 *
3510 * DisplayModeChange on: Change the display mode string.
3511 * EditCursorLast on: Set cursor position to bottom of segment.
3512 * EditCursorLast off: Set cursor position to top of segment.
3513 */
3514 Xsj3cEvent
3515 _Xsj3cEdit(buf)
3516 Xsj3cBuf buf;
3517 {
3518 Xsj3cEvent ret = KEY_NULL;
3519
3520 if (buf->convmode & SelectModeMask) {
3521 ret |= KEY_SELECT_ABORT;
3522 if (buf->selectstatus == SELECT_HINSI) {
3523 ret |= KEY_DICT_END;
3524 }
3525 } else if (buf->convmode & DictModeMask) {
3526 ret |= KEY_DICT_END;
3527 } else if (buf->convmode & NoInputModeMask) {
3528 #ifdef THROUGH_CONT
3529 return (KEY_NULL);
3530 #else /* THROUGH_CONT */
3531 if (buf->cntrlsame)
3532 return (KEY_NULL);
3533 else
3534 return (KEY_TEXT_CHANGE); /* dummy */
3535 #endif /* THROUGH_CONT */
3536 }
3537 ret |= _Xsj3cUnConvSeg(buf, ONE, buf->editcurlast);
3538 _Xsj3cStoreYomi(buf, buf->input[buf->curseg], 0);
3539 buf->input[buf->curseg]->edit = SEG_EDIT;
3540 return (ret);
3541 }
3542
3543 /*
3544 * _Xsj3cDRegBegin()
3545 *
3546 * <InputMode/ConvedMode> Begin to registr the word in the dictionary.
3547 * <NoInputMode/DictMode/SelectMode> Rings bell.
3548 *
3549 * DisplayModeChange on: Change the display mode string.
3550 */
3551 Xsj3cEvent
3552 _Xsj3cDRegBegin(buf)
3553 Xsj3cBuf buf;
3554 {
3555 if (buf->convmode & (ConvedModeMask|InputModeMask)) {
3556 buf->n_select = 0;
3557 if (buf->candidate)
3558 Xsj3cEndCandidate(buf, ON);
3559 buf->dict = _Xsj3cCreateDictData(buf, REG_STATE);
3560 buf->convmode = DictModeMask;
3561 _Xsj3cFlushDictMsg(buf);
3562 if (buf->dispmodechange) {
3563 buf->dispmode = MODE_TOROKU;
3564 return (KEY_DICT_START|KEY_MODE_CHANGE);
3565 } else
3566 return (KEY_DICT_START);
3567 } else {
3568 #ifdef THROUGH_CONT
3569 return (KEY_BELL);
3570 #else /* THROUGH_CONT */
3571 if (buf->cntrlsame)
3572 return (KEY_BELL);
3573 else
3574 return (KEY_TEXT_CHANGE|KEY_BELL); /* dummy */
3575 #endif /* THROUGH_CONT */
3576 }
3577 }
3578
3579 /*
3580 * _Xsj3cDClearBegin()
3581 *
3582 * <InputMode/ConvedMode> Begin to eliminate the word in the dictionary.
3583 * <NoInputMode/DictMode/SelectMode> Rings bell.
3584 *
3585 * DisplayModeChange on: Change the display mode string.
3586 */
3587 Xsj3cEvent
3588 _Xsj3cDClearBegin(buf)
3589 Xsj3cBuf buf;
3590 {
3591 if (buf->convmode & (ConvedModeMask|InputModeMask)) {
3592 buf->n_select = 0;
3593 if (buf->candidate)
3594 Xsj3cEndCandidate(buf, OFF);
3595 buf->dict = _Xsj3cCreateDictData(buf, CLR_STATE);
3596 buf->convmode = DictModeMask;
3597 _Xsj3cFlushDictMsg(buf);
3598 if (buf->dispmodechange) {
3599 buf->dispmode = MODE_SYOUKYO;
3600 return (KEY_DICT_START|KEY_MODE_CHANGE);
3601 } else
3602 return (KEY_DICT_START);
3603 } else {
3604 #ifdef THROUGH_CONT
3605 return (KEY_BELL);
3606 #else /* THROUGH_CONT */
3607 if (buf->cntrlsame)
3608 return (KEY_BELL);
3609 else
3610 return (KEY_TEXT_CHANGE|KEY_BELL); /* dummy */
3611 #endif /* THROUGH_CONT */
3612 }
3613 }
3614
3615 /*
3616 * _Xsj3cSymbolBegin()
3617 *
3618 * <NoInputMode/InputMode/ConvedMode> Begin symbol selecting
3619 * and popup the panel.
3620 * <DictMode/SelectMode> Ring bell.
3621 *
3622 * DisplayModeChange on: Change the display mode string.
3623 */
3624 Xsj3cEvent
3625 _Xsj3cSymbolBegin(buf)
3626 Xsj3cBuf buf;
3627 {
3628 Xsj3cEvent ret = KEY_SYMBOL_START;
3629
3630 if (buf->convmode & (InputModeMask|NoInputModeMask|ConvedModeMask)) {
3631 if (buf->dispmodechange) {
3632 buf->dispmode = MODE_SYMBOL;
3633 ret |= KEY_MODE_CHANGE;
3634 }
3635 buf->selectstatus = SELECT_SYMBOL;
3636 buf->convmode = SelectModeMask;
3637 return (ret);
3638 } else {
3639 return (KEY_BELL);
3640 }
3641 }
3642
3643 /*
3644 * _Xsj3cFlushBefore()
3645 *
3646 * <InputMode/ConvedMode> Delete current segment and all segments after
3647 * current segment or cursor position.
3648 * <DictMode> Delete all yomi strings.
3649 * <SelectMode> Popdown the panel and delete strings after current segment
3650 * or cursor position.
3651 * <NoInputMode> Does nothing.
3652 *
3653 * FlushChangeSegment off: Fix strings before current cursor position
3654 * FlushChangeSegment one: Fix strings before current cursor position
3655 * and unconvert one segment.
3656 * FlushChangeSegment all: Fix strings before current cursor position
3657 * and unconvert all segments.
3658 * FlushCursorLast on: Set cursor position to bottom of segment.
3659 * FlushCursorLast off: Set cursor position to top of segment.
3660 */
3661 Xsj3cEvent
3662 _Xsj3cFlushBefore(buf)
3663 Xsj3cBuf buf;
3664 {
3665 Xsj3cEvent ret = KEY_NULL;
3666 register int i, j;
3667 int store_num;
3668 unsigned char *tmp;
3669
3670 if (buf->convmode & SelectModeMask) {
3671 if (buf->selectstatus == SELECT_HINSI || buf->curseg >= buf->segnum) {
3672 if (buf->selectstatus == SELECT_HINSI)
3673 buf->dict->status = DICT_INPUT;
3674 if (buf->dispmodechange) {
3675 buf->dispmode =
3676 (buf->dict->mode == REG_STATE ? MODE_TOROKU : MODE_SYOUKYO);
3677 return (KEY_SELECT_ABORT|KEY_MODE_CHANGE);
3678 } else
3679 return (KEY_SELECT_ABORT);
3680 } else {
3681 ret |= KEY_SELECT_END;
3682 }
3683 /* SelectMode $B$N;~$O8uJdA*Br!?5-9fA*Br(B */
3684 /* $B%&%#%s%I%&$r%]%C%W%@%&%s(B */
3685 } else if (buf->convmode & (NoInputModeMask|DictModeMask)) {
3686 #ifdef THROUGH_CONT
3687 return (KEY_NULL);
3688 #else /* THROUGH_CONT */
3689 if (buf->cntrlsame)
3690 return (KEY_NULL);
3691 else
3692 return (KEY_TEXT_CHANGE); /* dummy */
3693 #endif /* THROUGH_CONT */
3694 } else if (buf->curseg >= buf->segnum) {
3695 /* $B$"$k$$$O%+%l%s%HJ8@aHV9f$,J8@a?t$h$j(B */
3696 /* $B>.$5$/$J$$;~$O%Y%k$rLD$i$9(B */
3697 #ifdef THROUGH_CONT
3698 return (KEY_BELL);
3699 #else /* THROUGH_CONT */
3700 if (buf->cntrlsame)
3701 return (KEY_BELL);
3702 else
3703 return (KEY_TEXT_CHANGE|KEY_BELL); /* dummy */
3704 #endif /* THROUGH_CONT */
3705 }
3706
3707 if (!buf->backup) {
3708 if ((buf->backup = (Xsj3cSeg *)calloc(BUNBUFSIZ,
3709 sizeof(Xsj3cSeg))) == NULL) {
3710 Xsj3cError("Cannot allocate for backup buffers");
3711 }
3712 } else {
3713 for (i = 0; i < buf->backsegnum + 1; i++) {
3714 Xsj3cFreeSegment(buf->backup[i]);
3715 buf->backup[i] = NULL;
3716 }
3717 }
3718
3719 switch(buf->flushchange) {
3720 case ONE:
3721 ret |= _Xsj3cUnConvSeg(buf, ONE, buf->flushcurlast);
3722 _Xsj3cStoreYomi(buf, buf->input[buf->curseg], 0);
3723 break;
3724 case ALL:
3725 ret |= _Xsj3cUnConvSeg(buf, AFTER, buf->flushcurlast);
3726 _Xsj3cStoreYomi(buf, buf->input[buf->curseg], 0);
3727 buf->input[buf->curseg]->edit = SEG_EDIT;
3728 break;
3729 case OFF:
3730 default:
3731 break;
3732 }
3733
3734 ret |= (KEY_TEXT_CHANGE|KEY_TEXT_FLUSH);
3735 for (i = buf->curseg, j = 0; i < buf->segnum; i++, j++) {
3736 buf->backup[j] = buf->input[i];
3737 buf->input[i] = NULL;
3738 }
3739 buf->backsegnum = j;
3740 Xsj3cFreeSegment(buf->input[buf->segnum]);
3741 buf->input[buf->segnum] = NULL;
3742 buf->segnum = buf->curseg;
3743 for (i = 0; i < buf->curseg; i++)
3744 if (buf->input[i]->status & SEG_CONVED)
3745 buf->convedsegnum--;
3746
3747 if (buf->flushchange == OFF && (buf->backup[0]->edit & SEG_EDIT)
3748 && (buf->backup[0]->cur < buf->backup[0]->num)
3749 && buf->backup[0]->cur) {
3750 /* .FlushChangeSegment $B$,(B off $B$G%+!<%=%k$,C<$K$J$$$H$-(B */
3751
3752 buf->backup[0]->cur = buf->backup[0]->num;
3753 if ((tmp = (unsigned char *)malloc(buf->backup[0]->size
3754 * sizeof(wchar))) == NULL)
3755 Xsj3cError("Cannot allocate for temporary buffer");
3756 store_num = buf->backup[0]->cur;
3757 _Xsj3cExtractChar(buf, buf->backup[0], tmp, buf->backup[0]->cur);
3758 _Xsj3cStoreYomi(buf, buf->backup[0], 0);
3759 if (!buf->input[buf->segnum]) {
3760 if ((buf->input[buf->segnum]
3761 = (Xsj3cSeg)Xsj3cCreateSegment(buf)) == NULL) {
3762 Xsj3cError("Failed to allocate segment.");
3763 }
3764 } else
3765 Xsj3cClearSegment(buf, buf->input[buf->segnum]);
3766 _Xsj3cInsertChar(buf, buf->input[buf->segnum], tmp, store_num);
3767 _Xsj3cStoreYomi(buf, buf->input[buf->segnum], 0);
3768 buf->segnum++;
3769 free(tmp);
3770 }
3771
3772 if (buf->gakusyuu && !buf->convedsegnum)
3773 _Xsj3cClearDcid(buf);
3774 if (buf->dispmodechange) {
3775 buf->dispmode = ((buf->segnum &&
3776 buf->convedsegnum == buf->segnum) ? MODE_KANJI :
3777 (buf->convedsegnum ? MODE_EDIT : buf->inputmode));
3778 ret |= KEY_MODE_CHANGE;
3779 }
3780 return(ret);
3781 }
3782
3783 /*
3784 * _Xsj3cQuote()
3785 *
3786 * <NoInputMode/InputMode/ConvedMode/DictMode/SelectMode> Set "through flag"
3787 * and input next character unconditionally.
3788 */
3789 Xsj3cEvent
3790 _Xsj3cQuote(buf)
3791 Xsj3cBuf buf;
3792 {
3793 Xsj3cEvent ret = KEY_NULL;
3794
3795 buf->throughflg = QUOTE;
3796 if (buf->dispmodechange) {
3797 buf->dispmode = MODE_QUOTE;
3798 ret |= KEY_MODE_CHANGE;
3799 }
3800 #ifndef THROUGH_CONT
3801 if (!buf->cntrlsame)
3802 ret |= KEY_TEXT_CHANGE; /* dummy */
3803 #endif /* THROUGH_CONT */
3804 return (ret);
3805 }
3806
3807 /*
3808 * _Xsj3cBell()
3809 *
3810 * <NoInputMode/InputMode/ConvedMode/DictMode/SelectMode> Rings bell.
3811 */
3812 Xsj3cEvent
3813 _Xsj3cBell(buf)
3814 Xsj3cBuf buf;
3815 {
3816 #ifdef THROUGH_CONT
3817 return (KEY_BELL);
3818 #else /* THROUGH_CONT */
3819 if (buf->cntrlsame)
3820 return (KEY_BELL);
3821 else
3822 return (KEY_TEXT_CHANGE|KEY_BELL); /* dummy */
3823 #endif /* THROUGH_CONT */
3824 }
3825
3826 /*
3827 * _Xsj3cKana()
3828 *
3829 * <NoInputMode/InputMode/ConvedMode/DictMode/SelectMode>
3830 * Toggle keyboard input mode between ASCII and Kana.
3831 *
3832 * KanaInputOnly on: Set toggle on in initializing.
3833 */
3834 Xsj3cEvent
3835 _Xsj3cKana(buf)
3836 Xsj3cBuf buf;
3837 {
3838 Xsj3cEvent ret = KEY_NULL;
3839
3840 if ((buf->convmode & DictModeMask)||((buf->convmode & SelectModeMask)
3841 && buf->selectstatus == SELECT_HINSI)) {
3842 buf->dict->seg->n_roma = 0;
3843 buf->dict->seg->n_kana = -1;
3844 *buf->dict->seg->oldstr = '\0';
3845 *buf->dict->seg->str = '\0';
3846 buf->dict->seg->sp = buf->dict->seg->str;
3847 }
3848 if (buf->convmode & ~NoInputModeMask) {
3849 buf->input[buf->curseg]->n_roma = 0;
3850 buf->input[buf->curseg]->n_kana = -1;
3851 *buf->input[buf->curseg]->oldstr = '\0';
3852 *buf->input[buf->curseg]->str = '\0';
3853 buf->input[buf->curseg]->sp = buf->input[buf->curseg]->str;
3854 }
3855 if (buf->kanaonly)
3856 buf->kanaonly = OFF;
3857 else
3858 buf->kanaonly = ON;
3859 #ifndef THROUGH_CONT
3860 if (!buf->cntrlsame)
3861 ret |= KEY_TEXT_CHANGE; /* dummy */
3862 #endif /* THROUGH_CONT */
3863 return ret;
3864 }
3865
3866 /*
3867 * _Xsj3cSjrc()
3868 *
3869 * <NoInputMode/InputMode/ConvedMode/DictMode/SelectMode> Reset customize.
3870 *
3871 * NextRCFile filename: Set file name to read next.
3872 */
3873 Xsj3cEvent
3874 _Xsj3cSjrc(buf)
3875 Xsj3cBuf buf;
3876 {
3877 Xsj3cEvent ret = (KEY_TEXT_CHANGE|KEY_MODE_CHANGE);
3878 register int i;
3879
3880 if (buf->dispmodechange) {
3881 ret |= KEY_MODE_CHANGE;
3882 buf->dispmode = buf->inputmode;
3883 }
3884 switch(buf->convmode) {
3885 case ConvedModeMask:
3886 buf->n_select = 0;
3887 if (buf->candidate)
3888 Xsj3cEndCandidate(buf, OFF);
3889 case InputModeMask:
3890 break;
3891 case SelectModeMask:
3892 buf->n_select = 0;
3893 if (buf->flusheconv)
3894 ret |= KEY_SELECT_END;
3895 else
3896 ret |= KEY_SELECT_ABORT;
3897 if (buf->candidate)
3898 Xsj3cEndCandidate(buf, OFF);
3899 break;
3900 case DictModeMask:
3901 ret |= KEY_DICT_END;
3902 break;
3903 case NoInputModeMask:
3904 default:
3905 break;
3906 }
3907 if (buf->flusheconv) {
3908 ret |= KEY_TEXT_FIXED;
3909 if (buf->gakusyuu)
3910 _Xsj3cFlushDcid(buf);
3911 } else {
3912 for (i = 1; i < buf->segnum + 1; i++) {
3913 Xsj3cFreeSegment(buf->input[i]);
3914 buf->input[i] = NULL;
3915 }
3916 if (buf->input[0])
3917 Xsj3cClearSegment(buf, buf->input[0]);
3918 buf->segnum = 0;
3919 buf->curseg = 0;
3920 }
3921 if (buf->setnormal) {
3922 free(buf->setnormal);
3923 buf->setnormal = NULL;
3924 }
3925 if (buf->throughnext) {
3926 free(buf->throughnext);
3927 buf->throughnext = NULL;
3928 }
3929 Xsj3cRCInit(buf, NULL, NULL);
3930 return ret;
3931 }
3932
3933 /*
3934 * _Xsj3cKill()
3935 *
3936 * <NoInputMode/InputMode/ConvedMode/DictMode/SelectMode> Exit.
3937 */
3938 Xsj3cEvent
3939 _Xsj3cKill(buf)
3940 Xsj3cBuf buf;
3941 {
3942 /* Not Yet */
3943 return (KEY_NULL);
3944 }
3945
3946 /*
3947 * _Xsj3cNull()
3948 *
3949 * <NoInputMode/InputMode/ConvedMode/DictMode/SelectMode> Does nothing.
3950 */
3951 Xsj3cEvent
3952 _Xsj3cNull(buf)
3953 Xsj3cBuf buf;
3954 {
3955 return (KEY_NULL|KEY_CONTROL);
3956 }
3957
3958 /*
3959 * _Xsj3cIgnore()
3960 *
3961 * <NoInputMode/InputMode/ConvedMode/DictMode/SelectMode> Does nothing.
3962 */
3963 Xsj3cEvent
3964 _Xsj3cIgnore(buf)
3965 Xsj3cBuf buf;
3966 {
3967 return (KEY_NULL|KEY_CONTROL);
3968 }