1 /*
2 * Copyright (c) 1994 Sony Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sublicense, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 * IN NO EVENT SHALL SONY CORPORATION BE LIABLE FOR ANY CLAIM,
19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
21 * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 *
23 * Except as contained in this notice, the name of Sony Corporation
24 * shall not be used in advertising or otherwise to promote the sale, use
25 * or other dealings in this Software without prior written authorization
26 * from Sony Corporation.
27 *
28 */
29
30 /*
31 * $SonyRCSfile: douon.c,v $
32 * $SonyRevision: 1.2 $
33 * $SonyDate: 1996/02/23 11:04:02 $
34 */
35
36
37
38 #include <stdlib.h>
39 #include <string.h>
40 #include "common.h"
41 #include "key.h"
42 #include "wchar16.h"
43
44 #include "sj3.h"
45
46 #define DNUM 5
47
48 static int Dcount;
49 static int Dpoint;
50 static struct douon_sj3 HenkanDouon[DOUON_N];
51 static wchar16_t Dkanji[BUFFLENGTH * 2];
52
53 int
SJ_getdouon(wchar16_t * s,struct douon_sj3 * d,int n,int choice,int reconv)54 SJ_getdouon(wchar16_t *s, struct douon_sj3 *d, int n, int choice, int reconv)
55 {
56 int len;
57
58 Dcount = SJ2_getdouon (s, d, n, choice, reconv);
59
60
61 if (Dcount < 0 && !dconnect(1))
62 Dcount = SJ2_getdouon (s, d, n, choice, reconv);
63
64 if (Dcount <= 0) {
65 Dcount = 1;
66 len = wslen (s);
67 Strncpy ((char *)d[0].ddata, s, len);
68 d[0].dlen = wcbyte(s);
69 d[0].wlen = len;
70 return(0);
71 } else
72 return(1);
73 }
74
75
76
77 void
exec_douon()78 exec_douon()
79 {
80 Conversion *cv;
81 int val;
82
83 cv = GetConversion ();
84 if (cv->CurBun == -1) {
85 cv->CurBun = 0;
86 Rdisp ();
87 }
88 cv->PreBun = cv->CurBun;
89 if (cv->Bkettei[cv->CurBun] & Bmuhenkan)
90 val = Sdouon (2);
91 else
92 val = Sdouon (1);
93 if (!val)
94 Rdisp ();
95 }
96
97 void
wrap_douon(int back)98 wrap_douon(int back)
99 {
100 Conversion *cv;
101 int val;
102
103 cv = current_conversion;
104 if (cv->CurBun == -1) {
105 cv->CurBun = 0;
106 Rdisp ();
107 }
108 cv->PreBun = cv->CurBun;
109 if (cv->Dflag == cv->CurBun)
110 val = Rdouon (back);
111 else {
112 val = Sdouon (2);
113 cv->Dflag = cv->CurBun;
114 }
115 if (!val)
116 Rdisp ();
117 }
118
119
120
121 int
Cdouon(wchar16_t * yomi,int gnum)122 Cdouon(wchar16_t *yomi, int gnum)
123 {
124
125
126 int i, j;
127 int len;
128 wchar16_t *s;
129 int dispnum;
130 int num;
131 int displen;
132 int base;
133 char tmp[BUFFLENGTH], tmp2[BUFFLENGTH * 2];
134 wchar16_t wtmp[BUFFLENGTH], wtmp2[BUFFLENGTH * 2];
135
136 int gakusyuu;
137 u_short row, col;
138 Conversion *cv;
139
140 cv = current_conversion;
141
142 gakusyuu = SJ_getdouon (yomi, HenkanDouon, gnum, 0, 0);
143
144 dispnum = DNUM;
145 if (dispnum > Dcount)
146 j = Dcount;
147 else
148 j = dispnum;
149 len = 0;
150 for (i = 0 ; i < j ; i ++)
151 len += HenkanDouon[i].dlen;
152 len /= j;
153 if (len < 1)
154 len = 1;
155 len += 6;
156 snprintf (tmp, sizeof(tmp), "%d/%d ", Dcount, Dcount);
157 displen = cv->column - strlen (tmp) - 1;
158 if (displen < 1)
159 displen = 1;
160 num = displen / len;
161 if (num < 1)
162 num = 1;
163 if (num < dispnum && num > 0)
164 dispnum = num;
165
166 for (i = 0 ; ; ) {
167 if (i >= Dcount)
168 i = 0;
169 StartGuide (&row, &col);
170 Clear_EOL ();
171 base = i;
172
173 snprintf (tmp, sizeof(tmp), "%d/%d", i + 1, Dcount);
174 (void) mbstowcs(wtmp, tmp, BUFFLENGTH);
175 printR (wtmp);
176 put_space (1);
177
178 for (j = 0 ; j < dispnum ; j ++, i ++) {
179 if (i >= Dcount)
180 break;
181 len = HenkanDouon[i].dlen;
182
183 if (len > displen)
184 len = displen;
185
186 s = (wchar16_t *)HenkanDouon[i].ddata;
187 Strncpy (wtmp, s, HenkanDouon[i].wlen);
188 wtmp[HenkanDouon[i].wlen] = '\0';
189 (void) wcstombs(tmp, wtmp, BUFFLENGTH);
190 snprintf (tmp2, sizeof(tmp2), "[%d] %s ", j+1, tmp);
191 (void) mbstowcs(wtmp2, tmp2, BUFFLENGTH);
192 SJ_print (wtmp2);
193 }
194
195 EndGuide (row, col);
196 Flush ();
197 num = Dselect (j);
198
199
200 if (num == 0)
201 continue;
202
203
204 else if (num == -1) {
205 if ((i >= Dcount) && ((Dcount % dispnum) != 0))
206 i = Dcount - (Dcount % dispnum);
207 else
208 i -= dispnum;
209 i -= dispnum;
210 if (i < 0) {
211 if (Dcount > dispnum) {
212 if ((Dcount % dispnum) == 0)
213 i = Dcount - dispnum;
214 else
215 i = Dcount - (Dcount % dispnum);
216 }
217 else
218 i = 0;
219 }
220 continue;
221 }
222
223
224 else if (num > j) {
225 disp_mode ();
226 return (FALSE);
227 }
228
229
230 else
231 break;
232 }
233
234 disp_mode ();
235
236 Dpoint = base + num - 1;
237 len = HenkanDouon[Dpoint].dlen;
238 s = (wchar16_t *)HenkanDouon[Dpoint].ddata;
239 Strncpy (Dkanji, s, HenkanDouon[Dpoint].wlen);
240 Dkanji[HenkanDouon[Dpoint].wlen] = '\0';
241 if (HenkanDouon[Dpoint].valid)
242 PushGD (gnum, &HenkanDouon[Dpoint].dcid);
243
244 if (gakusyuu)
245 if (HenkanDouon[Dpoint].valid)
246 SJ2_study (&HenkanDouon[Dpoint].dcid);
247 else
248 SJ2_toroku(yomi, HenkanDouon[Dpoint].ddata, SJ3_H_NRMNOUN);
249
250 return (TRUE);
251 }
252
253 int
Dselect(int lim)254 Dselect(int lim)
255 {
256 int c, num;
257 char s[2];
258
259 SaveConversion ();
260 while ((c = inkey ()) != EOF) {
261 if (AnotherConversion ()) {
262 unget_key (c);
263 break;
264 }
265 if (keyvalue == KEY_KETTEI)
266 break;
267 else if (keyvalue == KEY_HENKAN || keyvalue == KEY_RIGHT)
268 return (0);
269 else if (c == ' ')
270 return (0);
271 else if (keyvalue == KEY_MUHENKAN || keyvalue == KEY_LEFT
272 || is_bsdel (c))
273 return (-1);
274 else if (WcIsASCII(c) && isdigit (WcLowByte(c))) {
275 *s = c;
276 s[1] = '\0';
277 num = atoi (s);
278 if (num > 0 && num <= lim)
279 return (num);
280 }
281 else if (keyvalue != KEY_NORMAL)
282 break;
283 else if (keyvalue == KEY_NORMAL && IsESC (c))
284 break;
285 }
286 return (lim + 1);
287 }
288
289
290 void
Gdouon(wchar16_t * yomi,int num,int choice,int reconv)291 Gdouon(wchar16_t *yomi, int num, int choice, int reconv)
292 {
293
294
295 int len;
296 wchar16_t *s;
297
298 SJ_getdouon (yomi, HenkanDouon, num, choice, reconv);
299
300 Dpoint = 0;
301 len = HenkanDouon[Dpoint].wlen;
302 s = (wchar16_t *)HenkanDouon[Dpoint].ddata;
303 Strncpy (Dkanji, s, len);
304 Dkanji[len] = '\0';
305 if (HenkanDouon[Dpoint].valid)
306 PushGD (num, &HenkanDouon[Dpoint].dcid);
307 }
308
309 int
Sdouon(int Choice)310 Sdouon(int Choice)
311 {
312 Conversion *cv;
313 int i, j;
314 int len;
315 wchar16_t yomi[BUFFLENGTH * 2];
316 int count;
317
318 cv = current_conversion;
319 count = 0;
320 if (Choice == 0)
321 i = cv->PreBun;
322 else
323 i = cv->CurBun;
324 top:
325 if ((len = load_bun(i, yomi, MODE_ZHIRA)) <= 0) {
326 cv->Bkettei[i] |= Bmuhenkan;
327 cv->Bkettei[i] &= ~Bhenkan;
328 cv->Pkettei[i] = MODE_ZHIRA;
329 *Dkanji = '\0';
330 goto null;
331 }
332 else if (len > DLEN) {
333 cv->Bkettei[i] |= Bmuhenkan;
334 cv->Bkettei[i] &= ~Bhenkan;
335 *Dkanji = '\0';
336 goto null;
337 }
338 else if (Choice == 0 && (cv->Bkettei[i] & Bmuhenkan)) {
339 goto tail;
340 }
341 else {
342 cv->Bkettei[i] |= Bhenkan;
343 cv->Bkettei[i] &= ~Bmuhenkan;
344 }
345
346 if (Choice == 1) {
347 if (Cdouon (yomi, i) == FALSE)
348 return (1);
349 cv->Pkettei[i] = MODE_ZHIRA;
350 }
351 else if (Choice == 2) {
352 Gdouon (yomi, i, 0, 0);
353 }
354 else if (Choice == 3)
355 Gdouon (yomi, i, count, 1);
356 else
357 Gdouon (yomi, i, count, 0);
358 null:
359 len = wslen (Dkanji);
360
361 if (!(cv->Bkettei[i] & Bedit)) {
362 if (cv->Enum >= MAXENUM)
363 return (1);
364 j = cv->Enum ++;
365 cv->Edit[i] = j;
366 cv->Epoint[j] = &(cv->Ebuff[cv->e_point]);
367 cv->e_point += DLEN;
368 }
369 else
370 j = cv->Edit[i];
371 if (0 < len && len <= DLEN) {
372 cv->Bkettei[i] |= Bedit;
373 cv->Pkettei[i] = MODE_ZHIRA;
374 }
375 cv->Elen[j] = len;
376 wscpy (cv->Epoint[j], Dkanji);
377
378 tail:
379 if (Choice == 0 && i != cv->CurBun) {
380 i = cv->CurBun;
381 goto top;
382 }
383 if (cv->PreBun == cv->Bnum)
384 cv->Bkettei[cv->Bnum] = Bend;
385 return (0);
386 }
387
388
389
390 int
Rdouon(int back)391 Rdouon(int back)
392 {
393 Conversion *cv;
394 int i, j;
395 int len;
396 wchar16_t *s;
397
398 cv = current_conversion;
399 if (Dcount > 0) {
400 if (back) {
401 Dpoint --;
402 if (Dpoint < 0)
403 Dpoint = Dcount - 1;
404 }
405 else {
406 Dpoint ++;
407 if (Dpoint >= Dcount)
408 Dpoint = 0;
409 }
410 len = HenkanDouon[Dpoint].wlen;
411 s = (wchar16_t *)HenkanDouon[Dpoint].ddata;
412 Strncpy (Dkanji, s, len);
413 Dkanji[len] = '\0';
414
415 i = cv->CurBun;
416 j = cv->Edit[i];
417 cv->Elen[j] = len;
418 wscpy (cv->Epoint[j], Dkanji);
419 return (0);
420 }
421 return (1);
422 }
423
424 int
Bkanji(wchar16_t * kanji)425 Bkanji(wchar16_t *kanji)
426 {
427 Conversion *cv;
428 int i;
429 int plen, len;
430 wchar16_t *s;
431
432 cv = current_conversion;
433 s = kanji;
434 *s = '\0';
435 plen = 0;
436 for (i = 0 ; i < cv->Bnum ; i ++) {
437 if ((len = Bstr (i, s)) <= 0)
438 continue;
439 s += len;
440 plen += len;
441 }
442 return(plen);
443 }
444
445 struct studyrec Gdata[BUFFLENGTH];
446
447 void
PushGD(int num,struct studyrec * wordid)448 PushGD(int num, struct studyrec *wordid)
449 {
450 Gdata[num] = *wordid;
451 }
452
453 void
cl_gakusyuu()454 cl_gakusyuu()
455 {
456 Conversion *cv;
457 int i, j;
458 int o_point, n_point;
459
460 cv = current_conversion;
461 for (i = 0 ; i < cv->Bnum ; i ++) {
462 if (cv->OrgPlen[i] != cv->Plen[i]) {
463 o_point = n_point = 0;
464 j = i;
465 while (j < cv->Bnum) {
466 o_point += cv->OrgPlen[j];
467 n_point += cv->Plen[j];
468 j ++;
469 if (o_point == n_point)
470 break;
471 }
472 j--;
473 check_and_gakusyuu (i, j);
474 i = j;
475 }
476 }
477 }
478
479 void
check_and_gakusyuu(int m,int n)480 check_and_gakusyuu(int m, int n)
481 {
482 Conversion *cv;
483 int i, j;
484
485 cv = current_conversion;
486 i = m;
487 j = i + 1;
488 while (j <= n && j < cv->Bnum) {
489 if (cv->Bkettei[i] & Bedit && !(cv->Bkettei[i] & Bmuhenkan))
490 go_gakusyuu (i);
491 i ++;
492 j ++;
493 }
494 }
495
496 void
go_gakusyuu(int n)497 go_gakusyuu(int n)
498 {
499 Conversion *cv;
500 int i, j;
501 wchar16_t yomi1[BUFFLENGTH], yomi2[BUFFLENGTH];
502 struct studyrec *gdatap;
503 int len;
504
505 cv = current_conversion;
506 i = n;
507 j = i + 1;
508
509 if (cv->Pedited[i] == 1 || cv->Pedited[j] == 1)
510 return;
511
512
513 if ((len = load_bun(i, yomi1, MODE_ZHIRA)) <= 0 && len > DLEN)
514 return;
515 if ((len = load_bun(j, yomi2, MODE_ZHIRA)) > DLEN)
516 return;
517
518
519 if (len <= 0)
520 gdatap = NULL;
521 else
522 gdatap = &Gdata[j];
523 SJ2_clstudy (yomi1, yomi2, gdatap);
524 }
525