comparison lib/CcWnn.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 983aff0dcf18
comparison
equal deleted inserted replaced
-1:000000000000 0:92745d501b9a
1 #ifndef lint
2 static char *rcsid = "$Id: CcWnn.c,v 1.59 2002/01/10 15:51:47 ishisone Exp $";
3 #endif
4 /*
5 * Copyright (c) 1990 Software Research Associates, Inc.
6 *
7 * Permission to use, copy, modify, and distribute this software and its
8 * documentation for any purpose and without fee is hereby granted, provided
9 * that 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 Software Research Associates not be
12 * used in advertising or publicity pertaining to distribution of the
13 * software without specific, written prior permission. Software Research
14 * Associates makes no representations about the suitability of this software
15 * for any purpose. It is provided "as is" without express or implied
16 * warranty.
17 *
18 * Author: Makoto Ishisone, Software Research Associates, Inc., Japan
19 */
20
21 #include <X11/IntrinsicP.h>
22 #include <X11/StringDefs.h>
23 #include <X11/Xmu/Atoms.h>
24 #if XtSpecificationRelease > 4
25 #include <X11/Xfuncs.h>
26 #endif
27 #include "CcWnnP.h"
28 #include "CachedAtom.h"
29 #include "IOECall.h"
30
31 #define DEBUG_VAR debug_CcWnn
32 #include "DebugPrint.h"
33
34 static XtResource resources[] = {
35 #define offset(field) XtOffset(CcWnnObject, ccWnn.field)
36 { XtNconfirmFunc, XtCFunction, XtRPointer, sizeof(int (*)()),
37 offset(confirmfunc), XtRPointer, (XtPointer)NULL },
38 { XtNconfirmData, XtCConfirmData, XtRPointer, sizeof(XtPointer),
39 offset(confirmdata), XtRPointer, (XtPointer)NULL },
40 { XtNjserver, XtCJserver, XtRString, sizeof(String),
41 offset(jservername), XtRString, NULL },
42 { XtNjserver2nd, XtCJserver, XtRString, sizeof(String),
43 offset(jservername2), XtRString, NULL },
44 { XtNwnnEnvname, XtCWnnEnvname, XtRString, sizeof(String),
45 offset(wnnenvname), XtRString, NULL },
46 { XtNwnnEnvrc, XtCWnnEnvrc, XtRString, sizeof(String),
47 offset(wnnenvrcfile), XtRString, NULL },
48 { XtNwnnEnvrc4, XtCWnnEnvrc, XtRString, sizeof(String),
49 offset(wnnenvrcfile4), XtRString, NULL },
50 { XtNwnnEnvrc6, XtCWnnEnvrc, XtRString, sizeof(String),
51 offset(wnnenvrcfile6), XtRString, NULL },
52 { XtNwnnOverrideEnv, XtCWnnOverrideEnv, XtRBoolean, sizeof(Boolean),
53 offset(wnnoverrideenv), XtRString, "false" },
54 { XtNccdef, XtCCcdef, XtRString, sizeof(String),
55 offset(ccdeffile), XtRString, NULL },
56 { XtNwnnEnv, XtCWnnEnv, XtRWnnEnv, sizeof(struct wnn_buf *),
57 offset(wnnbuf), XtRWnnEnv, NULL},
58 { XtNccRule, XtCCcRule, XtRCcRule, sizeof(ccRule),
59 offset(ccrule), XtRCcRule, NULL},
60 { XtNsaveInterval, XtCSaveInterval, XtRInt, sizeof(int),
61 offset(saveinterval), XtRImmediate, 0 },
62 #undef offset
63 };
64
65 static void ClassInitialize();
66 static int buildSymbolList();
67 static void Initialize(), Destroy();
68 static Boolean SetValues();
69 static int InputEvent();
70 static ICString *GetMode();
71 static int CursorPos();
72 static int NumSegments();
73 static ICString *GetSegment();
74 static int CompareSegment();
75 static ICString *GetItemList();
76 static int SelectItem();
77 static int ConvertedString();
78 static int ClearConversion();
79 static ICString *GetAuxSegments();
80 static int PreeditString();
81 static int StatusString();
82
83 CcWnnClassRec ccWnnClassRec = {
84 { /* object fields */
85 /* superclass */ (WidgetClass) &inputConvClassRec,
86 /* class_name */ "CcWnn",
87 /* widget_size */ sizeof(CcWnnRec),
88 /* class_initialize */ ClassInitialize,
89 /* class_part_initialize */ NULL,
90 /* class_inited */ FALSE,
91 /* initialize */ Initialize,
92 /* initialize_hook */ NULL,
93 /* obj1 */ NULL,
94 /* obj2 */ NULL,
95 /* obj3 */ 0,
96 /* resources */ resources,
97 /* num_resources */ XtNumber(resources),
98 /* xrm_class */ NULLQUARK,
99 /* obj4 */ FALSE,
100 /* obj5 */ FALSE,
101 /* obj6 */ FALSE,
102 /* obj7 */ FALSE,
103 /* destroy */ Destroy,
104 /* obj8 */ NULL,
105 /* obj9 */ NULL,
106 /* set_values */ SetValues,
107 /* set_values_hook */ NULL,
108 /* obj10 */ NULL,
109 /* get_values_hook */ NULL,
110 /* obj11 */ NULL,
111 /* version */ XtVersion,
112 /* callback_private */ NULL,
113 /* obj12 */ NULL,
114 /* obj13 */ NULL,
115 /* obj14 */ NULL,
116 /* extension */ NULL
117 },
118 { /* inputConv fields */
119 /* InputEvent */ InputEvent,
120 /* GetMode */ GetMode,
121 /* CursorPos */ CursorPos,
122 /* NumSegments */ NumSegments,
123 /* GetSegment */ GetSegment,
124 /* CompareSegment */ CompareSegment,
125 /* GetItemList */ GetItemList,
126 /* SelectItem */ SelectItem,
127 /* GetConvetedString */ ConvertedString,
128 /* ClearConversion */ ClearConversion,
129 /* GetAuxSegments */ GetAuxSegments,
130 /* SupportMultipleObjects */ True,
131 /* GetTriggerKeys */ XtInheritGetTriggerKeys,
132 /* num_trigger_keys */ 0,
133 /* trigger_keys */ NULL,
134 /* GetPreeditString */ PreeditString,
135 /* GetStatusString */ StatusString,
136 /* NoMoreObjects */ False,
137 },
138 { /* ccWnn fields */
139 /* foo */ 0,
140 }
141 };
142
143 WidgetClass ccWnnObjectClass = (WidgetClass)&ccWnnClassRec;
144
145 /* cconv function table */
146 static char *fepfunctbl[] = {
147 "convert",
148 "convert-or-fix1",
149 "convert-or-space",
150 "convert-or-sendback",
151 "convert-s",
152 "unconvert",
153 "next",
154 "next-s",
155 "previous",
156 "previous-s",
157 "forward",
158 "backward",
159 "move-top",
160 "move-bottom",
161 "clear",
162 "expand",
163 "expand-s",
164 "shrink",
165 "shrink-s",
166 "expand-noconv",
167 "expand-noconv-s",
168 "shrink-noconv",
169 "shrink-noconv-s",
170 "fix",
171 "fix2",
172 "fix-or-cr",
173 "fix-or-sendback",
174 "to-hankaku",
175 "to-zenkaku",
176 "to-hiragana",
177 "to-katakana",
178 "backspace",
179 "delete",
180 "kill-line",
181 "carriage-return",
182 "fix-and-write",
183 "beep",
184 "jiscode-begin",
185 "jiscode-end",
186 "kutencode-begin",
187 "kutencode-end",
188 "symbol-input",
189 "end-conversion",
190 "send-back",
191 "convert-move-top-or-sendback",
192 "convert-move-top-or-space",
193 "clear-or-cancel",
194 "backspace-or-cancel",
195 "delete-or-cancel",
196 "convert-next-or-move-top-or-sendback",
197 "convert-next-or-move-top-or-space",
198 "select",
199 "select-s",
200 "register",
201 };
202 #define FTSIZE (sizeof(fepfunctbl) / sizeof(char *))
203
204 static void convert();
205 static void convert_f1();
206 static void convert_sb();
207 static void convert_sp();
208 static void convert_s();
209 static void convert_mt_sb();
210 static void convert_mt_sp();
211 static void unconvert();
212 static void egg_select();
213 static void egg_select_s();
214
215 static void move_forward();
216 static void move_backward();
217 static void move_top();
218 static void move_bottom();
219
220 static void cand_next();
221 static void cand_next_s();
222 static void cand_next_mt_sb();
223 static void cand_next_mt_sp();
224 static void cand_prev();
225 static void cand_prev_s();
226
227 static void expand_cl();
228 static void expand_cl_s();
229 static void shrink_cl();
230 static void shrink_cl_s();
231 static void expand_cl2();
232 static void expand_cl2_s();
233 static void shrink_cl2();
234 static void shrink_cl2_s();
235
236 static void clear_buffer();
237 static void clear_c();
238
239 static void sel_top();
240 static void sel_bottom();
241 static void sel_forward();
242 static void sel_backward();
243 static void sel_next();
244 static void sel_prev();
245 static void sel_select();
246 static void sel_abort();
247
248 static void fix();
249 static void fix1();
250 static void fix_cr();
251 static void fix_sb();
252
253 static void hankaku();
254 static void zenkaku();
255
256 static void hiragana();
257 static void katakana();
258
259 static void backspace();
260 static void backspace_c();
261 static void delete();
262 static void delete_c();
263 static void kill_line();
264
265 static void bell();
266 static void beep();
267 static void carriageret();
268 static void jiscode_begin();
269 static void jiscode_end();
270 static void kuten_begin();
271 static void kuten_end();
272
273 static void sym_input();
274 static void convend();
275 static void send_back();
276 static void register_word();
277
278 /* cconv function dispatch table */
279 static void (*functable[][3])() = {
280 /* Function Name Normal-mode selection-mode symbol-mode */
281 /* convert */ convert, sel_forward, beep,
282 /* convert-or-fix1 */ convert_f1, sel_forward, beep,
283 /* convert-or-sendback*/convert_sb, sel_forward, beep,
284 /* convert-or-space */ convert_sp, sel_forward, beep,
285 /* convert-s */ convert_s, sel_forward, beep,
286 /* unconvert */ unconvert, beep, beep,
287 /* next */ cand_next, sel_next, sel_next,
288 /* next-s */ cand_next_s, sel_next, sel_next,
289 /* previous */ cand_prev, sel_prev, sel_prev,
290 /* previous-s */ cand_prev_s, sel_prev, sel_prev,
291 /* forward */ move_forward, sel_forward, sel_forward,
292 /* backward */ move_backward, sel_backward, sel_backward,
293 /* move-top */ move_top, sel_top, sel_top,
294 /* move-bottom */ move_bottom, sel_bottom, sel_bottom,
295 /* clear */ clear_buffer, clear_buffer, clear_buffer,
296 /* expand */ expand_cl, expand_cl, beep,
297 /* expand-s */ expand_cl_s, expand_cl_s, beep,
298 /* shrink */ shrink_cl, shrink_cl, beep,
299 /* shrink-s */ shrink_cl_s, shrink_cl_s, beep,
300 /* expand-noconv */ expand_cl2, expand_cl2, beep,
301 /* expand-noconv-s */ expand_cl2_s, expand_cl2_s, beep,
302 /* shrink-noconv */ shrink_cl2, shrink_cl2, beep,
303 /* shrink-noconv-s */ shrink_cl2_s, shrink_cl2_s, beep,
304 /* fix */ fix, fix, fix,
305 /* fix2 */ fix, fix, fix,
306 /* fix-or-cr */ fix_cr, sel_select, sel_select,
307 /* fix-or-sendback */ fix_sb, sel_select, sel_select,
308 /* to-hankaku */ hankaku, hankaku, beep,
309 /* to-zenkaku */ zenkaku, zenkaku, beep,
310 /* to-hiragana */ hiragana, hiragana, beep,
311 /* to-katakana */ katakana, katakana, beep,
312 /* backspace */ backspace, backspace, backspace,
313 /* delete */ delete, delete, delete,
314 /* kill-line */ kill_line, kill_line, kill_line,
315 /* carriage-return */ carriageret, sel_select, sel_select,
316 /* fix-and-write */ fix, beep, beep,
317 /* beep */ bell, bell, bell,
318 /* jiscode-begin */ jiscode_begin, beep, beep,
319 /* jiscode-end */ jiscode_end, beep, beep,
320 /* kutencode-begin */ kuten_begin, beep, beep,
321 /* kutencode-end */ kuten_end, beep, beep,
322 /* symbol-input */ sym_input, beep, sel_abort,
323 /* end-conversion */ convend, convend, convend,
324 /* send-back */ send_back, send_back, send_back,
325 /* convert-move-..sb*/ convert_mt_sb, sel_forward, beep,
326 /* convert-move-..sp*/ convert_mt_sp, sel_forward, beep,
327 /* clear-or-cancel */ clear_c, clear_c, clear_c,
328 /* backspace-or-cancel */ backspace_c, backspace_c, backspace_c,
329 /* delete-or-cancel */ delete_c, delete_c, delete_c,
330 /* convert-next-..sb */ cand_next_mt_sb, sel_forward, beep,
331 /* convert-next-..sp */ cand_next_mt_sp, sel_forward, beep,
332 /* select */ egg_select, beep, beep,
333 /* select-s */ egg_select_s, beep, beep,
334 /* register */ register_word, beep, beep,
335 };
336
337 static ICString *SymbolList;
338 static int NumSymbols;
339
340 static void ccInitialize();
341 static void jcInitialize();
342 static void createEnvError();
343 static int createConfirm();
344
345 static int funcDispatch();
346 static void defAction();
347 static void insChar();
348 static void delChar();
349 static void autoFix();
350
351 static void startSelection();
352 static void moveSelection();
353 static int endSelection();
354 static int insertSelection();
355
356 static int getSymbol();
357
358 static void normalState();
359
360 static void allocCandlist();
361 static void allocStrdata();
362 static void getAllCandidates();
363
364 static void addObject();
365 static void deleteObject();
366 static void serverDead();
367
368 static void saveData();
369 static void restoreData();
370
371 static void ioeCallback();
372
373 static CcWnnObject findSelectionObj();
374
375 static Boolean convertSelection();
376 static void saveYomiAndKanji();
377
378 static void
379 ClassInitialize()
380 {
381 /* symbollist $B$r@_Dj(B */
382 NumSymbols = buildSymbolList(&SymbolList);
383 /* I/O error $B%3!<%k%P%C%/4X?t$N@_Dj(B */
384 XIOESet(ioeCallback, (XPointer)NULL);
385 }
386
387 static int
388 buildSymbolList(listp)
389 ICString **listp;
390 {
391 static struct symgroup {
392 int first;
393 int last;
394 } symgroups[] = {
395 { 0xa1a1, 0xa2ae }, /* '$B!!(B' - '$B".(B' */
396 { 0xa2ba, 0xa2c1 }, /* '$B":(B' - '$B"A(B' */
397 { 0xa2ca, 0xa2d0 }, /* '$B"J(B' - '$B"P(B' */
398 { 0xa2dc, 0xa2ea }, /* '$B"\(B' - '$B"j(B' */
399 { 0xa2f2, 0xa2f9 }, /* '$B"r(B' - '$B"y(B' */
400 { 0xa2fe, 0xa2fe }, /* '$B"~(B' */
401 { 0xa4ee, 0xa4ee }, /* '$B$n(B' */
402 { 0xa4f0, 0xa4f1 }, /* '$B$p(B', '$B$q(B' */
403 { 0xa5ee, 0xa5ee }, /* '$B%n(B' */
404 { 0xa5f0, 0xa5f1 }, /* '$B%p(B', '$B%q(B' */
405 { 0xa5f4, 0xa5f6 }, /* '$B%t(B', '$B%u(B', '$B%v(B' */
406 { 0xa6a1, 0xa6b8 }, /* '$B&!(B' - '$B&8(B' */
407 { 0xa6c1, 0xa6d8 }, /* '$B&A(B' - '$B&X(B' */
408 { 0xa7a1, 0xa7c1 }, /* '$B'!(B' - '$B'A(B' */
409 { 0xa7d1, 0xa7f1 }, /* '$B'Q(B' - '$B'q(B' */
410 { 0xa8a1, 0xa8c0 }, /* '$B(!(B' - '$B(@(B' */
411 { -1, -1 }
412 };
413 struct symgroup *sgp;
414 Cardinal nsyms;
415 ICString *symlist, *sp;
416 wchar *buf, *p;
417
418 for (nsyms = 0, sgp = symgroups; sgp->first > 0; sgp++) {
419 #define LINEAR_INDEX(c) (((((c)>>8)&0x7f)*94)+((c)&0x7f))
420 nsyms += LINEAR_INDEX(sgp->last) - LINEAR_INDEX(sgp->first) + 1;
421 }
422
423 symlist = (ICString *)XtMalloc(nsyms * sizeof(ICString));
424 buf = (wchar *)XtMalloc(nsyms * sizeof(wchar));
425
426 sp = symlist;
427 p = buf;
428 for (sgp = symgroups; sgp->first > 0; sgp++) {
429 int i;
430 #define NEXT_CHAR(c) ((((c)&0xff)>0xfd)?(((c)&0xff00)+0x1a1):((c)+1))
431 for (i = sgp->first; i <= sgp->last; i = NEXT_CHAR(i)) {
432 sp->nchars = 1;
433 sp->nbytes = sizeof(wchar);
434 sp->data = (char *)p;
435 sp->attr = ICAttrNormalString;
436 sp++;
437 *p++ = i;
438 }
439 }
440
441 *listp = symlist;
442 return nsyms;
443 }
444
445 static int
446 InputEvent(w, event)
447 Widget w;
448 XEvent *event;
449 {
450 CcWnnObject obj = (CcWnnObject)w;
451 int sendback;
452 int ret = 0;
453 wchar *curmode;
454
455 if (event->type != KeyPress /*&& event->type != KeyRelease*/) return 0;
456
457 /* $B%$%Y%s%H$r%/%i%$%"%s%H$KAw$jJV$9$+$I$&$+$NH=Dj$=$N(B 1 */
458 sendback = (NumSegments(w) == 0 && obj->ccWnn.state == normal_state);
459
460 obj->ccWnn.sendbackevent = False;
461 obj->ccWnn.fixperformed = False;
462 obj->ccWnn.textchanged = False;
463
464 /*
465 * $B$b$7!"(Bwnnbuf $B$,L$3MF@$G$"$k$+(B ($B$3$s$J$3$H$O!"$"$j$($J$$$H;W$&$,(B)$B!"(B
466 * jserver $B$,;`$s$@$J$I$NM}M3$G(B jserver $B$H$N@\B3$,@Z$l$F$$$k$J$i$P!":F(B
467 * $B=i4|2=!J:F@\B3!K$r9T$J$&!#(B
468 */
469 if (obj->ccWnn.wnnbuf == NULL || !jcIsConnect(obj->ccWnn.wnnbuf)) {
470 jcInitialize(obj);
471 /* $B:F@\B3$r;n$_$F$b!"$^$@@\B3$G$-$F$$$J$$$H$-$O!"%(%i!<$rJV$9(B */
472 if (obj->ccWnn.wnnbuf == NULL || !jcIsConnect(obj->ccWnn.wnnbuf)) {
473 bell(obj);
474 return -1;
475 }
476 }
477
478 wnn_errorno = 0;
479 curmode = ccGetModePrompt(obj->ccWnn.ccbuf);
480
481 (void)ccConvchar(obj->ccWnn.ccbuf, (XKeyPressedEvent *)event);
482
483 /*
484 * $B%(%i!<HV9f$r%A%'%C%/$7!"(Bjserver $B$,;`$s$G$$$l$P4D6-$r(B destroy $B$7(B
485 * $B:F$S@\B3$r;n$_$k(B
486 */
487 if (wnn_errorno == WNN_JSERVER_DEAD) {
488 XtAppWarning(XtWidgetToApplicationContext((Widget)w),
489 "ccWnn Object: jserver died");
490 /* $B$b$7$bF~NOCf$NJ8;zNs$,$"$l$P$H$C$F$*$/(B */
491 saveData(obj);
492 serverDead();
493 /* secondary jserver $B$,;XDj$5$l$F$$$l$P:F@\B3$r;n$_$k(B */
494 if (obj->ccWnn.jservername2 != NULL) jcInitialize(obj);
495 if (obj->ccWnn.wnnbuf == NULL || !jcIsConnect(obj->ccWnn.wnnbuf)) {
496 bell(obj);
497 ret = -1;
498 }
499 }
500
501 /* $B%F%-%9%H$NJQ2=$r%A%'%C%/$9$k(B */
502 if (obj->ccWnn.textchanged) {
503 XtCallCallbackList(w, obj->inputConv.textchangecallback,
504 (XtPointer)NULL);
505 obj->ccWnn.textchanged = False;
506 }
507 /* $BF~NO%b!<%I$r%A%'%C%/$9$k(B */
508 if (wstrcmp(ccGetModePrompt(obj->ccWnn.ccbuf), curmode)) {
509 sendback = 0;
510 XtCallCallbackList(w, obj->inputConv.modechangecallback,
511 (XtPointer)NULL);
512 }
513 /* $B%$%Y%s%H$r%/%i%$%"%s%H$KAw$jJV$9$+$I$&$+$NH=Dj$=$N(B 2 */
514 if (NumSegments(w) != 0 ||
515 obj->ccWnn.state != normal_state ||
516 obj->ccWnn.fixperformed) {
517 sendback = 0;
518 }
519 if (ret == 0 && (obj->ccWnn.sendbackevent || sendback)) ret = 1;
520
521 return ret;
522 }
523
524 static ICString *
525 GetMode(w)
526 Widget w;
527 {
528 CcWnnObject obj = (CcWnnObject)w;
529 wchar *mode;
530 static ICString icstr;
531
532 mode = ccGetModePrompt(obj->ccWnn.ccbuf);
533 icstr.data = (char *)mode;
534 icstr.nchars = wstrlen(mode);
535 icstr.nbytes = icstr.nchars * sizeof(wchar);
536 icstr.attr = ICAttrNormalString;
537
538 return &icstr;
539 }
540
541 static int
542 CursorPos(w, nsegp, ncharp)
543 Widget w;
544 Cardinal *nsegp;
545 Cardinal *ncharp;
546 {
547 CcWnnObject obj = (CcWnnObject)w;
548 jcConvBuf *jcbuf = obj->ccWnn.jcbuf;
549 Cardinal nseg, nchar;
550
551 if (jcbuf == NULL || jcIsConverted(jcbuf, jcbuf->curClause)) return 0;
552
553 nseg = jcbuf->curClause;
554 nchar = jcDotOffset(jcbuf);
555
556 if (nseg >= jcbuf->nClause) {
557 if (nseg == 0) {
558 nchar = 0;
559 } else {
560 jcClause *cinfo = jcbuf->clauseInfo;
561 nseg--;
562 nchar = cinfo[nseg + 1].dispp - cinfo[nseg].dispp;
563 }
564 }
565
566 if (nsegp) *nsegp = nseg;
567 if (ncharp) *ncharp = nchar;
568
569 return 1;
570 }
571
572 static int
573 NumSegments(w)
574 Widget w;
575 {
576 CcWnnObject obj = (CcWnnObject)w;
577
578 return (obj->ccWnn.jcbuf != NULL) ? obj->ccWnn.jcbuf->nClause : 0;
579 }
580
581 static ICString *
582 GetSegment(w, n)
583 Widget w;
584 Cardinal n;
585 {
586 CcWnnObject obj = (CcWnnObject)w;
587 jcConvBuf *jcbuf = obj->ccWnn.jcbuf;
588 jcClause *cinfo = jcbuf->clauseInfo;
589 static ICString seg;
590
591 if (jcbuf == NULL || n >= jcbuf->nClause) return NULL;
592 seg.data = (char *)cinfo[n].dispp;
593 seg.nchars = cinfo[n + 1].dispp - cinfo[n].dispp;
594 seg.nbytes = seg.nchars * sizeof(wchar);
595 seg.attr = cinfo[n].conv ? ICAttrConverted : ICAttrNotConverted;
596 if (n == jcbuf->curClause) {
597 seg.attr |= ICAttrCurrentSegment;
598 } else if (jcbuf->curLCStart <= n && n < jcbuf->curLCEnd) {
599 seg.attr |= ICAttrCurrentSubSegment;
600 }
601 return &seg;
602 }
603
604 /* ARGSUSED */
605 static int
606 CompareSegment(w, seg1, seg2, n)
607 Widget w;
608 ICString *seg1;
609 ICString *seg2;
610 Cardinal *n;
611 {
612 wchar *p, *q;
613 int len, nsame;
614 int result = 0;
615
616 if (seg1->attr != seg2->attr) result |= ICAttrChanged;
617
618 len = seg1->nchars > seg2->nchars ? seg2->nchars : seg1->nchars;
619 nsame = 0;
620 p = (wchar *)seg1->data;
621 q = (wchar *)seg2->data;
622 while (nsame < len && *p++ == *q++) nsame++;
623
624 if (nsame != len || len != seg1->nchars || len != seg2->nchars)
625 result |= ICStringChanged;
626
627 if (n) *n = nsame;
628
629 return result;
630 }
631
632 static ICString *
633 GetItemList(w, n)
634 Widget w;
635 Cardinal *n;
636 {
637 CcWnnObject obj = (CcWnnObject)w;
638
639 switch (obj->ccWnn.state) {
640 case selection_l_state:
641 case selection_s_state:
642 *n = obj->ccWnn.numcand;
643 return obj->ccWnn.candlist;
644 case symbol_state:
645 *n = obj->ccWnn.numsymbols;
646 return obj->ccWnn.symbollist;
647 default:
648 *n = 0;
649 return NULL; /* no item available */
650 }
651 /* NOTREACHED */
652 }
653
654 static int
655 SelectItem(w, n)
656 Widget w;
657 int n;
658 {
659 CcWnnObject obj = (CcWnnObject)w;
660 int ret = 0;
661
662 if (obj->ccWnn.state == normal_state) return -1;
663
664 if (obj->ccWnn.jcbuf == NULL) {
665 ret = -1;
666 } else if (n >= 0) {
667 ret = insertSelection(obj, n);
668 if (obj->ccWnn.textchanged) {
669 XtCallCallbackList((Widget)obj,
670 obj->inputConv.textchangecallback,
671 (XtPointer)NULL);
672 obj->ccWnn.textchanged = False;
673 }
674 }
675
676 obj->ccWnn.state = normal_state;
677 return ret;
678 }
679
680 static int
681 ConvertedString(w, encoding, format, length, string)
682 Widget w;
683 Atom *encoding;
684 int *format;
685 int *length;
686 XtPointer *string;
687 {
688 CcWnnObject obj = (CcWnnObject)w;
689 jcConvBuf *jcbuf = obj->ccWnn.jcbuf;
690 wchar *wbuf, *wp;
691 int len, wlen;
692 extern int convJWStoCT();
693
694 if (jcbuf == NULL) return -1;
695
696 wlen = jcbuf->displayEnd - jcbuf->displayBuf;
697 if (wlen == 0) return -1;
698
699 /*
700 * jcbuf $B$KF~$C$F$$$kJQ49%F%-%9%H$O(B null $B%?!<%_%M!<%H$5$l$F$$$J$$$N$G(B
701 * $B$^$:%3%T!<$7$F(B null $B%?!<%_%M!<%H$9$k(B
702 */
703 wbuf = (wchar *)XtMalloc((wlen + 1) * sizeof(wchar));
704 (void)bcopy((char *)jcbuf->displayBuf, (char *)wbuf,
705 sizeof(wchar) * wlen);
706 wbuf[wlen] = 0;
707
708 /*
709 * CcWnn $B%*%V%8%'%/%H$O(B COMPOUND_TEXT $B%(%s%3!<%G%#%s%0$7$+%5%]!<%H$7$J$$(B
710 * COMPOUND_TEXT $B$KJQ49$9$k(B
711 */
712 *encoding = XA_COMPOUND_TEXT(XtDisplayOfObject((Widget)obj));
713 *format = 8;
714
715 /* COMPOUND_TEXT $B$O(B \r $B$,Aw$l$J$$$N$G(B \n $B$KJQ49$7$F$*$/(B */
716 for (wp = wbuf; *wp != 0; wp++) {
717 if (*wp == '\r') *wp = '\n';
718 }
719
720 *length = len = convJWStoCT(wbuf, (unsigned char *)NULL, 0);
721 *string = XtMalloc(len + 1);
722 (void)convJWStoCT(wbuf, (unsigned char *)*string, 0);
723
724 /* wbuf $B$r(B free $B$7$F$*$/(B */
725 XtFree((char *)wbuf);
726
727 return 0;
728 }
729
730 static int
731 ClearConversion(w)
732 Widget w;
733 {
734 CcWnnObject obj = (CcWnnObject)w;
735
736 if (obj->ccWnn.jcbuf == NULL) {
737 return 0; /* not -1, because it's already cleared */
738 }
739 clear_buffer(obj);
740 XtCallCallbackList(w, obj->inputConv.textchangecallback, (XtPointer)NULL);
741 return 0;
742 }
743
744 /* ARGSUSED */
745 static ICString *
746 GetAuxSegments(w, n, ns, nc)
747 Widget w;
748 Cardinal *n, *ns, *nc;
749 {
750 /* CcWnn doesn't use AuxPanel */
751 XtAppWarning(XtWidgetToApplicationContext(w),
752 "ccWnn Object: GetAuxSegments shouldn't be called");
753 return NULL;
754 }
755
756 /* ARGSUSED */
757 static void
758 Initialize(req, new, args, num_args)
759 Widget req;
760 Widget new;
761 ArgList args;
762 Cardinal *num_args;
763 {
764 CcWnnObject obj = (CcWnnObject)new;
765
766 obj->ccWnn.ccrule = NULL;
767 obj->ccWnn.jcbuf = NULL;
768 obj->ccWnn.state = normal_state;
769 obj->ccWnn.selectionending = False;
770 obj->ccWnn.textchanged = False;
771 obj->ccWnn.symbollist = SymbolList;
772 obj->ccWnn.numsymbols = NumSymbols;
773 obj->ccWnn.cursymbol = 0;
774 obj->ccWnn.candlist = NULL;
775 obj->ccWnn.candlistsize = 0;
776 obj->ccWnn.numcand = 0;
777 obj->ccWnn.strdata = NULL;
778 obj->ccWnn.strdatasize = 0;
779 obj->ccWnn.inputmode = OTHERS;
780 obj->ccWnn.pendingdata = NULL;
781 obj->ccWnn.fixcount = 0;
782 obj->ccWnn.selwidget = NULL;
783 obj->ccWnn.selyomi = obj->ccWnn.selkanji = NULL;
784
785 /* $BJQ49$N=i4|2=(B */
786 obj->ccWnn.createrule = False;
787 obj->ccWnn.createenv = False;
788 ccInitialize(obj);
789 jcInitialize(obj);
790
791 addObject(obj);
792 }
793
794 static void
795 ccInitialize(obj)
796 CcWnnObject obj;
797 {
798 extern char *getenv();
799
800 if (obj->ccWnn.createrule) {
801 ccDestroyBuf(obj->ccWnn.ccbuf);
802 obj->ccWnn.ccbuf = NULL;
803 }
804 if (obj->ccWnn.ccrule == NULL) {
805 if (obj->ccWnn.ccdeffile == NULL) {
806 obj->ccWnn.ccdeffile = getenv("CC_DEF");
807 if (obj->ccWnn.ccdeffile == NULL) {
808 obj->ccWnn.ccdeffile = DEF_CCDEF_FILE;
809 }
810 }
811 obj->ccWnn.ccrule = ccParseRule(obj->ccWnn.ccdeffile, XtWarning);
812 obj->ccWnn.createrule = True;
813 }
814
815 if (obj->ccWnn.ccrule == NULL) {
816 XtAppError(XtWidgetToApplicationContext((Widget)obj),
817 "CcWnn Object: cconv initialization failed.");
818 }
819
820 obj->ccWnn.ccbuf = ccCreateBuf(obj->ccWnn.ccrule, 16,
821 fepfunctbl, FTSIZE,
822 defAction, insChar, delChar,
823 funcDispatch, autoFix, NULL, (caddr_t)obj);
824 }
825
826 static CcWnnObject current_obj = NULL;
827
828 static void
829 jcInitialize(obj)
830 CcWnnObject obj;
831 {
832 if (obj->ccWnn.createenv) {
833 (void)jcDestroyBuffer(obj->ccWnn.jcbuf, 0);
834 obj->ccWnn.jcbuf = NULL;
835 obj->ccWnn.createenv = False;
836 }
837
838 if (obj->ccWnn.wnnbuf == NULL || !jcIsConnect(obj->ccWnn.wnnbuf)) {
839 if (obj->ccWnn.wnnbuf != NULL) {
840 jcClose(obj->ccWnn.wnnbuf);
841 obj->ccWnn.wnnbuf = NULL;
842 }
843 if (obj->ccWnn.wnnenvname == NULL) obj->ccWnn.wnnenvname = "";
844 if (obj->ccWnn.wnnenvrcfile == NULL) obj->ccWnn.wnnenvrcfile = "";
845 if (obj->ccWnn.wnnenvrcfile4 == NULL) {
846 obj->ccWnn.wnnenvrcfile4 = obj->ccWnn.wnnenvrcfile;
847 }
848 if (obj->ccWnn.wnnenvrcfile6 == NULL) {
849 obj->ccWnn.wnnenvrcfile6 = obj->ccWnn.wnnenvrcfile;
850 }
851
852 /*
853 * jllib $B$N%3!<%k%P%C%/$G$O!"%/%i%$%"%s%H!&%G!<%?$rEO$;$J$$$N(B
854 * $B$G!"3P$($F$*$/!#(B
855 */
856 current_obj = obj;
857 obj->ccWnn.wnnbuf = jcOpen2(obj->ccWnn.jservername,
858 obj->ccWnn.wnnenvname,
859 obj->ccWnn.wnnoverrideenv,
860 obj->ccWnn.wnnenvrcfile4,
861 obj->ccWnn.wnnenvrcfile6,
862 createEnvError,
863 createConfirm,
864 30);
865 /* wnnbuf $B$,3MF@$G$-$J$1$l$P!"$=$N$^$^%j%?!<%s(B */
866 if (obj->ccWnn.wnnbuf == NULL) {
867 XtAppWarning(XtWidgetToApplicationContext((Widget)obj),
868 "ccWnn Object: can't open jserver");
869 return;
870 }
871
872 /* jserver $B$H@\B3$5$l$F$$$J$1$l$P!"%;%+%s%@%j$r;n$7$F$_$k(B */
873 if (!jcIsConnect(obj->ccWnn.wnnbuf)
874 && obj->ccWnn.jservername2 != NULL) {
875 jcClose(obj->ccWnn.wnnbuf);
876 current_obj = obj;
877 obj->ccWnn.wnnbuf = jcOpen2(obj->ccWnn.jservername2,
878 obj->ccWnn.wnnenvname,
879 obj->ccWnn.wnnoverrideenv,
880 obj->ccWnn.wnnenvrcfile4,
881 obj->ccWnn.wnnenvrcfile6,
882 createEnvError,
883 createConfirm,
884 30);
885 if (obj->ccWnn.wnnbuf == NULL) {
886 XtAppWarning(XtWidgetToApplicationContext((Widget)obj),
887 "ccWnn Object: can't open jserver");
888 return;
889 }
890 }
891 obj->ccWnn.createenv = True;
892 if (!jcIsConnect(obj->ccWnn.wnnbuf)) {
893 XtAppWarning(XtWidgetToApplicationContext((Widget)obj),
894 "ccWnn Object: can't connect to jserver");
895 }
896 }
897 /* $B@\B3$G$-$J$/$F$b%P%C%U%!$O:n$C$F$*$/(B */
898 obj->ccWnn.jcbuf = jcCreateBuffer(obj->ccWnn.wnnbuf, 10, 80);
899 if (obj->ccWnn.pendingdata) restoreData(obj);
900 }
901
902 static void
903 createEnvError(s)
904 char *s;
905 {
906 if (current_obj != NULL)
907 XtAppWarning(XtWidgetToApplicationContext((Widget)current_obj), s);
908 }
909
910 static int
911 createConfirm(s)
912 char *s;
913 {
914 if (current_obj != NULL && current_obj->ccWnn.confirmfunc != NULL)
915 return (*current_obj->ccWnn.confirmfunc)((Widget)current_obj, s);
916 return 1;
917 }
918
919 static void
920 Destroy(w)
921 Widget w;
922 {
923 CcWnnObject obj = (CcWnnObject)w;
924
925 /* $B%P%C%U%!$N2rJ|(B */
926 if (obj->ccWnn.ccbuf) ccDestroyBuf(obj->ccWnn.ccbuf);
927 if (obj->ccWnn.jcbuf) jcDestroyBuffer(obj->ccWnn.jcbuf, 1);
928
929 /* $B$b$7(B Initialize() $BCf$G%k!<%k(B/$B4D6-$r:n$C$?$N$G$"$l$P2rJ|$9$k(B */
930 if (obj->ccWnn.createrule) ccFreeRule(obj->ccWnn.ccrule);
931 if (obj->ccWnn.createenv) jcClose(obj->ccWnn.wnnbuf);
932
933 if (obj->ccWnn.candlist) XtFree((char *)obj->ccWnn.candlist);
934 if (obj->ccWnn.strdata) XtFree((char *)obj->ccWnn.strdata);
935
936 if (obj->ccWnn.pendingdata) XtFree((char *)obj->ccWnn.pendingdata);
937
938 if (obj->ccWnn.selwidget) XtDestroyWidget(obj->ccWnn.selwidget);
939 if (obj->ccWnn.selyomi) XtFree(obj->ccWnn.selyomi);
940 if (obj->ccWnn.selkanji) XtFree(obj->ccWnn.selkanji);
941
942 deleteObject(obj);
943 }
944
945 /* ARGSUSED */
946 static Boolean
947 SetValues(cur, req, wid, args, num_args)
948 Widget cur;
949 Widget req;
950 Widget wid;
951 ArgList args;
952 Cardinal *num_args;
953 {
954 CcWnnObject old = (CcWnnObject)cur;
955 CcWnnObject new = (CcWnnObject)wid;
956
957 if (old->ccWnn.ccdeffile != new->ccWnn.ccdeffile ||
958 old->ccWnn.wnnbuf != new->ccWnn.wnnbuf ||
959 old->ccWnn.ccrule != new->ccWnn.ccrule) {
960 XtAppWarning(XtWidgetToApplicationContext(wid),
961 "ccWnn Object: can't change resource by XtSetValues()");
962 }
963 return False;
964 }
965
966
967 /*
968 * cconv function dispatcher
969 */
970
971 /* ARGSUSED */
972 static int
973 funcDispatch(func, str, nbytes, w)
974 int func;
975 unsigned char *str;
976 int nbytes;
977 caddr_t w;
978 {
979 CcWnnObject obj = (CcWnnObject)w;
980
981 obj->ccWnn.cont = True;
982 if (func < 0 || func >= FTSIZE) return True;
983
984 wnn_errorno = 0;
985
986 switch (obj->ccWnn.state) {
987 case selection_s_state:
988 case selection_l_state:
989 (*functable[func][1])(obj);
990 break;
991 case symbol_state:
992 (*functable[func][2])(obj);
993 break;
994 default:
995 (*functable[func][0])(obj);
996 break;
997 }
998
999 return obj->ccWnn.cont;
1000 }
1001
1002 /* ARGSUSED */
1003 static void
1004 defAction(str, nbytes, w)
1005 unsigned char *str;
1006 int nbytes;
1007 caddr_t w;
1008 {
1009 if (nbytes > 0) beep((CcWnnObject)w);
1010 }
1011
1012 #define ZERO 0xa3b0
1013 #define NINE 0xa3b9
1014 #define SmallA 0xa3e1
1015 #define SmallF 0xa3e6
1016 #define LargeA 0xa3c1
1017 #define LargeF 0xa3c6
1018 static int
1019 toHex(c)
1020 int c;
1021 {
1022 if ('0' <= c && c <= '9')
1023 return c - '0';
1024 if ('a' <= c && c <= 'f')
1025 return c + 10 - 'a';
1026 if ('A' <= c && c <= 'F')
1027 return c + 10 - 'A';
1028 if (ZERO <= c && c <= NINE)
1029 return c - ZERO;
1030 if (SmallA <= c && c <= SmallF)
1031 return c + 10 - SmallA;
1032 if (LargeA <= c && c <= LargeF)
1033 return c + 10 - LargeA;
1034 return -1;
1035 }
1036
1037 static int
1038 toHex4(s)
1039 wchar *s;
1040 {
1041 int c, h, cnt, hex;
1042
1043 hex = 0;
1044 cnt = 0;
1045 while (cnt < 4 && (c = *s++)) {
1046 if ((h = toHex(c)) < 0)
1047 return -1;
1048 hex = hex * 16 + h;
1049 cnt++;
1050 }
1051 if (cnt != 4)
1052 return -1;
1053
1054 return hex;
1055 }
1056
1057 static int
1058 toKuten(s)
1059 wchar *s;
1060 {
1061 int i, c, d[4];
1062
1063 for (i = 0; i < 4 && (c = *s++); i++) {
1064 if ((d[i] = toHex(c)) < 0 || d[i] >= 10)
1065 return(-1);
1066 }
1067 if (i != 4)
1068 return(-1);
1069 return((((d[0] * 10 + d[1]) << 8) | (d[2] * 10 + d[3])) + 0x2020);
1070 }
1071
1072 static void
1073 insChar(c, cldata)
1074 int c;
1075 caddr_t cldata;
1076 {
1077 CcWnnObject obj = (CcWnnObject)cldata;
1078 jcConvBuf *jcbuf = obj->ccWnn.jcbuf;
1079 ccBuf ccbuf = obj->ccWnn.ccbuf;
1080 wchar context[17];
1081 int h;
1082
1083 normalState(obj);
1084
1085 if (jcIsConverted(jcbuf, jcbuf->curClause)) {
1086 (void)jcBottom(jcbuf);
1087 }
1088
1089 switch (obj->ccWnn.inputmode) {
1090 case KUTEN_MODE:
1091 case JIS_MODE:
1092 /* $B%X%-%5$+$I$&$+$N%F%9%H(B */
1093 if ((h = toHex(c)) < 0 || (obj->ccWnn.inputmode == KUTEN_MODE && h >= 10)) {
1094 beep(obj);
1095 ccContextDelete(ccbuf);
1096 break;
1097 }
1098 ccContextGet(ccbuf, context);
1099 if (wstrlen(context) == 4) {
1100 /* convert to KANJI */
1101 c = obj->ccWnn.inputmode == KUTEN_MODE ? toKuten(context): toHex4(context);
1102 if (c < 0x2121 || 0x7e7e < c || (c & 0xff) < 0x21 ||
1103 0x7e < (c & 0xff)) {
1104 beep(obj);
1105 break;
1106 }
1107 /* $B#3J8;z:o=|(B -- $B#4J8;zL\$O$^$@A^F~$7$F$$$J$$(B */
1108 jcDeleteChar(jcbuf, 1);
1109 jcDeleteChar(jcbuf, 1);
1110 jcDeleteChar(jcbuf, 1);
1111 (void)jcInsertChar(jcbuf, c | 0x8080);
1112 obj->ccWnn.textchanged = True;
1113 /* $B%3%s%F%-%9%H$N%/%j%"(B */
1114 ccContextClear(ccbuf);
1115 break;
1116 }
1117 /* fall thru */
1118 case OTHERS:
1119 (void)jcInsertChar(jcbuf, c);
1120 obj->ccWnn.textchanged = True;
1121 break;
1122 }
1123 }
1124
1125 static void
1126 delChar(cldata)
1127 caddr_t cldata;
1128 {
1129 CcWnnObject obj = (CcWnnObject)cldata;
1130
1131 if (obj->ccWnn.state != normal_state) {
1132 beep(obj);
1133 return;
1134 }
1135 ccContextDelete(obj->ccWnn.ccbuf);
1136 jcDeleteChar(obj->ccWnn.jcbuf, 1);
1137 obj->ccWnn.textchanged = True;
1138 }
1139
1140 static void
1141 autoFix(cldata)
1142 caddr_t cldata;
1143 {
1144 CcWnnObject obj = (CcWnnObject)cldata;
1145
1146 switch (obj->ccWnn.state)
1147 {
1148 case selection_s_state:
1149 case selection_l_state:
1150 case symbol_state:
1151 fix(obj);
1152 break;
1153 default:
1154
1155 if (jcIsConverted(obj->ccWnn.jcbuf, 0))
1156 fix(obj);
1157 break;
1158 }
1159 }
1160
1161 /*
1162 * cconv functions
1163 */
1164
1165 /* some convenient macros */
1166 #define JCBUF(obj) ((obj)->ccWnn.jcbuf)
1167 #define CCBUF(obj) ((obj)->ccWnn.ccbuf)
1168 #define HINT(obj) ((obj)->ccWnn.textchanged)
1169
1170 /* $BJQ49%U%!%s%/%7%g%s72(B
1171 * convert
1172 * convert-sp
1173 * convert-s
1174 * unconvert
1175 */
1176
1177 static void
1178 convert_general(obj, small)
1179 CcWnnObject obj;
1180 int small;
1181 {
1182 jcConvBuf *jcbuf = JCBUF(obj);
1183
1184 if (jcbuf->curClause == jcbuf->nClause) {
1185 (void)jcMove(jcbuf, small, JC_BACKWARD);
1186 HINT(obj) = True;
1187 }
1188
1189 if (jcIsConverted(jcbuf, jcbuf->curClause)) {
1190 startSelection(obj, small);
1191 return;
1192 }
1193
1194 if (jcConvert(jcbuf, small, 0, 1) < 0) beep(obj);
1195 ccContextClear(CCBUF(obj));
1196 HINT(obj) = True;
1197 }
1198
1199 static void
1200 convert(obj)
1201 CcWnnObject obj;
1202 {
1203 convert_general(obj, 0);
1204 }
1205
1206 static void
1207 convert_sb(obj)
1208 CcWnnObject obj;
1209 {
1210 if (JCBUF(obj)->nClause == 0) {
1211 send_back(obj);
1212 fix(obj);
1213 } else {
1214 convert_general(obj, 0);
1215 }
1216 }
1217
1218 static void
1219 convert_sp(obj)
1220 CcWnnObject obj;
1221 {
1222 if (JCBUF(obj)->nClause == 0) {
1223 insChar(' ', (caddr_t)obj);
1224 fix(obj);
1225 } else {
1226 convert_general(obj, 0);
1227 }
1228 }
1229
1230 static void
1231 convert_mt(obj)
1232 CcWnnObject obj;
1233 {
1234 jcConvBuf *jcbuf = JCBUF(obj);
1235 if (jcbuf->nClause == 0) {
1236 send_back(obj);
1237 fix(obj);
1238 } else {
1239 int nc = jcbuf->nClause - 1;
1240 convert_general(obj, 0);
1241 if (!jcIsConverted(jcbuf, jcbuf->curClause)) {
1242 int i;
1243 move_top(obj);
1244 if (nc < jcbuf->nClause)
1245 for (i = 0; i < nc; i++)
1246 move_forward(obj);
1247 }
1248 }
1249 }
1250
1251 static void
1252 convert_f1(obj)
1253 CcWnnObject obj;
1254 {
1255 jcConvBuf *jcbuf = JCBUF(obj);
1256
1257 if (0 < jcbuf->nClause && jcIsConverted(jcbuf, 0)) {
1258 fix1(obj);
1259 } else {
1260 convert_general(obj, 0);
1261 }
1262 }
1263
1264 static void
1265 convert_mt_sb(obj)
1266 CcWnnObject obj;
1267 {
1268 jcConvBuf *jcbuf = JCBUF(obj);
1269 if (jcbuf->nClause == 0) {
1270 send_back(obj);
1271 fix(obj);
1272 } else {
1273 int nc = jcbuf->nClause - 1;
1274 convert_general(obj, 0);
1275 if (!jcIsConverted(jcbuf, jcbuf->curClause)) {
1276 int i;
1277 move_top(obj);
1278 if (nc < jcbuf->nClause)
1279 for (i = 0; i < nc; i++)
1280 move_forward(obj);
1281 }
1282 }
1283 }
1284
1285 static void
1286 convert_mt_sp(obj)
1287 CcWnnObject obj;
1288 {
1289 jcConvBuf *jcbuf = JCBUF(obj);
1290 if (jcbuf->nClause == 0) {
1291 insChar(' ', (caddr_t)obj);
1292 fix(obj);
1293 } else {
1294 int nc = jcbuf->nClause - 1;
1295 convert_general(obj, 0);
1296 if (!jcIsConverted(jcbuf, jcbuf->curClause)) {
1297 int i;
1298 move_top(obj);
1299 if (nc < jcbuf->nClause)
1300 for (i = 0; i < nc; i++)
1301 move_forward(obj);
1302 }
1303 }
1304 }
1305
1306 static void
1307 convert_s(obj)
1308 CcWnnObject obj;
1309 {
1310 convert_general(obj, 1);
1311 }
1312
1313 static void
1314 unconvert(obj)
1315 CcWnnObject obj;
1316 {
1317 if (jcUnconvert(JCBUF(obj)) < 0) beep(obj);
1318 ccContextClear(CCBUF(obj));
1319 HINT(obj) = True;
1320 }
1321
1322 static void
1323 select_general(obj, small)
1324 CcWnnObject obj;
1325 int small;
1326 {
1327 jcConvBuf *jcbuf = JCBUF(obj);
1328
1329 if (jcbuf->curClause == jcbuf->nClause) {
1330 (void)jcMove(jcbuf, small, JC_BACKWARD);
1331 HINT(obj) = True;
1332 }
1333
1334 if (jcIsConverted(jcbuf, jcbuf->curClause)) {
1335 startSelection(obj, small);
1336 obj->ccWnn.cont = False; /* $B<!$N4X?t$O8F$P$J$$(B */
1337 }
1338 }
1339
1340
1341 static void
1342 egg_select(obj)
1343 CcWnnObject obj;
1344 {
1345 select_general(obj, 0);
1346 }
1347
1348
1349 static void
1350 egg_select_s(obj)
1351 CcWnnObject obj;
1352 {
1353 select_general(obj, 1);
1354 }
1355
1356 /* $B%+!<%=%k0\F0%U%!%s%/%7%g%s72(B
1357 * move_forward
1358 * move_backward
1359 * move_top
1360 * move_bottom
1361 */
1362
1363 static void
1364 move_general(obj, direction)
1365 CcWnnObject obj;
1366 int direction;
1367 {
1368 int status = -1;
1369
1370 switch (direction) {
1371 case ICMoveLeftMost:
1372 status = jcTop(JCBUF(obj));
1373 break;
1374 case ICMoveRightMost:
1375 status = jcBottom(JCBUF(obj));
1376 break;
1377 case ICMoveRight:
1378 status = jcMove(JCBUF(obj), 1, JC_FORWARD);
1379 break;
1380 case ICMoveLeft:
1381 status = jcMove(JCBUF(obj), 1, JC_BACKWARD);
1382 break;
1383 }
1384
1385 if (status < 0) beep(obj);
1386
1387 ccContextClear(CCBUF(obj));
1388
1389 HINT(obj) = True;
1390 }
1391
1392 static void
1393 move_forward(obj)
1394 CcWnnObject obj;
1395 {
1396 move_general(obj, ICMoveRight);
1397 }
1398
1399 static void
1400 move_backward(obj)
1401 CcWnnObject obj;
1402 {
1403 move_general(obj, ICMoveLeft);
1404 }
1405
1406 static void
1407 move_top(obj)
1408 CcWnnObject obj;
1409 {
1410 move_general(obj, ICMoveLeftMost);
1411 }
1412
1413 static void
1414 move_bottom(obj)
1415 CcWnnObject obj;
1416 {
1417 move_general(obj, ICMoveRightMost);
1418 }
1419
1420
1421 /* $B8uJd@ZBX$(%U%!%s%/%7%g%s72(B
1422 * cand_next
1423 * cand_next_s
1424 * cand_prev
1425 * cand_prev_s
1426 */
1427
1428 static void
1429 cand_general(obj, small, type)
1430 CcWnnObject obj;
1431 int small;
1432 int type;
1433 {
1434 if (jcNext(JCBUF(obj), small, type) < 0) beep(obj);
1435 ccContextClear(CCBUF(obj));
1436 HINT(obj) = True;
1437 }
1438
1439 static void
1440 cand_next(obj)
1441 CcWnnObject obj;
1442 {
1443 cand_general(obj, 0, JC_NEXT);
1444 }
1445
1446 static void
1447 cand_next_mt(obj)
1448 CcWnnObject obj;
1449 {
1450 jcConvBuf *jcbuf = JCBUF(obj);
1451 if (jcIsConverted(jcbuf, jcbuf->curClause))
1452 cand_general(obj, 0, JC_NEXT);
1453 else
1454 convert_mt(obj);
1455 }
1456
1457 static void
1458 cand_next_mt_sb(obj)
1459 CcWnnObject obj;
1460 {
1461 jcConvBuf *jcbuf = JCBUF(obj);
1462 if (jcIsConverted(jcbuf, jcbuf->curClause))
1463 cand_general(obj, 0, JC_NEXT);
1464 else
1465 convert_mt_sb(obj);
1466 }
1467
1468 static void
1469 cand_next_mt_sp(obj)
1470 CcWnnObject obj;
1471 {
1472 jcConvBuf *jcbuf = JCBUF(obj);
1473 if (jcIsConverted(jcbuf, jcbuf->curClause))
1474 cand_general(obj, 0, JC_NEXT);
1475 else
1476 convert_mt_sp(obj);
1477 }
1478
1479 static void
1480 cand_next_s(obj)
1481 CcWnnObject obj;
1482 {
1483 cand_general(obj, 1, JC_NEXT);
1484 }
1485
1486 static void
1487 cand_prev(obj)
1488 CcWnnObject obj;
1489 {
1490 cand_general(obj, 0, JC_PREV);
1491 }
1492
1493 static void
1494 cand_prev_s(obj)
1495 CcWnnObject obj;
1496 {
1497 cand_general(obj, 1, JC_PREV);
1498 }
1499
1500
1501 /* $BJ8@aD9JQ99%U%!%s%/%7%g%s72(B
1502 * expand_cl
1503 * expand_cl_s
1504 * expand_cl2
1505 * expand_cl2_s
1506 * shrink_cl
1507 * shrink_cl_s
1508 * shrink_cl2
1509 * shrink_cl2_s
1510 */
1511
1512 static void
1513 expand_shrink_general(obj, shrink, small, conv)
1514 CcWnnObject obj;
1515 int shrink;
1516 int small;
1517 int conv;
1518 {
1519 int status;
1520
1521 normalState(obj);
1522
1523 if (shrink) {
1524 status = jcShrink(JCBUF(obj), small, conv);
1525 } else {
1526 status = jcExpand(JCBUF(obj), small, conv);
1527 }
1528 if (status < 0) beep(obj);
1529
1530 ccContextClear(CCBUF(obj));
1531 HINT(obj) = True;
1532 }
1533
1534 static void
1535 expand_cl(obj)
1536 CcWnnObject obj;
1537 {
1538 expand_shrink_general(obj, 0, 0, 1);
1539 }
1540
1541 static void
1542 expand_cl_s(obj)
1543 CcWnnObject obj;
1544 {
1545 expand_shrink_general(obj, 0, 1, 1);
1546 }
1547
1548 static void
1549 shrink_cl(obj)
1550 CcWnnObject obj;
1551 {
1552 expand_shrink_general(obj, 1, 0, 1);
1553 }
1554
1555 static void
1556 shrink_cl_s(obj)
1557 CcWnnObject obj;
1558 {
1559 expand_shrink_general(obj, 1, 1, 1);
1560 }
1561
1562 static void
1563 expand_cl2(obj)
1564 CcWnnObject obj;
1565 {
1566 expand_shrink_general(obj, 0, 0, 0);
1567 }
1568
1569 static void
1570 expand_cl2_s(obj)
1571 CcWnnObject obj;
1572 {
1573 expand_shrink_general(obj, 0, 1, 0);
1574 }
1575
1576 static void
1577 shrink_cl2(obj)
1578 CcWnnObject obj;
1579 {
1580 expand_shrink_general(obj, 1, 0, 0);
1581 }
1582
1583 static void
1584 shrink_cl2_s(obj)
1585 CcWnnObject obj;
1586 {
1587 expand_shrink_general(obj, 1, 1, 0);
1588 }
1589
1590
1591 /* $BJQ49%P%C%U%!%/%j%"%U%!%s%/%7%g%s(B
1592 * clear_buffer
1593 */
1594
1595 static void
1596 clear_buffer(obj)
1597 CcWnnObject obj;
1598 {
1599 normalState(obj);
1600 if (jcClear(JCBUF(obj)) < 0) beep(obj);
1601 ccContextClear(CCBUF(obj));
1602 HINT(obj) = True;
1603 }
1604
1605 static void
1606 cancel(obj)
1607 CcWnnObject obj;
1608 {
1609 if (jcCancel(JCBUF(obj)) < 0) beep(obj);
1610 ccContextClear(CCBUF(obj));
1611 move_bottom(obj);
1612 HINT(obj) = True;
1613 }
1614
1615
1616 static void
1617 clear_c(obj)
1618 CcWnnObject obj;
1619 {
1620 switch (obj->ccWnn.state)
1621 {
1622 case selection_s_state:
1623 case selection_l_state:
1624 endSelection(obj, False);
1625 cancel(obj);
1626 break;
1627 case symbol_state:
1628 clear_buffer(obj);
1629 break;
1630 default:
1631 if (jcIsConverted(JCBUF(obj), JCBUF(obj)->curClause))
1632 cancel(obj);
1633 else
1634 clear_buffer(obj);
1635 break;
1636 }
1637 }
1638
1639 /* $B8uJd0\F0%U%!%s%/%7%g%s72(B
1640 * sel_next
1641 * sel_prev
1642 * sel_top
1643 * sel_bottom
1644 * sel_forward
1645 * sel_backward
1646 */
1647
1648 static void
1649 sel_top(obj)
1650 CcWnnObject obj;
1651 {
1652 moveSelection(obj, ICMoveLeftMost);
1653 }
1654
1655 static void
1656 sel_bottom(obj)
1657 CcWnnObject obj;
1658 {
1659 moveSelection(obj, ICMoveRightMost);
1660 }
1661
1662 static void
1663 sel_forward(obj)
1664 CcWnnObject obj;
1665 {
1666 moveSelection(obj, ICMoveRight);
1667 }
1668
1669 static void
1670 sel_backward(obj)
1671 CcWnnObject obj;
1672 {
1673 moveSelection(obj, ICMoveLeft);
1674 }
1675
1676 static void
1677 sel_next(obj)
1678 CcWnnObject obj;
1679 {
1680 moveSelection(obj, ICMoveDown);
1681 }
1682
1683 static void
1684 sel_prev(obj)
1685 CcWnnObject obj;
1686 {
1687 moveSelection(obj, ICMoveUp);
1688 }
1689
1690 static void
1691 sel_select(obj)
1692 CcWnnObject obj;
1693 {
1694 endSelection(obj, False);
1695 }
1696
1697 static void
1698 sel_abort(obj)
1699 CcWnnObject obj;
1700 {
1701 endSelection(obj, True);
1702 }
1703
1704 static void
1705 fix(obj)
1706 CcWnnObject obj;
1707 {
1708 jcConvBuf *jcbuf = JCBUF(obj);
1709
1710 normalState(obj);
1711 ccContextClear(CCBUF(obj));
1712
1713 if (jcbuf->nClause > 0) {
1714 obj->ccWnn.fixperformed = True;
1715
1716 if (jcFix(jcbuf) < 0) {
1717 beep(obj);
1718 return;
1719 }
1720
1721 /* $B<-=q%;!<%V$N=hM}(B */
1722 obj->ccWnn.fixcount++;
1723 if (obj->ccWnn.saveinterval > 0 &&
1724 obj->ccWnn.fixcount >= obj->ccWnn.saveinterval) {
1725 jcSaveDic(jcbuf);
1726 obj->ccWnn.fixcount = 0;
1727 }
1728
1729 /* $B3NDj$N=hM}(B */
1730 XtCallCallbackList((Widget)obj, obj->inputConv.fixcallback,
1731 (XtPointer)NULL); /* ??? */
1732
1733 HINT(obj) = True;
1734 }
1735
1736 /* $B%P%C%U%!$r%/%j%"$9$k(B */
1737 jcClear(jcbuf);
1738 }
1739
1740 static void
1741 fix1(obj)
1742 CcWnnObject obj;
1743 {
1744 jcConvBuf *jcbuf = JCBUF(obj);
1745
1746 normalState(obj);
1747 ccContextClear(CCBUF(obj));
1748
1749 if (jcbuf->nClause > 0) {
1750 obj->ccWnn.fixperformed = True;
1751
1752 if (jcFix1(jcbuf) < 0) { /* $B$3$3$@$1$,(B fix(obj) $B$H0c$&$H$3$m(B */
1753 beep(obj);
1754 return;
1755 }
1756
1757 /* $B<-=q%;!<%V$N=hM}(B */
1758 obj->ccWnn.fixcount++;
1759 if (obj->ccWnn.saveinterval > 0 &&
1760 obj->ccWnn.fixcount >= obj->ccWnn.saveinterval) {
1761 jcSaveDic(jcbuf);
1762 obj->ccWnn.fixcount = 0;
1763 }
1764
1765 /* $B3NDj$N=hM}(B */
1766 XtCallCallbackList((Widget)obj, obj->inputConv.fixcallback,
1767 (XtPointer)NULL); /* ??? */
1768
1769 HINT(obj) = True;
1770 }
1771
1772 /* $B%P%C%U%!$r%/%j%"$9$k(B */
1773 jcClear(jcbuf);
1774 }
1775
1776 static void
1777 fix_cr(obj)
1778 CcWnnObject obj;
1779 {
1780 if (JCBUF(obj)->nClause == 0) {
1781 carriageret(obj);
1782 } else {
1783 fix(obj);
1784 }
1785 }
1786
1787
1788 static void
1789 fix_sb(obj)
1790 CcWnnObject obj;
1791 {
1792 if (JCBUF(obj)->nClause == 0) {
1793 send_back(obj);
1794 } else {
1795 fix(obj);
1796 }
1797 }
1798
1799
1800 static void
1801 to_hankaku(start, end, res)
1802 wchar *start;
1803 wchar *end;
1804 wchar *res;
1805 {
1806 static unsigned short hiratohan[] = { /* $BA43Q$+$J(B <-> $BH>3Q$+$J(B */
1807 #define D (0xde<<8) /* $BBy2;(B */
1808 #define H (0xdf<<8) /* $BH>By2;(B */
1809 /* a */ 0xa7, 0xb1, 0xa8, 0xb2, 0xa9, 0xb3, 0xaa, 0xb4, 0xab, 0xb5,
1810 /* k */ 0xb6, 0xb6|D, 0xb7, 0xb7|D, 0xb8, 0xb8|D,
1811 0xb9, 0xb9|D, 0xba, 0xba|D,
1812 /* s */ 0xbb, 0xbb|D, 0xbc, 0xbc|D, 0xbd, 0xbd|D,
1813 0xbe, 0xbe|D, 0xbf, 0xbf|D,
1814 /* t */ 0xc0, 0xc0|D, 0xc1, 0xc1|D, 0xaf, 0xc2, 0xc2|D,
1815 0xc3, 0xc3|D, 0xc4, 0xc4|D,
1816 /* n */ 0xc5, 0xc6, 0xc7, 0xc8, 0xc9,
1817 /* h */ 0xca, 0xca|D, 0xca|H, 0xcb, 0xcb|D, 0xcb|H, 0xcc, 0xcc|D,
1818 0xcc|H, 0xcd, 0xcd|D, 0xcd|H, 0xce, 0xce|D, 0xce|H,
1819 /* m */ 0xcf, 0xd0, 0xd1, 0xd2, 0xd3,
1820 /* y */ 0xac, 0xd4, 0xad, 0xd5, 0xae, 0xd6,
1821 /* r */ 0xd7, 0xd8, 0xd9, 0xda, 0xdb,
1822 /* w */ 0xdc, 0xdc, 0xb2, 0xb4, 0xa6,
1823 /* n */ 0xdd
1824 #undef D
1825 #undef H
1826 };
1827 static struct symzenhan {
1828 unsigned short zen;
1829 unsigned char han;
1830 } kigoutohan[] = { /* $BA43Q5-9f(B -> $BH>3Q5-9f(B */
1831 0xa1a1, 0x20, 0xa1a2, 0xa4, 0xa1a3, 0xa1, 0xa1a4, 0x2c,
1832 0xa1a5, 0x2e, 0xa1a6, 0xa5, 0xa1a7, 0x3a, 0xa1a8, 0x3b,
1833 0xa1a9, 0x3f, 0xa1aa, 0x21, 0xa1ab, 0xde, 0xa1ac, 0xdf,
1834 0xa1b0, 0x5e, 0xa1b2, 0x5f, 0xa1bc, 0xb0, 0xa1bf, 0x2f,
1835 0xa1c1, 0x7e, 0xa1c3, 0x7c, 0xa1c6, 0x60, 0xa1c7, 0x27,
1836 0xa1c8, 0x22, 0xa1c9, 0x22, 0xa1ca, 0x28, 0xa1cb, 0x29,
1837 0xa1cc, 0x5b, 0xa1cd, 0x5d, 0xa1ce, 0x5b, 0xa1cf, 0x5d,
1838 0xa1d0, 0x7b, 0xa1d1, 0x7d, 0xa1d6, 0xa2, 0xa1d7, 0xa3,
1839 0xa1dc, 0x2b, 0xa1dd, 0x2d, 0xa1e1, 0x3d, 0xa1e3, 0x3c,
1840 0xa1e4, 0x3e, 0xa1ef, 0x5c, 0xa1f0, 0x24, 0xa1f3, 0x25,
1841 0xa1f4, 0x23, 0xa1f5, 0x26, 0xa1f6, 0x2a, 0xa1f7, 0x40,
1842 };
1843 #define KIGOUSIZE (sizeof(kigoutohan) / sizeof(struct symzenhan))
1844 register int c;
1845
1846 while (start < end) {
1847 c = *start++;
1848 if (0xa1a1 <= c && c <= 0xa1fe) { /* symbol */
1849 register struct symzenhan *hi = kigoutohan + KIGOUSIZE;
1850 register struct symzenhan *lo = kigoutohan;
1851 register struct symzenhan *m;
1852 register int dif;
1853
1854 while (lo <= hi) {
1855 m = lo + (hi - lo) / 2;
1856 if ((dif = c - m->zen) == 0) break;
1857 if (dif < 0) {
1858 hi = m - 1;
1859 } else {
1860 lo = m + 1;
1861 }
1862 }
1863 *res++ = (lo > hi) ? c : m->han;
1864 } else if (0xa3b0 <= c && c <= 0xa3b9) { /* Numeric */
1865 *res++ = c - 0xa3b0 + '0';
1866 } else if (0xa3c1 <= c && c <= 0xa3da) { /* A-Z */
1867 *res++ = c - 0xa3c1 + 'A';
1868 } else if (0xa3e1 <= c && c <= 0xa3fa) { /* a-z */
1869 *res++ = c - 0xa3e1 + 'a';
1870 } else if (0xa4a1 <= c && c <= 0xa4f3) { /* $B$R$i$,$J(B */
1871 c = hiratohan[c - 0xa4a1];
1872 *res++ = c & 0xff;
1873 if (c & 0xff00) *res++ = c >> 8;
1874 } else if (0xa5a1 <= c && c <= 0xa5f3) { /* $B$+$?$+$J(B */
1875 c = hiratohan[c - 0xa5a1];
1876 *res++ = c & 0xff;
1877 if (c & 0xff00) *res++ = c >> 8;
1878 } else {
1879 *res++ = c;
1880 }
1881 }
1882 *res = 0; /* NULL terminate */
1883 }
1884
1885 static void
1886 to_zenkaku(start, end, res)
1887 wchar *start;
1888 wchar *end;
1889 wchar *res;
1890 {
1891 static wchar hantozen[] = { /* $BH>3Q(B $B"M(B $BA43QJQ49I=(B */
1892 /* C0 */
1893 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
1894 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f,
1895 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017,
1896 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f,
1897 /* ASCII */
1898 0xa1a1, 0xa1aa, 0xa1c9, 0xa1f4, 0xa1f0, 0xa1f3, 0xa1f5, 0xa1c7,
1899 0xa1ca, 0xa1cb, 0xa1f6, 0xa1dc, 0xa1a4, 0xa1dd, 0xa1a5, 0xa1bf,
1900 0xa3b0, 0xa3b1, 0xa3b2, 0xa3b3, 0xa3b4, 0xa3b5, 0xa3b6, 0xa3b7,
1901 0xa3b8, 0xa3b9, 0xa1a7, 0xa1a8, 0xa1e3, 0xa1e1, 0xa1e4, 0xa1a9,
1902 0xa1f7, 0xa3c1, 0xa3c2, 0xa3c3, 0xa3c4, 0xa3c5, 0xa3c6, 0xa3c7,
1903 0xa3c8, 0xa3c9, 0xa3ca, 0xa3cb, 0xa3cc, 0xa3cd, 0xa3ce, 0xa3cf,
1904 0xa3d0, 0xa3d1, 0xa3d2, 0xa3d3, 0xa3d4, 0xa3d5, 0xa3d6, 0xa3d7,
1905 0xa3d8, 0xa3d9, 0xa3da, 0xa1ce, 0xa1ef, 0xa1cf, 0xa1b0, 0xa1b2,
1906 0xa1c6, 0xa3e1, 0xa3e2, 0xa3e3, 0xa3e4, 0xa3e5, 0xa3e6, 0xa3e7,
1907 0xa3e8, 0xa3e9, 0xa3ea, 0xa3eb, 0xa3ec, 0xa3ed, 0xa3ee, 0xa3ef,
1908 0xa3f0, 0xa3f1, 0xa3f2, 0xa3f3, 0xa3f4, 0xa3f5, 0xa3f6, 0xa3f7,
1909 0xa3f8, 0xa3f9, 0xa3fa, 0xa1d0, 0xa1c3, 0xa1d1, 0xa1c1, 0x007f,
1910 /* C1 */
1911 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
1912 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
1913 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
1914 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
1915 /* KANA */
1916 0xa1a1, 0xa1a3, 0xa1d6, 0xa1d7, 0xa1a2, 0xa1a6, 0xa5f2, 0xa5a1,
1917 0xa5a3, 0xa5a5, 0xa5a7, 0xa5a9, 0xa5e3, 0xa5e5, 0xa5e7, 0xa5c3,
1918 0xa1bc, 0xa5a2, 0xa5a4, 0xa5a6, 0xa5a8, 0xa5aa, 0xa5ab, 0xa5ad,
1919 0xa5af, 0xa5b1, 0xa5b3, 0xa5b5, 0xa5b7, 0xa5b9, 0xa5bb, 0xa5bd,
1920 0xa5bf, 0xa5c1, 0xa5c4, 0xa5c6, 0xa5c8, 0xa5ca, 0xa5cb, 0xa5cc,
1921 0xa5cd, 0xa5ce, 0xa5cf, 0xa5d2, 0xa5d5, 0xa5d8, 0xa5db, 0xa5de,
1922 0xa5df, 0xa5e0, 0xa5e1, 0xa5e2, 0xa5e4, 0xa5e6, 0xa5e8, 0xa5e9,
1923 0xa5ea, 0xa5eb, 0xa5ec, 0xa5ed, 0xa5ef, 0xa5f3, 0xa1ab, 0xa1ac,
1924 /* undefined */
1925 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7,
1926 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
1927 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7,
1928 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff,
1929 };
1930 register int c;
1931
1932 while (start < end) {
1933 c = *start++;
1934 if ((0x20 <= c && c <= 0x7e) || (0xa1 <= c && c <= 0xdf)) {
1935 *res++ = hantozen[c];
1936 } else {
1937 *res++ = c;
1938 }
1939 }
1940 *res = 0; /* NULL terminate */
1941 }
1942
1943 static void
1944 zenkaku_hankaku(obj, hankaku)
1945 CcWnnObject obj;
1946 int hankaku;
1947 {
1948 jcConvBuf *jcbuf = JCBUF(obj);
1949
1950 normalState(obj);
1951
1952 if (jcbuf->curClause != jcbuf->nClause) {
1953 jcClause *cinfo = jcbuf->clauseInfo;
1954 wchar *ks = cinfo[jcbuf->curLCStart].kanap;
1955 wchar *ke = cinfo[jcbuf->curLCEnd].kanap;
1956 wchar buf[256];
1957
1958 if (hankaku) {
1959 to_hankaku(ks, ke, buf);
1960 } else {
1961 to_zenkaku(ks, ke, buf);
1962 }
1963 if (jcChangeClause(jcbuf, buf) < 0) beep(obj);
1964 }
1965 ccContextClear(CCBUF(obj));
1966 HINT(obj) = True;
1967 }
1968
1969 static void
1970 zenkaku(obj)
1971 CcWnnObject obj;
1972 {
1973 zenkaku_hankaku(obj, 0);
1974 }
1975
1976 static void
1977 hankaku(obj)
1978 CcWnnObject obj;
1979 {
1980 zenkaku_hankaku(obj, 1);
1981 }
1982
1983 static void
1984 hiragana_katakana(obj, type)
1985 CcWnnObject obj;
1986 int type;
1987 {
1988 normalState(obj);
1989
1990 if (jcKana(JCBUF(obj), 0, type) < 0) beep(obj);
1991 ccContextClear(CCBUF(obj));
1992 HINT(obj) = True;
1993 }
1994
1995 static void
1996 hiragana(obj)
1997 CcWnnObject obj;
1998 {
1999 hiragana_katakana(obj, JC_HIRAGANA);
2000 }
2001
2002 static void
2003 katakana(obj)
2004 CcWnnObject obj;
2005 {
2006 hiragana_katakana(obj, JC_KATAKANA);
2007 }
2008
2009
2010 static void
2011 backspace(obj)
2012 CcWnnObject obj;
2013 {
2014 switch (obj->ccWnn.state) {
2015 case selection_l_state:
2016 endSelection(obj, False);
2017 (void)jcMove(JCBUF(obj), 0, JC_FORWARD);
2018 break;
2019 case selection_s_state:
2020 endSelection(obj, False);
2021 (void)jcMove(JCBUF(obj), 1, JC_FORWARD);
2022 break;
2023 case symbol_state:
2024 endSelection(obj, False);
2025 break;
2026 }
2027 ccContextDelete(CCBUF(obj));
2028 if (jcDeleteChar(JCBUF(obj), 1) < 0) beep(obj);
2029 HINT(obj) = True;
2030 }
2031
2032 static void
2033 backspace_c(obj)
2034 CcWnnObject obj;
2035 {
2036 switch (obj->ccWnn.state) {
2037 case selection_s_state:
2038 case selection_l_state:
2039 endSelection(obj, False);
2040 cancel(obj);
2041 break;
2042 case symbol_state:
2043 backspace(obj);
2044 break;
2045 default:
2046 if (jcIsConverted(JCBUF(obj), 0))
2047 cancel(obj);
2048 else
2049 backspace(obj);
2050 break;
2051 }
2052 }
2053
2054 static void
2055 delete(obj)
2056 CcWnnObject obj;
2057 {
2058 normalState(obj);
2059 if (jcDeleteChar(JCBUF(obj), 0) < 0) beep(obj);
2060 ccContextClear(CCBUF(obj));
2061 HINT(obj) = True;
2062 }
2063
2064 static void
2065 delete_c(obj)
2066 CcWnnObject obj;
2067 {
2068 switch (obj->ccWnn.state) {
2069 case selection_s_state:
2070 case selection_l_state:
2071 endSelection(obj, False);
2072 cancel(obj);
2073 break;
2074 case symbol_state:
2075 delete(obj);
2076 break;
2077 default:
2078 if (jcIsConverted(JCBUF(obj), JCBUF(obj)->curClause))
2079 cancel(obj);
2080 else
2081 delete(obj);
2082 break;
2083 }
2084 }
2085
2086 static void
2087 kill_line(obj)
2088 CcWnnObject obj;
2089 {
2090 normalState(obj);
2091 if (jcKillLine(JCBUF(obj)) < 0) beep(obj);
2092 ccContextClear(CCBUF(obj));
2093 HINT(obj) = True;
2094 }
2095
2096 static void
2097 bell(obj)
2098 CcWnnObject obj;
2099 {
2100 XBell(XtDisplayOfObject((Widget)obj), 0);
2101 }
2102
2103 static void
2104 beep(obj)
2105 CcWnnObject obj;
2106 {
2107 if (JCBUF(obj)->nClause == 0) return;
2108 bell(obj);
2109 }
2110
2111 static void
2112 jiscode_begin(obj)
2113 CcWnnObject obj;
2114 {
2115 obj->ccWnn.inputmode = JIS_MODE;
2116 }
2117
2118 static void
2119 jiscode_end(obj)
2120 CcWnnObject obj;
2121 {
2122 obj->ccWnn.inputmode = OTHERS;
2123 }
2124
2125 static void
2126 kuten_begin(obj)
2127 CcWnnObject obj;
2128 {
2129 obj->ccWnn.inputmode = KUTEN_MODE;
2130 }
2131
2132 static void
2133 kuten_end(obj)
2134 CcWnnObject obj;
2135 {
2136 obj->ccWnn.inputmode = OTHERS;
2137 }
2138
2139 static void
2140 carriageret(obj)
2141 CcWnnObject obj;
2142 {
2143 insChar('\r', (caddr_t)obj);
2144 fix(obj);
2145 }
2146
2147
2148 static void
2149 convend(obj)
2150 CcWnnObject obj;
2151 {
2152 fix(obj);
2153 /* $B%$%Y%s%H$rAw$jJV$5$J$$$h$&$K(B fixperformed $B$r%;%C%H$7$F$*$/(B */
2154 obj->ccWnn.fixperformed = True;
2155 XtCallCallbackList((Widget)obj, obj->inputConv.endcallback,
2156 (XtPointer)NULL);
2157 }
2158
2159
2160 static void
2161 send_back(obj)
2162 CcWnnObject obj;
2163 {
2164 obj->ccWnn.sendbackevent = True;
2165 }
2166
2167
2168 static void
2169 register_word(obj)
2170 CcWnnObject obj;
2171 {
2172 Widget w = obj->ccWnn.selwidget;
2173 Display *dpy;
2174
2175 TRACE(("register_word()\n"));
2176 if (w == NULL) {
2177 /*
2178 * $B%&%#%s%I%&$r;H$$$?$$$N$G!"<+J,$G(B widget $B$r0l$D:n$k!#(B
2179 * nonwidget $B$r?F$K$7$F(B widget $B$r:n@.$9$k$3$H$O2DG=$J$h$&$K(B
2180 * $B;W$($k$N$@$,!"$J$<$+$G$-$J$$$_$?$$$J$N$G!"$^$:$O(B widget $B$G$"$k(B
2181 * $B?F$rC5$7$F!"$=$3$K:n$k$3$H$K$9$k!#(B
2182 */
2183 Widget p = XtParent((Widget)obj);
2184
2185 while (p != NULL) {
2186 if (XtIsWidget(p)) break;
2187 p = XtParent(p);
2188 }
2189 if (p == NULL) {
2190 DPRINT(("register_word(): cannot find widget parent\n"));
2191 return;
2192 }
2193
2194 TRACE(("register_word(): creating core widget\n"));
2195 w = XtVaCreateWidget("for_selection", coreWidgetClass, p,
2196 XtNwidth, 1, XtNheight, 1, NULL);
2197 XtRealizeWidget(w);
2198 obj->ccWnn.selwidget = w;
2199 }
2200 saveYomiAndKanji(obj);
2201 if (obj->ccWnn.selyomi == NULL && obj->ccWnn.selkanji == NULL) return;
2202
2203 dpy = XtDisplay(w);
2204 XtOwnSelection(w, CachedInternAtom(dpy, CCWNN_REGISTER_ATOM, False),
2205 XtLastTimestampProcessed(dpy),
2206 convertSelection, NULL, NULL);
2207 }
2208
2209 static void
2210 sym_input(obj)
2211 CcWnnObject obj;
2212 {
2213 ICSelectionControlArg arg;
2214
2215 if (obj->ccWnn.state != normal_state) {
2216 beep(obj);
2217 return;
2218 }
2219 obj->ccWnn.state = symbol_state;
2220
2221 arg.command = ICSelectionStart;
2222 arg.u.selection_kind = ICSelectionSymbols;
2223 XtCallCallbackList((Widget)obj, obj->inputConv.selectioncallback,
2224 (XtPointer)&arg);
2225
2226 arg.command = ICSelectionSet;
2227 arg.u.current_item = obj->ccWnn.cursymbol;
2228 XtCallCallbackList((Widget)obj, obj->inputConv.selectioncallback,
2229 (XtPointer)&arg);
2230 }
2231
2232 static int
2233 getSymbol(obj, n)
2234 CcWnnObject obj;
2235 int n;
2236 {
2237 int c;
2238
2239 if (n < 0 || n >= obj->ccWnn.numsymbols) return -1;
2240
2241 c = *(wchar *)(obj->ccWnn.symbollist[n].data);
2242
2243 return c;
2244 }
2245
2246 static void
2247 startSelection(obj, small)
2248 CcWnnObject obj;
2249 int small;
2250 {
2251 ICSelectionControlArg arg;
2252 int ncand, curcand;
2253
2254 if (obj->ccWnn.state != normal_state) {
2255 beep(obj);
2256 return;
2257 }
2258
2259 if (jcCandidateInfo(JCBUF(obj), small, &ncand, &curcand) < 0) {
2260 beep(obj);
2261 return;
2262 }
2263
2264 getAllCandidates(obj, ncand);
2265
2266 obj->ccWnn.numcand = ncand;
2267 obj->ccWnn.curcand = curcand;
2268 obj->ccWnn.state = small ? selection_s_state : selection_l_state;
2269
2270 arg.command = ICSelectionStart;
2271 arg.u.selection_kind = ICSelectionCandidates;
2272 XtCallCallbackList((Widget)obj, obj->inputConv.selectioncallback,
2273 (XtPointer)&arg);
2274
2275 /* set current item */
2276 arg.command = ICSelectionSet;
2277 arg.u.current_item = curcand;
2278 XtCallCallbackList((Widget)obj, obj->inputConv.selectioncallback,
2279 (XtPointer)&arg);
2280 }
2281
2282 static void
2283 moveSelection(obj, dir)
2284 CcWnnObject obj;
2285 int dir;
2286 {
2287 ICSelectionControlArg arg;
2288
2289 if (obj->ccWnn.state == normal_state) return;
2290 arg.command = ICSelectionMove;
2291 arg.u.dir = dir;
2292 XtCallCallbackList((Widget)obj, obj->inputConv.selectioncallback,
2293 (XtPointer)&arg);
2294 }
2295
2296 static int
2297 endSelection(obj, abort)
2298 CcWnnObject obj;
2299 int abort;
2300 {
2301 ICSelectionControlArg arg;
2302 int selected;
2303 int ret = 0;
2304
2305 if (obj->ccWnn.selectionending) return 0;
2306
2307 if (obj->ccWnn.state == normal_state) return -1;
2308
2309 arg.command = ICSelectionEnd;
2310 arg.u.current_item = -1;
2311 XtCallCallbackList((Widget)obj, obj->inputConv.selectioncallback,
2312 (XtPointer)&arg);
2313
2314 if (!abort && (selected = arg.u.current_item) >= 0) {
2315 ret = insertSelection(obj, selected);
2316 }
2317 obj->ccWnn.state = normal_state;
2318
2319 return ret;
2320 }
2321
2322 static int
2323 insertSelection(obj, selected)
2324 CcWnnObject obj;
2325 int selected;
2326 {
2327 int state = obj->ccWnn.state;
2328 int ret = 0;
2329
2330 HINT(obj) = True;
2331
2332 obj->ccWnn.selectionending = True;
2333 if (state == symbol_state) {
2334 int c = getSymbol(obj, selected);
2335 if (c < 0) return -1;
2336 obj->ccWnn.cursymbol = selected;
2337 ccContextAppend(CCBUF(obj), c);
2338 insChar(c, (caddr_t)obj);
2339 } else {
2340 obj->ccWnn.curcand = selected;
2341 ret = jcSelect(JCBUF(obj), selected);
2342 }
2343 obj->ccWnn.selectionending = False;
2344
2345 return ret;
2346 }
2347
2348 static void
2349 normalState(obj)
2350 CcWnnObject obj;
2351 {
2352 switch (obj->ccWnn.state) {
2353 case selection_l_state:
2354 case selection_s_state:
2355 /* $B8uJdA*BrCf$G$"$l$P%+%l%s%H$N8uJd$rA*Br$7$FA*Br%b!<%I$+$iH4$1$k(B */
2356 case symbol_state:
2357 /* $B5-9fF~NOCf$G$"$l$P%+%l%s%H$N5-9f$rA*Br$7$F5-9f%b!<%I$+$iH4$1$k(B */
2358 endSelection(obj, False);
2359 break;
2360 }
2361 }
2362
2363 static void
2364 allocCandlist(obj, n)
2365 CcWnnObject obj;
2366 int n;
2367 {
2368 ICString *p;
2369
2370 if (n <= obj->ccWnn.candlistsize) return;
2371
2372 if (obj->ccWnn.candlistsize == 0) {
2373 p = (ICString *)XtMalloc(n * sizeof(ICString));
2374 } else {
2375 p = (ICString *)XtRealloc((char *)obj->ccWnn.candlist,
2376 n * sizeof(ICString));
2377 }
2378
2379 obj->ccWnn.candlist = p;
2380 obj->ccWnn.candlistsize = n;
2381 }
2382
2383 static void
2384 allocStrdata(obj, nchars)
2385 CcWnnObject obj;
2386 Cardinal nchars;
2387 {
2388 wchar *p;
2389
2390 if (nchars <= obj->ccWnn.strdatasize) return;
2391
2392 if (obj->ccWnn.strdatasize == 0) {
2393 if (nchars < 256) nchars = 256;
2394 p = (wchar *)XtMalloc(nchars * sizeof(wchar));
2395 } else {
2396 if (nchars - obj->ccWnn.strdatasize < 256)
2397 nchars = obj->ccWnn.strdatasize + 256;
2398 p = (wchar *)XtRealloc((char *)obj->ccWnn.strdata,
2399 nchars * sizeof(wchar));
2400 }
2401
2402 obj->ccWnn.strdata = p;
2403 obj->ccWnn.strdatasize = nchars;
2404 }
2405
2406 static void
2407 getAllCandidates(obj, ncand)
2408 CcWnnObject obj;
2409 int ncand;
2410 {
2411 ICString *strp;
2412 Cardinal nchars;
2413 wchar *p;
2414 int i;
2415 wchar buf[256];
2416
2417 allocCandlist(obj, ncand);
2418
2419 nchars = 0;
2420 for (i = 0, strp = obj->ccWnn.candlist; i < ncand; i++, strp++) {
2421 (void)jcGetCandidate(obj->ccWnn.jcbuf, i, buf);
2422 strp->nchars = wstrlen(buf);
2423 strp->nbytes = strp->nchars * sizeof(wchar);
2424 strp->attr = ICAttrNormalString;
2425 allocStrdata(obj, nchars + strp->nchars);
2426 (void)bcopy((char *)buf, (char *)(obj->ccWnn.strdata + nchars),
2427 strp->nbytes);
2428 nchars += strp->nchars;
2429 }
2430
2431 p = obj->ccWnn.strdata;
2432 for (i = 0, strp = obj->ccWnn.candlist; i < ncand; i++, strp++) {
2433 strp->data = (char *)p;
2434 p += strp->nchars;
2435 }
2436 }
2437
2438 /*
2439 * keeping list of objects
2440 */
2441 typedef struct _oblist_ {
2442 CcWnnObject obj;
2443 struct _oblist_ *next;
2444 } ObjRec;
2445
2446 static ObjRec *ObjList = NULL;
2447
2448 static void
2449 addObject(obj)
2450 CcWnnObject obj;
2451 {
2452 ObjRec *objp = XtNew(ObjRec);
2453
2454 objp->obj = obj;
2455 objp->next = ObjList;
2456 ObjList = objp;
2457 }
2458
2459 static void
2460 deleteObject(obj)
2461 CcWnnObject obj;
2462 {
2463 ObjRec *objp, *objp0;
2464
2465 for (objp0 = NULL, objp = ObjList;
2466 objp != NULL;
2467 objp0 = objp, objp = objp->next) {
2468 if (objp->obj == obj) {
2469 if (objp0 == NULL) {
2470 ObjList = objp->next;
2471 } else {
2472 objp0->next = objp->next;
2473 }
2474 XtFree((char *)objp);
2475 return;
2476 }
2477 }
2478 }
2479
2480 static void
2481 serverDead()
2482 {
2483 ObjRec *objp = ObjList;
2484
2485 while (objp != NULL) {
2486 if (objp->obj->ccWnn.wnnbuf != NULL
2487 && !jcIsConnect(objp->obj->ccWnn.wnnbuf)
2488 && wnn_errorno == WNN_JSERVER_DEAD) {
2489 if (objp->obj->ccWnn.jcbuf != NULL) {
2490 (void)jcDestroyBuffer(objp->obj->ccWnn.jcbuf, 0);
2491 objp->obj->ccWnn.jcbuf = NULL;
2492 }
2493 (void)jcClose(objp->obj->ccWnn.wnnbuf);
2494 objp->obj->ccWnn.wnnbuf = NULL;
2495 if (objp->obj->ccWnn.ccbuf != NULL) {
2496 ccContextClear(objp->obj->ccWnn.ccbuf);
2497 }
2498 }
2499 objp = objp->next;
2500 }
2501 }
2502
2503 static void
2504 saveData(obj)
2505 CcWnnObject obj;
2506 {
2507 wchar *wbuf;
2508 int len;
2509 jcConvBuf *jcbuf = obj->ccWnn.jcbuf;
2510
2511 len = jcbuf->kanaEnd - jcbuf->kanaBuf;
2512 if (len <= 0) return;
2513
2514 wbuf = (wchar *)XtMalloc((len + 1) * sizeof(wchar));
2515 (void)bcopy((char *)jcbuf->kanaBuf, (char *)wbuf,
2516 sizeof(wchar) * (len + 1));
2517 wbuf[len] = 0;
2518 obj->ccWnn.pendingdata = wbuf;
2519 }
2520
2521 static void
2522 restoreData(obj)
2523 CcWnnObject obj;
2524 {
2525 wchar *wp = obj->ccWnn.pendingdata;
2526
2527 if (wp == NULL) return;
2528
2529 while (*wp != 0) {
2530 jcInsertChar(obj->ccWnn.jcbuf, (int)*wp++);
2531 }
2532 XtFree((char *)obj->ccWnn.pendingdata);
2533
2534 obj->ccWnn.pendingdata = NULL;
2535 obj->ccWnn.textchanged = True;
2536 }
2537
2538 /* ARGSUSED */
2539 static void
2540 ioeCallback(dummy)
2541 XPointer dummy;
2542 {
2543 ObjRec *objp = ObjList;
2544
2545 /*
2546 * I/O Error callback function.
2547 * Does minimum cleanup -- i.e. saving dictionaries.
2548 */
2549 while (objp != NULL) {
2550 if (objp->obj->ccWnn.jcbuf != NULL) {
2551 jcSaveDic(objp->obj->ccWnn.jcbuf);
2552 }
2553 objp = objp->next;
2554 }
2555 }
2556
2557 static CcWnnObject
2558 findSelectionObj(w)
2559 Widget w;
2560 {
2561 ObjRec *objp = ObjList;
2562
2563 while (objp != NULL) {
2564 if (objp->obj->ccWnn.selwidget == w) return objp->obj;
2565 objp = objp->next;
2566 }
2567 return NULL;
2568 }
2569
2570 /* ARGSUSED */
2571 static int
2572 PreeditString(w, segn, offset, encoding, format, length, string)
2573 Widget w;
2574 int segn;
2575 int offset;
2576 Atom *encoding;
2577 int *format;
2578 int *length;
2579 XtPointer *string;
2580 {
2581 CcWnnObject obj = (CcWnnObject)w;
2582 jcConvBuf *jcbuf = obj->ccWnn.jcbuf;
2583 jcClause *cinfo = jcbuf->clauseInfo;
2584 wchar *wbuf, *wp;
2585 int len, wlen;
2586 extern int convJWStoCT();
2587
2588 if (jcbuf == NULL) return -1;
2589 if (segn < jcbuf->nClause &&
2590 offset >= (cinfo[segn + 1].dispp - cinfo[segn].dispp)) {
2591 /* $B%;%0%a%s%H$N:G8e(B */
2592 ++segn;
2593 offset = 0;
2594 }
2595 if (segn >= jcbuf->nClause ||
2596 offset >= (cinfo[segn + 1].dispp - cinfo[segn].dispp)) {
2597 /* $B:o=|$5$l$?(B */
2598 *encoding = XA_COMPOUND_TEXT(XtDisplayOfObject(w));
2599 *format = 8;
2600 *length = 0;
2601 *string = (XtPointer)XtMalloc(1);
2602 return 0;
2603 }
2604
2605 wlen = (cinfo[jcbuf->nClause].dispp - cinfo[segn].dispp) - offset;
2606
2607 /*
2608 * jcbuf $B$KF~$C$F$$$kJQ49%F%-%9%H$O(B null $B%?!<%_%M!<%H$5$l$F$$$J$$$N$G(B
2609 * $B$^$:%3%T!<$7$F(B null $B%?!<%_%M!<%H$9$k(B
2610 */
2611 wbuf = (wchar *)XtMalloc((wlen + 1) * sizeof(wchar));
2612 (void)bcopy((char *)(cinfo[segn].dispp + offset), (char *)wbuf, sizeof(wchar) * wlen);
2613 wbuf[wlen] = 0;
2614
2615 /*
2616 * CcWnn $B%*%V%8%'%/%H$O(B COMPOUND_TEXT $B%(%s%3!<%G%#%s%0$7$+%5%]!<%H$7$J$$(B
2617 * COMPOUND_TEXT $B$KJQ49$9$k(B
2618 */
2619 *encoding = XA_COMPOUND_TEXT(XtDisplayOfObject(w));
2620 *format = 8;
2621
2622 /* COMPOUND_TEXT $B$O(B \r $B$,Aw$l$J$$$N$G(B \n $B$KJQ49$7$F$*$/(B */
2623 for (wp = wbuf; *wp != 0; wp++) {
2624 if (*wp == '\r') *wp = '\n';
2625 }
2626
2627 *length = len = convJWStoCT(wbuf, (unsigned char *)NULL, 0);
2628 *string = (XtPointer)XtMalloc(len + 1);
2629 (void)convJWStoCT(wbuf, (unsigned char *)*string, 0);
2630
2631 /* wbuf $B$r(B free $B$7$F$*$/(B */
2632 XtFree((char *)wbuf);
2633
2634 return 0;
2635 }
2636
2637 /* ARGSUSED */
2638 static int
2639 StatusString(w, encoding, format, length, string, nchars)
2640 Widget w;
2641 Atom *encoding;
2642 int *format;
2643 int *length;
2644 XtPointer *string;
2645 int *nchars;
2646 {
2647 ICString *seg;
2648 wchar *wbuf, *wp;
2649 int len, wlen;
2650 extern int convJWStoCT();
2651
2652 seg = GetMode(w);
2653 if (seg == NULL) {
2654 *length = *nchars = 0;
2655 return -1;
2656 }
2657
2658 wlen = seg->nchars;
2659 if (wlen <= 0) {
2660 *length = *nchars = 0;
2661 return -1;
2662 }
2663
2664 /*
2665 * data $B$KF~$C$F$$$kJQ49%F%-%9%H$O(B null $B%?!<%_%M!<%H$5$l$F$$$J$$$+$b(B
2666 * $B$7$l$J$$$N$G!"$^$:%3%T!<$7$F(B null $B%?!<%_%M!<%H$9$k(B
2667 */
2668 wbuf = (wchar *)XtMalloc((wlen + 1) * sizeof(wchar));
2669 (void)bcopy(seg->data, (char *)wbuf, sizeof(wchar) * wlen);
2670 wbuf[wlen] = 0;
2671
2672 /*
2673 * CcWnn $B%*%V%8%'%/%H$O(B COMPOUND_TEXT $B%(%s%3!<%G%#%s%0$7$+%5%]!<%H$7$J$$(B
2674 * COMPOUND_TEXT $B$KJQ49$9$k(B
2675 */
2676 *encoding = XA_COMPOUND_TEXT(XtDisplayOfObject(w));
2677 *format = 8;
2678
2679 /* COMPOUND_TEXT $B$O(B \r $B$,Aw$l$J$$$N$G(B \n $B$KJQ49$7$F$*$/(B */
2680 for (wp = wbuf; *wp != 0; wp++) {
2681 if (*wp == '\r') *wp = '\n';
2682 }
2683
2684 *length = len = convJWStoCT(wbuf, (unsigned char *)NULL, 0);
2685 *string = XtMalloc(len + 1);
2686 (void)convJWStoCT(wbuf, (unsigned char *)*string, 0);
2687 *nchars = seg->nchars;
2688
2689 /* wbuf $B$r(B free $B$7$F$*$/(B */
2690 XtFree((char *)wbuf);
2691
2692 return 0;
2693 }
2694
2695 static Boolean
2696 convertSelection(w, selp, targetp, typep, valp, lenp, formatp)
2697 Widget w;
2698 Atom *selp;
2699 Atom *targetp;
2700 Atom *typep;
2701 XtPointer *valp;
2702 unsigned long *lenp;
2703 int *formatp;
2704 {
2705 CcWnnObject obj = findSelectionObj(w);
2706 int len;
2707 char *s, *data;
2708 Atom t = *targetp;
2709
2710 TRACE(("CcWnn:convertSelection()\n"));
2711
2712 if (obj == NULL) {
2713 DPRINT(("CcWnn:convertSelection(): cannot find selection object\n"));
2714 return False;
2715 }
2716
2717 /* $B%+%l%s%HJ8@a$NFI$_$^$?$O4A;z$rJV$9(B */
2718 if (t == CachedInternAtom(XtDisplay(w), CCWNN_YOMI_ATOM, True) ||
2719 t == CachedInternAtom(XtDisplay(w), "TEXT", True)) {
2720 data = obj->ccWnn.selyomi;
2721 } else if (t == CachedInternAtom(XtDisplay(w), CCWNN_KANJI_ATOM, True)) {
2722 data = obj->ccWnn.selkanji;
2723 } else {
2724 DPRINT(("CcWnn:convertSelection(): unknown target %s\n",
2725 CachedGetAtomName(XtDisplay(w), t)));
2726 return False;
2727 }
2728
2729 if (data != NULL) {
2730 len = strlen(data);
2731 s = XtMalloc(len + 1);
2732 strcpy(s, data);
2733 } else {
2734 len = 0;
2735 s = XtMalloc(1);
2736 *s = '\0';
2737 }
2738
2739 TRACE(("CcWnn:convertSelection(): sending yomi/kanji\n"));
2740 *typep = XA_COMPOUND_TEXT(XtDisplay(w));
2741 *valp = (XtPointer)s;
2742 *lenp = len;
2743 *formatp = 8;
2744 return True;
2745 }
2746
2747 static void
2748 saveYomiAndKanji(obj)
2749 CcWnnObject obj;
2750 {
2751 jcConvBuf *jcbuf = JCBUF(obj);
2752 int clnum = jcbuf->curClause;
2753 jcClause *cinfo = jcbuf->clauseInfo;
2754 wchar wbuf[1024];
2755 int wlen;
2756 int len;
2757
2758 TRACE(("CcWnn:saveYomiAndKanji()\n"));
2759
2760 if (obj->ccWnn.selyomi != NULL) {
2761 XtFree(obj->ccWnn.selyomi);
2762 obj->ccWnn.selyomi = NULL;
2763 }
2764 if (obj->ccWnn.selkanji != NULL) {
2765 XtFree(obj->ccWnn.selkanji);
2766 obj->ccWnn.selkanji = NULL;
2767 }
2768
2769 /* $B%+%l%s%HJ8@a$NFI$_$H4A;z$r<hF@(B */
2770 if (clnum == jcbuf->nClause) clnum--;
2771 if (clnum < 0) return;
2772
2773 /* $BFI$_(B */
2774 wlen = cinfo[clnum + 1].kanap - cinfo[clnum].kanap;
2775 memcpy(wbuf, cinfo[clnum].kanap, wlen * sizeof(wchar));
2776 wbuf[wlen] = 0;
2777 len = convJWStoCT(wbuf, (unsigned char *)NULL, 0);
2778 obj->ccWnn.selyomi = XtMalloc(len + 1);
2779 convJWStoCT(wbuf, obj->ccWnn.selyomi, 0);
2780
2781 /* $B4A;z(B */
2782 wlen = cinfo[clnum + 1].dispp - cinfo[clnum].dispp;
2783 memcpy(wbuf, cinfo[clnum].dispp, wlen * sizeof(wchar));
2784 wbuf[wlen] = 0;
2785 len = convJWStoCT(wbuf, (unsigned char *)NULL, 0);
2786 obj->ccWnn.selkanji = XtMalloc(len + 1);
2787 convJWStoCT(wbuf, obj->ccWnn.selkanji, 0);
2788 }