comparison lib/Atok.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 /*
2 * Copyright (c) 1990 Software Research Associates, Inc.
3 *
4 * Permission to use, copy, modify, and distribute this software and its
5 * documentation for any purpose and without fee is hereby granted, provided
6 * that the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name of Software Research Associates not be
9 * used in advertising or publicity pertaining to distribution of the
10 * software without specific, written prior permission. Software Research
11 * Associates makes no representations about the suitability of this software
12 * for any purpose. It is provided "as is" without express or implied
13 * warranty.
14 *
15 * Author: Makoto Ishisone, Software Research Associates, Inc., Japan
16 */
17
18 /* Copyright 1991 NEC Corporation, Tokyo, Japan.
19 *
20 * Permission to use, copy, modify, and distribute this software and its
21 * documentation for any purpose and without fee is hereby granted,
22 * provided that the above copyright notice appear in all copies and that
23 * both that copyright notice and this permission notice appear in
24 * supporting documentation, and that the name of NEC Corporation
25 * not be used in advertising or publicity pertaining to distribution
26 * of the software without specific, written prior permission. NEC
27 * Corporation makes no representations about the suitability of this
28 * software for any purpose. It is provided "as is" without express
29 * or implied warranty.
30 *
31 * NEC CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
32 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
33 * NO EVENT SHALL NEC CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
34 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
35 * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
36 * OTHER TORTUOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
37 * PERFORMANCE OF THIS SOFTWARE.
38 *
39 * Author: Akira Kon, NEC Corporation. (kon@d1.bs2.mt.nec.co.jp)
40 */
41
42 /*
43 * Copyright 1999 Justsystem Corporation, Japan.
44 *
45 * Permission to use, copy, modify, and distribute this software and its
46 * documentation for any purpose and without fee is hereby granted,
47 * provided that the above copyright notice appear in all copies and that
48 * both that copyright notice and this permission notice appear in
49 * supporting documentation, and that the name of Justsystem Corporation
50 * not be used in advertising or publicity pertaining to distribution
51 * of the software without specific, written prior permission. Justsystem
52 * Corporation makes no representations about the suitability of this
53 * software for any purpose. It is provided "as is" without express
54 * or implied warranty.
55 *
56 * Author: Atsushi Irisawa
57 */
58
59 #ifndef lint
60 static char *rcsid = "$Id: Atok.c,v 1.3 1999/08/24 08:59:35 ishisone Exp $";
61 #endif
62
63 #include <X11/IntrinsicP.h>
64 #include <X11/StringDefs.h>
65 #include <X11/Xmu/Atoms.h>
66 #define XK_KATAKANA
67 #include <X11/keysym.h>
68 #if XtSpecificationRelease > 4
69 #include <X11/Xfuncs.h>
70 #endif
71 #include "AtokP.h"
72 #include "key_def.h"
73 #include "DebugPrint.h"
74
75 #define _WCHAR_T
76 #define wchar_t wchar
77
78 #ifdef SVR4
79 #define bzero(p, l) memset(p, 0, l)
80 #else
81 #if defined(SYSV) || defined(USG)
82 #define OVERLAP_BCOPY
83 extern char *memset();
84 #define bzero(p, l) memset(p, 0, l)
85 #endif
86 #endif
87
88 static XtResource resources[] = {
89 #define offset(field) XtOffset(AtokObject, atok.field)
90 { XtNAtokServer, XtCAtokServer, XtRString, sizeof(String),
91 offset(atokserver), XtRString, NULL },
92 { XtNConfFile, XtCConfFile, XtRString, sizeof(String),
93 offset(conffile), XtRString, NULL },
94 { XtNStyleFile, XtCStyleFile, XtRString, sizeof(String),
95 offset(stylefile), XtRString, NULL },
96 { XtNPort, XtCPort, XtRString, sizeof(String),
97 offset(port), XtRString, NULL },
98 #undef offset
99 };
100
101 static void ClassInitialize();
102 static void Initialize();
103 static void Destroy();
104 static Boolean SetValues();
105 static int InputEvent();
106 static ICString *GetMode();
107 static int CursorPos();
108 static int NumSegments();
109 static ICString *GetSegment();
110 static int CompareSegment();
111 static ICString *GetItemList();
112 static int SelectItem();
113 static int ConvertedString();
114 static int ClearConversion();
115 static ICString *GetAuxSegments();
116 static int PreeditString();
117 static int StatusString();
118
119 AtokClassRec atokClassRec = {
120 { /* object fields */
121 /* superclass */ (WidgetClass) &inputConvClassRec,
122 /* class_name */ "Atok",
123 /* widget_size */ sizeof(AtokRec),
124 /* class_initialize */ ClassInitialize,
125 /* class_part_initialize */ NULL,
126 /* class_inited */ FALSE,
127 /* initialize */ Initialize,
128 /* initialize_hook */ NULL,
129 /* obj1 */ NULL,
130 /* obj2 */ NULL,
131 /* obj3 */ 0,
132 /* resources */ resources,
133 /* num_resources */ XtNumber(resources),
134 /* xrm_class */ NULLQUARK,
135 /* obj4 */ FALSE,
136 /* obj5 */ FALSE,
137 /* obj6 */ FALSE,
138 /* obj7 */ FALSE,
139 /* destroy */ Destroy,
140 /* obj8 */ NULL,
141 /* obj9 */ NULL,
142 /* set_values */ SetValues,
143 /* set_values_hook */ NULL,
144 /* obj10 */ NULL,
145 /* get_values_hook */ NULL,
146 /* obj11 */ NULL,
147 /* version */ XtVersion,
148 /* callback_private */ NULL,
149 /* obj12 */ NULL,
150 /* obj13 */ NULL,
151 /* obj14 */ NULL,
152 /* extension */ NULL
153 },
154 { /* inputConv fields */
155 /* InputEvent */ InputEvent,
156 /* GetMode */ GetMode,
157 /* CursorPos */ CursorPos,
158 /* NumSegments */ NumSegments,
159 /* GetSegment */ GetSegment,
160 /* CompareSegment */ CompareSegment,
161 /* GetItemList */ GetItemList,
162 /* SelectItem */ SelectItem,
163 /* GetConvertedString */ ConvertedString,
164 /* ClearConversion */ ClearConversion,
165 /* GetAuxSegments */ GetAuxSegments,
166 /* SupportMultipleObjects */ True,
167 /* GetTriggerKeys */ XtInheritGetTriggerKeys,
168 /* num_trigger_keys */ 0,
169 /* trigger_keys */ NULL,
170 /* GetPreeditString */ PreeditString,
171 /* GetStatusString */ StatusString,
172 /* NoMoreObjects */ False,
173 },
174 { /* atok fields */
175 /* foo */ 0,
176 }
177 };
178
179 WidgetClass atokObjectClass = (WidgetClass)&atokClassRec;
180
181 static int bell();
182 static void fix();
183 static void fixProcForAtok();
184 static void convend();
185
186 static void addObject();
187 static void deleteObject();
188
189 static void atokDisplay();
190 static int atokCandDisplay();
191 static int atokAuxDisplay();
192
193 static void moveLeft();
194 static void moveRight();
195 static void setSelection();
196 static void moveSelection();
197 static void querySelection();
198 static void endSelection();
199 static void insertSelection();
200 static int allocCandList();
201 static int changeTextForAtok();
202 static int changeTextForAtokAUX();
203 static void startSelection();
204 static int makeCandList();
205
206 static void copyInWchar();
207
208 static Display *displaybell = (Display *)0;
209
210 static int clientID = -1;
211 static int nAtokContexts = 0;
212 static int ceSock = -1;
213
214
215 static void
216 ClassInitialize()
217 {
218 DPRINT(( "ATOK Class Initialize\n" ));
219 TRACE(("AtokObjectClass initialized\n"));
220 /* $B2?$b$7$J$$(B */
221 }
222
223 /* ARGSUSED */
224 static void
225 Initialize(req, new, args, num_args)
226 Widget req;
227 Widget new;
228 ArgList args;
229 Cardinal *num_args;
230 {
231 AtokObject obj = (AtokObject)new;
232 AtokObject objX = (AtokObject)req;
233 int sock;
234 menuAux *orgMenuAux;
235 char buf[256];
236 int isConnect = 1;
237 int i;
238
239 bzero((char *)&obj->atok, sizeof(obj->atok));
240
241 obj->atok.textchanged = False;
242 obj->atok.nbr_of_cand = 0;
243 obj->atok.cand_lists_ics = NULL;
244 obj->atok.cur_cand = 0;
245
246 for (i = 0; i < NBR_OF_PART; i++) {
247 obj->atok.aux_ics[i].data = (char *)NULL;
248 obj->atok.aux_ics[i].nchars = 0;
249 obj->atok.aux_ics[i].nbytes = 0;
250 obj->atok.aux_length[i] = 0;
251 obj->atok.aux_size[i] = 0;
252 }
253
254 if (objX->atok.atokserver)
255 obj->atok.atokserver = objX->atok.atokserver;
256 if (objX->atok.port)
257 obj->atok.port = objX->atok.port;
258 if (objX->atok.conffile)
259 obj->atok.conffile = objX->atok.conffile;
260
261 /* $BF~NO%P%C%U%!$r:n@.$9$k!#(B*/
262 obj->atok.comm = (_XatokRecPtr)XtMalloc(sizeof(_XatokRec));
263 bzero((char *)obj->atok.comm, sizeof(_XatokRec));
264 obj->atok.comm->echoLen = 0;
265 /* obj->atok.sock = ceSock; */
266
267 if (!nAtokContexts) {
268 ceSock = atokConnect(obj->atok.atokserver,
269 obj->atok.port,
270 obj->atok.conffile,
271 obj->atok.stylefile,
272 /*
273 obj->atok.conffile ?
274 obj->atok.conffile : "atok12.conf",
275 obj->atok.stylefile ?
276 obj->atok.stylefile : "atok12.sty",
277 */
278 obj->atok.comm);
279 if (ceSock < 0) {
280 XtAppWarning(XtWidgetToApplicationContext((Widget)obj),
281 "Cannot connect to ATOK server");
282 /* exit(0); */
283 XtFree((char *)obj->atok.comm);
284 obj->atok.comm = (_XatokRecPtr)NULL;
285 return;
286 }
287 isConnect = 0;
288 obj->atok.comm->sock = ceSock;
289 clientID = obj->atok.comm->NETrqst.clntid;
290 }
291
292 obj->atok.comm->sock = ceSock;
293
294 addObject(obj, ceSock, clientID, isConnect);
295
296 orgMenuAux = getMenuInstance();
297 obj->atok.comm->menuAux = auxMenuCopy(orgMenuAux);
298 obj->atok.comm->curAux = obj->atok.comm->menuAux;
299 XtCallCallbackList((Widget) obj, obj->inputConv.modechangecallback,
300 (XtPointer)NULL);
301 nAtokContexts++;
302 }
303
304 static void
305 Destroy(w)
306 Widget w;
307 {
308 AtokObject obj = (AtokObject)w;
309
310 if (obj->atok.comm) XtFree((char *)obj->atok.comm);
311 deleteObject(obj);
312 }
313
314 /* ARGSUSED */
315 static Boolean SetValues(cur, req, wid, args, num_args)
316 Widget cur;
317 Widget req;
318 Widget wid;
319 ArgList args;
320 Cardinal *num_args;
321 {
322 AtokObject old = (AtokObject)cur;
323 AtokObject new = (AtokObject)wid;
324
325 return False;
326 }
327
328
329 static int
330 XKanaLookup(event_struct, buffer_return, bytes_buffer,
331 keysym, status_return)
332 XKeyEvent *event_struct;
333 char *buffer_return;
334 int bytes_buffer;
335 KeySym *keysym;
336 XComposeStatus *status_return;
337 {
338 int res;
339 res = XLookupString(event_struct, buffer_return, bytes_buffer,
340 keysym, status_return);
341 if (!res && XK_overline <= *keysym && *keysym <= XK_semivoicedsound) {
342 buffer_return[0] = (unsigned long)(*keysym) & 0xff;
343 res = 1;
344 }
345 return res;
346 }
347
348
349 /*
350 * Kinput2 API Functions
351 */
352
353 static int
354 InputEvent(w, event)
355 Widget w;
356 XEvent *event;
357 {
358 AtokObject obj = (AtokObject)w;
359 wchar wbuf[BUFSIZ*4]; /* $B3NDjJ8;zNs$N%P%C%U%!(B */
360 int wlen; /* $B3NDjJ8;zNs$ND9$5(B */
361 unsigned char kbuf[BUFSIZ]; /* $B%-!<F~NO%G!<%?(B */
362 int nbytes; /* $B%-!<F~NO$ND9$5(B */
363 KeySym ks; /* X$B$N%-!<%7%s%\%k(B */
364 XComposeStatus comp_status;
365 WORD aajcode; /* AAJCODE */
366 int kanjiStatus;
367 int enableStatus;
368 int changeStatus;
369 int elseEvent;
370 int status;
371 int isThrue = 0;
372
373 DPRINT(( "\n### NEW EVENT \n" ));
374
375 /* KeyPress$B0J30$O<N$F$k(B */
376 if (event->type != KeyPress /*&& event->type != KeyRelease*/) return 0;
377
378 obj->atok.textchanged = False;
379
380 /*
381 * AtokServer $B$,(B $B:F5/F0$5$l$?$P$"$$$J$I!"%3%M%/%7%g%s$,$-$l$F$$$k>l9g$,(B
382 * $B$"$k$N$G(B $B:FEY%3%M%/%7%g%s$rD%$C$F$_$k!#(B
383 */
384 if (obj->atok.comm == NULL) {
385 /* return -1; /* $B@\B3$G$-$F$$$J$$$H$-$O!"%(%i!<$rJV$9(B */
386 return 1; /* $B@\B3$G$-$F$$$J$$$H$-$O!"L5;k$9$k(B */
387 }
388
389 /* X $B$N%-!<%$%Y%s%H$r<hF@$9$k!#(B*/
390 kbuf[0] = '\0';
391 nbytes = XKanaLookup((XKeyEvent*)event, kbuf, sizeof(kbuf), &ks,
392 &comp_status);
393
394 wbuf[0] = (wchar)kbuf[0]; /* $B$-$?$J$$(B */
395
396 DPRINT(("nbytes %d\n", nbytes));
397
398 /* $BMW$i$J$$>l9g$OL5;k$9$k(B */
399 if (nbytes == 0 && ks & 0xff00 == 0) return 1;
400
401 /* $B%Y%k$rLD$i$9%G%#%9%W%l%$$N@_Dj(B */
402 displaybell = XtDisplayOfObject((Widget)obj);
403
404 /*
405 * $B8uJd%&%#%s%I%&$,(BACTIVE $B$K$J$C$F$$$?>l9g$N8uJd$N0\F0$O(B
406 * Kinput2 $B$h$j(B Callback $B$,8F$S=P$5$l$:!"A*Br$5$l$F$$$kHV9f$,(B
407 * $B<hF@$G$-$J$$$N$G!"$3$3$G0lEY(B $BA*Br$5$l$F$$$kHV9f$r<hF@$9$k!#(B
408 */
409 if (obj->atok.comm->convStatus & M_CAND) {
410 querySelection(obj);
411 }
412
413 /*
414 * $B%-!<F~NO$r85$K(B AAJCODE$B$KJQ49$7!"(BCE$B$X$N%j%/%(%9%H$r9T$&!#(B
415 * $B%j%/%(%9%H7k2L$K4p$E$$$F!"I=<($d%b!<%I$rJQ99$9$k!#(B
416 * $B3NDjJ8;zNs$,$"$C$?>l9g$K$O!"%j%?!<%s$H$7$F!"$=$NJ8;zNs$ND9$5$,(B
417 * $BJV$C$F$/$k!#(B
418 * $B$3$l0J9_$N=hM}$O(B $B2hLL$KI=<($9$k$?$a$NJ*$G$"$k!#(B
419 */
420 wlen = XatokEventControl(obj->atok.comm, event, ks, kbuf, nbytes,
421 &aajcode, &kanjiStatus, &enableStatus,
422 &changeStatus, &elseEvent);
423
424 if (!aajcode) {
425 /* Can't convertsion to AAJ CODE */
426 return 0;
427 }
428
429 if (obj->atok.comm->convStatus == M_NOKEYCONV) {
430 convend(obj);
431 return 0;
432 }
433
434 /*
435 * $B$3$3$+$i2<$O(B kanjiStatus $B$G;XDj$5$l$F$$$k%b!<%I$N=hM}$r(B
436 * $B9T$$!"2hLL$KI=<($9$k!#(B
437 * $B8uJd0lMw!"!"<-=q!"3NDj$J$I$K2r$l$k!#(B
438 *
439 * $BDL>o$N%-!<F~NO$N>l9g(B
440 * $B8uJd0lMwI=<(Cf$N>l9g(B
441 * $B<-=q%f!<%F%#%j%F%#!<I=<(Cf$N>l9g(B
442 */
443 switch(kanjiStatus) {
444 case KRS_UNCHANGED: /* $B%9%k!<3NDj(B */
445 isThrue = 1 ;
446 obj->atok.comm->wlen = 0 ;
447 obj->atok.comm->wbuf[0] = aajcode ;
448 break;
449 case KRS_BACKSPACE:
450 case KRS_SOFTBACKSPACE:
451 case KRS_SOFTCARRIAGERETURN:
452 case KRS_EXTTANGO_OPEN:
453 default:
454 break;
455 }
456 status = 0;
457 if (enableStatus) {
458 if (elseEvent & EVENTB_BEEP) {
459 bell();
460 }
461 /* $B%b!<%I$NJQ99$,$"$C$?(B */
462 if (changeStatus & ATCHANGEB_MODESTR) {
463 XtCallCallbackList((Widget)obj, obj->inputConv.modechangecallback,
464 (XtPointer)NULL);
465 }
466 if (changeStatus & ATCHANGEB_RESULTSTR) {
467 /* do nothing */
468 }
469 if (changeStatus & ATCHANGEB_COMPSTR) {
470 /* do nothing */
471 }
472 /* $B<!8uJd%&%#%s%I%&99?7(B */
473 if (changeStatus &
474 (ATCHANGEB_RECTOPEN | ATCHANGEB_RECTCLOSE | ATCHANGEB_RECTCHANGE))
475 {
476 /* do nothing */
477 }
478 if (changeStatus & (ATCHANGEB_SYSLSTR | ATCHANGEB_SYSLTOSYSL)) {
479 /*
480 * auxSyslineCtrl() $B$N(B return $B$,#00J30$N;~$O!"(B
481 * $B%7%9%F%`9T$NI=<($,=*N;$N;~$G$"$j!"(B
482 * $B3NDjJ8;zNs$,B8:_$9$k2DG=@-$,$"$k$N$G(B
483 * $B%7%9%F%`9T$r>C$7$F$+$i(B
484 * AuxDisplay()$B$r8F$S=P$9I,MW$,$"$k!#(B
485 */
486 status = auxSyslineCtrl(obj->atok.comm,
487 changeStatus & ATCHANGEB_RESULTSTR);
488 atokAuxDisplay(obj, M_SYSLINE);
489 /*
490 if (!status) {
491 DPRINT(("SYSLINE END\n"));
492 return 0;
493 }
494 */
495 }
496 }
497 /*
498 * $B$3$3$+$i2<$O(B $BI=<($N%3%s%H%m!<%k(B
499 * $BF~NO$5$l$?%-!<$K$h$j=hM}$rJ,$1$F$$$k!#(B
500 */
501 if (obj->atok.comm->convStatus & M_CAND) {
502 status = atokCandDisplay(obj, (int)aajcode);
503 if (status < 1) {
504 return 0;
505 }
506 }
507 /* else */
508 if (obj->atok.comm->convStatus & M_AUX) {
509 status = atokAuxDisplay(obj, obj->atok.comm->convStatus);
510 if (status < 1) {
511 return;
512 }
513 }
514 else if (obj->atok.comm->convStatus & M_SYSLINE && !status) {
515 status = auxSyslineCtrl(obj->atok.comm,
516 changeStatus & ATCHANGEB_RESULTSTR);
517 atokAuxDisplay(obj, obj->atok.comm->convStatus);
518 if (!status) {
519 return 0;
520 }
521 }
522 else if (kanjiStatus == XKEY_DICT) {
523 /* $B<-=q%f!<%F%#%j%F%#!<I=<(;~$N%-!<F~NO(B */
524 }
525 /* $B$=$NB>$N>l9g$N%-!<F~NO(B */
526 if (obj->atok.comm->convStatus & M_KEYCONV) {
527 atokDisplay(obj, &kanjiStatus);
528 }
529
530 return isThrue;
531 }
532
533 static ICString *
534 GetMode(w)
535 Widget w;
536 {
537 AtokObject obj = (AtokObject)w;
538 _XatokRecPtr acomm = obj->atok.comm;
539 int len;
540 static ICString icstr;
541
542 if (acomm == NULL) return NULL; /* Not connected */
543
544 icstr.data = (char *)XatokGetModeStr(acomm, &len);
545 icstr.nchars = len;
546 icstr.nbytes = icstr.nchars * sizeof(wchar);
547 icstr.attr = ICAttrNormalString;
548
549 return &icstr;
550 }
551
552 static int
553 CursorPos(w, nsegp, ncharp)
554 Widget w;
555 Cardinal *nsegp;
556 Cardinal *ncharp;
557 {
558 AtokObject obj = (AtokObject)w;
559 _XatokRecPtr acomm = obj->atok.comm;
560
561 if (acomm == NULL) return 0; /* Not connected */
562
563 return XatokGetSegmentPosition(acomm, nsegp, ncharp);
564 }
565
566 static int
567 NumSegments(w)
568 Widget w;
569 {
570 AtokObject obj = (AtokObject)w;
571 _XatokRecPtr acomm = obj->atok.comm;
572
573 if (acomm == NULL) return 0; /* Not connected */
574
575 return XatokGetSegmentNumber(acomm);
576 }
577
578 static ICString *
579 GetSegment(w, n)
580 Widget w;
581 Cardinal n;
582 {
583 AtokObject obj = (AtokObject)w;
584 _XatokRecPtr acomm = obj->atok.comm;
585 int len;
586 int attr;
587 static ICString seg;
588
589 if (acomm == NULL) return NULL; /* Not connected */
590
591 seg.data = (char *)XatokGetSegmentRec(acomm, n, &len, &attr);
592 seg.nchars = len;
593 seg.nbytes = seg.nchars * sizeof(wchar);
594 seg.attr = attr;
595
596 return &seg;
597 }
598
599 /* ARGSUSED */
600 static int
601 CompareSegment(w, seg1, seg2, n)
602 Widget w;
603 ICString *seg1;
604 ICString *seg2;
605 Cardinal *n;
606 {
607 wchar *p, *q;
608 int len, nsame;
609 int result = 0;
610
611 if (seg1->attr != seg2->attr) result |= ICAttrChanged;
612
613 len = seg1->nchars > seg2->nchars ? seg2->nchars : seg1->nchars;
614 nsame = 0;
615 p = (wchar *)seg1->data;
616 q = (wchar *)seg2->data;
617 while (nsame < len && *p++ == *q++) nsame++;
618
619 if (nsame != len || len != seg1->nchars || len != seg2->nchars)
620 result |= ICStringChanged;
621
622 if (n) *n = nsame;
623
624 return result;
625 }
626
627 static ICString *
628 GetItemList(w, n)
629 Widget w;
630 Cardinal *n;
631 {
632 AtokObject obj = (AtokObject)w;
633
634 #ifdef CAND_PAGE
635 *n = (CAND_ROWS * CAND_COLS) + 1; /* +1 $B$O(B $B8uJd?t(B */
636 #else
637 *n = obj->atok.nbr_of_cand;
638 #endif /* CAND_PAGE */
639
640 return obj->atok.cand_lists_ics;
641 }
642
643 static int
644 SelectItem(w, n)
645 Widget w;
646 int n;
647 {
648 AtokObject obj = (AtokObject)w;
649 _XatokRecPtr acomm = obj->atok.comm;
650 int changed = FALSE;
651 int status = 0;
652
653 if (acomm == NULL) return -1; /* Not connected */
654
655 if (n >= 0) obj->atok.selected_cand = n;
656
657 /* ATOK $B$N3NDj(BFUNC$B$r8F$S=P$9!#(B */
658 if (changed) {
659 XtCallCallbackList((Widget)obj, obj->inputConv.fixcallback,
660 (XtPointer)NULL);
661 /* ATOK $B$N%P%C%U%!$b(BFLUSH$B$9$k!#(B */
662 XtCallCallbackList((Widget)obj, obj->inputConv.textchangecallback,
663 (XtPointer)NULL);
664 }
665
666 return status;
667 }
668
669 static int
670 ConvertedString(w, encoding, format, length, string)
671 Widget w;
672 Atom *encoding;
673 int *format;
674 int *length;
675 XtPointer *string;
676 {
677 AtokObject obj = (AtokObject)w;
678 _XatokRecPtr acomm = obj->atok.comm;
679 wchar *wbuf, *wp;
680 int len, wlen;
681 extern int convJWStoCT();
682
683 if (acomm == NULL || acomm->nbr_of_seg == 0 || acomm->offset == 0)
684 return -1;
685
686 wlen = acomm->segments[acomm->offset -1].length;
687 wbuf = acomm->segments[acomm->offset -1].string;
688
689 /*
690 * Atok $B%*%V%8%'%/%H$O(B COMPOUND_TEXT $B%(%s%3!<%G%#%s%0$7$+%5%]!<%H$7$J$$(B
691 * COMPOUND_TEXT $B$KJQ49$9$k(B
692 */
693 *encoding = XA_COMPOUND_TEXT( XtDisplayOfObject(( Widget )obj ));
694 *format = 8;
695
696 /* COMPOUND_TEXT $B$O(B \r $B$,Aw$l$J$$$N$G(B \n $B$KJQ49$7$F$*$/(B */
697 for (wp = wbuf; *wp != 0; wp++ ) {
698 if (*wp == '\r') *wp = '\n';
699 }
700
701 *length = len = convJWStoCT(wbuf, (unsigned char *)NULL, 0);
702 *string = XtMalloc(len + 1);
703 (void)convJWStoCT(wbuf, (unsigned char *)*string, 0);
704
705 XatokShiftLeftAll(acomm);
706
707 return 0;
708 }
709
710 static int
711 ClearConversion(w)
712 Widget w;
713 {
714 AtokObject obj = (AtokObject)w;
715 _XatokRecPtr acomm = obj->atok.comm;
716
717 if (acomm == NULL) return -1; /* Not connected */
718
719 XatokClearBuffer(acomm);
720 XtCallCallbackList((Widget)obj, obj->inputConv.textchangecallback,
721 (XtPointer)NULL);
722 return 0;
723 }
724
725 static ICString *
726 GetAuxSegments(w, n, ns, nc)
727 Widget w;
728 Cardinal *n, *ns, *nc;
729 {
730 AtokObject obj = (AtokObject)w;
731 Cardinal nseg, nchar;
732
733 if (obj->atok.comm == NULL) return NULL; /* Not connected */
734
735 if (n) {
736 *n = obj->atok.aux_nseg;
737 }
738
739 if (obj->atok.aux_curseg < obj->atok.aux_nseg) {
740 nseg = obj->atok.aux_curseg;
741 nchar = 0;
742 }
743 else {
744 nseg = 0;
745 nchar = obj->atok.aux_length[0];
746 }
747 if (ns) {
748 *ns = nseg;
749 }
750 if (nc) {
751 *nc = nchar;
752 }
753
754 return obj->atok.aux_ics;
755 }
756
757 /* ARGSUSED */
758 static int
759 PreeditString(w, segn, offset, encoding, format, length, string)
760 Widget w;
761 int segn;
762 int offset;
763 Atom *encoding;
764 int *format;
765 int *length;
766 XtPointer *string;
767 {
768 AtokObject obj = (AtokObject)w;
769 _XatokRecPtr acomm = obj->atok.comm;
770 int i;
771 wchar *wbuf, *wp;
772 int len, wlen;
773 extern int convJWStoCT();
774
775 if (acomm == NULL) return -1;
776 if (segn < acomm->nbr_of_seg && offset >= acomm->segments[segn].length) {
777 /* $B%;%0%a%s%H$N:G8e(B */
778 ++segn;
779 offset = 0;
780 }
781 if (segn >= acomm->nbr_of_seg || offset >= acomm->segments[segn].length) {
782 /* $B:o=|$5$l$?(B */
783 *encoding = XA_COMPOUND_TEXT(XtDisplayOfObject(w));
784 *format = 8;
785 *length = 0;
786 *string = (XtPointer)XtMalloc(1);
787 return 0;
788 }
789
790 wlen = 0;
791 for (i = segn; i < acomm->nbr_of_seg; i++) {
792 wlen += acomm->segments[i].length;
793 }
794 wlen -= offset;
795
796 wp = wbuf = (wchar *)XtMalloc((wlen + 1) * sizeof(wchar));
797 len = acomm->segments[segn].length - offset;
798 (void)bcopy((char *)(acomm->segments[segn].string + offset),
799 (char *)wp,
800 sizeof(wchar) * len);
801 wp += len;
802 for (i = segn + 1; i < acomm->nbr_of_seg; i++) {
803 len = acomm->segments[i].length;
804 (void)bcopy((char *)acomm->segments[i].string,
805 (char *)wp,
806 sizeof(wchar) * len);
807 wp += len;
808 }
809 wbuf[wlen] = 0;
810
811 /*
812 * Atok $B%*%V%8%'%/%H$O(B COMPOUND_TEXT $B%(%s%3!<%G%#%s%0$7$+%5%]!<%H$7$J$$(B
813 * COMPOUND_TEXT $B$KJQ49$9$k(B
814 */
815 *encoding = XA_COMPOUND_TEXT(XtDisplayOfObject((Widget)obj));
816 *format = 8;
817
818 /* COMPOUND_TEXT $B$O(B \r $B$,Aw$l$J$$$N$G(B \n $B$KJQ49$7$F$*$/(B */
819 for (wp = wbuf; *wp != 0; wp++) {
820 if (*wp == '\r') *wp = '\n';
821 }
822
823 *length = len = convJWStoCT(wbuf, (unsigned char *)NULL, 0);
824 *string = (XtPointer)XtMalloc(len + 1);
825 (void)convJWStoCT(wbuf, (unsigned char *)*string, 0);
826
827 /* wbuf $B$r(B free $B$7$F$*$/(B */
828 XtFree((char *)wbuf);
829
830 return 0;
831 }
832
833 /* ARGSUSED */
834 static int
835 StatusString(w, encoding, format, length, string, nchars)
836 Widget w;
837 Atom *encoding;
838 int *format;
839 int *length;
840 XtPointer *string;
841 int *nchars;
842 {
843 ICString *seg;
844 wchar *wbuf, *wp;
845 int len, wlen;
846 extern int convJWStoCT();
847
848 seg = GetMode(w);
849 if (seg == NULL) {
850 *length = *nchars = 0;
851 return -1;
852 }
853
854 wlen = seg->nchars;
855 if (wlen <= 0) {
856 *length = *nchars = 0;
857 return -1;
858 }
859
860 /*
861 * data $B$KF~$C$F$$$kJQ49%F%-%9%H$O(B null $B%?!<%_%M!<%H$5$l$F$$$J$$$+$b(B
862 * $B$7$l$J$$$N$G!"$^$:%3%T!<$7$F(B null $B%?!<%_%M!<%H$9$k(B
863 */
864 wbuf = (wchar *)XtMalloc((wlen + 1) * sizeof(wchar));
865 (void)bcopy(seg->data, (char *)wbuf, sizeof(wchar) * wlen);
866 wbuf[wlen] = 0;
867
868 /*
869 * Canna $B%*%V%8%'%/%H$O(B COMPOUND_TEXT $B%(%s%3!<%G%#%s%0$7$+%5%]!<%H$7$J$$(B
870 * COMPOUND_TEXT $B$KJQ49$9$k(B
871 */
872 *encoding = XA_COMPOUND_TEXT(XtDisplayOfObject(w));
873 *format = 8;
874
875 /* COMPOUND_TEXT $B$O(B \r $B$,Aw$l$J$$$N$G(B \n $B$KJQ49$7$F$*$/(B */
876 for (wp = wbuf; *wp != 0; wp++) {
877 if (*wp == '\r') *wp = '\n';
878 }
879
880 *length = len = convJWStoCT(wbuf, (unsigned char *)NULL, 0);
881 *string = XtMalloc(len + 1);
882 (void)convJWStoCT(wbuf, (unsigned char *)*string, 0);
883 *nchars = seg->nchars;
884
885 /* wbuf $B$r(B free $B$7$F$*$/(B */
886 XtFree((char *)wbuf);
887
888 return 0;
889 }
890
891 /*
892 * Private FUNCTIONS
893 */
894
895 static int
896 bell()
897 {
898 if (displaybell) {
899 XBell(displaybell, 0);
900 }
901 return 0;
902 }
903
904 static void
905 fix(obj)
906 AtokObject obj;
907 {
908 /* $B3NDj$N=hM}(B */
909 XtCallCallbackList((Widget)obj, obj->inputConv.fixcallback,
910 (XtPointer)NULL); /* $B!)!)!)(B */
911 }
912
913 static void
914 fixProcForAtok(obj, fixedstr, fixedlen)
915 AtokObject obj;
916 wchar *fixedstr;
917 int fixedlen;
918 {
919 int offset;
920 int i;
921
922 offset = obj->atok.comm->offset;
923
924 if (offset < ATOK_NSEG) {
925 XatokShiftRight(obj->atok.comm);
926 offset = obj->atok.comm->offset;
927 }
928 else {
929 XatokShiftLeft(obj->atok.comm);
930 }
931 copyInWchar(fixedstr, fixedlen,
932 &(obj->atok.comm->segments[offset-1].string),
933 &(obj->atok.comm->segments[offset-1].size),
934 &(obj->atok.comm->segments[offset-1].length));
935 }
936
937 /*
938 * $BJQ49=*N;(B
939 */
940 static void
941 convend(obj)
942 AtokObject obj;
943 {
944 XtCallCallbackList((Widget)obj, obj->inputConv.endcallback,
945 (XtPointer)NULL);
946 }
947
948 /*
949 * keeping list of objects
950 */
951 typedef struct _oblist_ {
952 AtokObject obj;
953 struct _oblist_ *next;
954 } ObjRec;
955
956 static ObjRec *ObjList = NULL;
957
958 static void
959 addObject(obj, sock, clntid, isConnect)
960 AtokObject obj;
961 int sock;
962 int clntid;
963 int isConnect;
964 {
965 ObjRec *objp = XtNew(ObjRec);
966 _XatokRecPtr acomm;
967 char buf[256];
968
969 objp->obj = obj;
970 objp->next = ObjList;
971 ObjList = objp;
972
973 acomm = objp->obj->atok.comm;
974 /* bzero(acomm, sizeof(_XatokRecPtr)); */
975
976 acomm->convStatus = M_KEYCONV; /* $B4A;zJQ49(B ON $B$N%b!<%I$K@_Dj(B */
977 /* acomm->mode.dsp = 1; /* $B%5!<%P$+$i<hF@$9$k;v$R$i$,$J(B $B%b!<%I$K@_Dj(B */
978
979 if (isConnect) {
980 atokCEOpen(acomm->sock,
981 clntid, objp->obj->atok.comm
982 /*
983 &objp->obj->atok.comm->NETrqst,
984 &objp->obj->atok.comm->NETrslt);
985 */
986 );
987 }
988 }
989
990 static void
991 deleteObject(obj)
992 AtokObject obj;
993 {
994 ObjRec *objp, *objp0;
995
996 for (objp0 = NULL, objp = ObjList;
997 objp != NULL;
998 objp0 = objp, objp = objp->next) {
999 if (objp->obj == obj) {
1000 if (objp0 == NULL) {
1001 ObjList = objp->next;
1002 } else {
1003 objp0->next = objp->next;
1004 }
1005 XtFree((char *)objp);
1006 return;
1007 }
1008 }
1009 }
1010
1011 static void
1012 atokDisplay(obj, kstat)
1013 AtokObject obj;
1014 int *kstat;
1015 {
1016 wchar *wbuf = obj->atok.comm->wbuf;
1017 int len = obj->atok.comm->wlen;
1018
1019 /*
1020 * len > 0 $B$N;~$O!"(B atokClntEvent $B$GJQ49$r9T$C$?7k2L!"(B
1021 * $B3NDjJ8;zNs$,$"$k;~$G$"$k!#(B
1022 */
1023 if (len > 0) {
1024 /*
1025 XtCallCallbackList((Widget)obj, obj->inputConv.fixcallback,
1026 (XtPointer)NULL);
1027 */
1028 fixProcForAtok(obj, wbuf, len);
1029 fix(obj);
1030 }
1031 changeTextForAtok(obj, kstat);
1032
1033 /*
1034 * $BI=<($9$kFbMF(B($B%F%-%9%H(B)$B$,JQ$o$C$F$$$?>l9g$K$O!"I=<($7$J$*$9!#(B
1035 */
1036 if ( obj->atok.textchanged ) {
1037 XtCallCallbackList((Widget)obj, obj->inputConv.textchangecallback,
1038 (XtPointer)NULL);
1039 obj->atok.textchanged = False;
1040 }
1041 }
1042
1043 static int
1044 atokCandDisplay(obj, aajcode)
1045 AtokObject obj;
1046 int aajcode;
1047 {
1048 int status = 0;
1049
1050 /*
1051 * $B8uJd%&%$%s%I%&I=<(;~$N%-!<F~NO(B
1052 * $B%-!<$O(B key.c $B$GDj5A$7$F$$$k$b$N$r;HMQ$9$k;v!#(B
1053 */
1054 switch( aajcode ) {
1055 case XFER:
1056 #ifdef CAND_PAGE
1057 startSelection(obj, 1);
1058 #else
1059 startSelection(obj, 0);
1060 #endif
1061 break;
1062 case SPACE:
1063 case RIGHT:
1064 case CTR_F:
1065 #ifdef CAND_PAGE
1066 moveRight(obj, 1);
1067 #else
1068 moveRight(obj, 0);
1069 #endif
1070 break;
1071 case LEFT:
1072 case CTR_B:
1073 #ifdef CAND_PAGE
1074 moveLeft(obj, 1);
1075 #else
1076 moveLeft(obj, 0);
1077 #endif
1078 break;
1079 case UP:
1080 case CTR_P:
1081 moveSelection(obj, ICMoveUp);
1082 break;
1083 case DOWN:
1084 case CTR_N:
1085 moveSelection(obj, ICMoveDown);
1086 break;
1087 case CTR_E:
1088 moveSelection(obj, ICMoveLast);
1089 break;
1090 case CTR_A:
1091 moveSelection(obj, ICMoveFirst);
1092 break;
1093 case CR:
1094 case VKEY|FUNC_KAKU_BUBUN:
1095 endSelection(obj, FALSE, TRUE);
1096 status = 1;
1097 break;
1098 case CTR_G:
1099 endSelection(obj, TRUE, TRUE);
1100 obj->atok.cur_cand = -1;
1101 break;
1102 case CTR_DEL: /* 616 */
1103 case EESC:
1104 case FUNC_CNV_CANCL: /* 1999/06/30 */
1105 endSelection(obj, TRUE, TRUE);
1106 obj->atok.cur_cand = -1;
1107 status = 1;
1108 break;
1109 case 0:
1110 default:
1111 break;
1112 }
1113 return status;
1114 }
1115
1116 static int
1117 atokAuxDisplay(obj, op)
1118 AtokObject obj;
1119 opMode op;
1120 {
1121 ICAuxControlArg arg;
1122 int status = 1;
1123
1124 switch (obj->atok.comm->menuStatus) {
1125 case ICAuxEnd :
1126 if (obj->atok.comm->convStatus & op) {
1127 obj->atok.comm->convStatus ^= op;
1128 }
1129 obj->atok.comm->convStatus |= M_KEYCONV;
1130 status = 0;
1131 case ICAuxStart :
1132 case ICAuxChange :
1133 arg.command = obj->atok.comm->menuStatus;
1134 break;
1135 default :
1136 return -1;
1137 }
1138 if (arg.command != ICAuxEnd) {
1139 changeTextForAtokAUX(&obj->atok);
1140 }
1141
1142 XtCallCallbackList((Widget)obj, obj->inputConv.auxcallback,
1143 (XtPointer)&arg);
1144
1145 return status;
1146 }
1147
1148 /*
1149 * Utils
1150 */
1151 /*
1152 * $B8uJd0lMwI=<($N4X?t74(B
1153 */
1154 /*
1155 * $B40(B
1156 */
1157 static void
1158 moveLeft(obj, cand_page)
1159 AtokObject obj;
1160 int cand_page;
1161 {
1162 _XatokRecPtr comm;
1163 int pgMax;
1164 int move = TRUE;
1165 ICSelectionControlArg arg;
1166 int kohoNum;
1167
1168 if (!cand_page) {
1169 moveSelection(obj, ICMoveLeft);
1170 return;
1171 }
1172 comm = obj->atok.comm;
1173
1174 querySelection(obj);
1175 pgMax = comm->kohoMax;
1176
1177 if (comm->kohoPos == 0) {
1178 /*
1179 * $B:G8e$N%Z!<%8$rI=<($7$F$$$k!#(B
1180 */
1181 if (comm->kohoCurPage + 1 == comm->kohoPageNbr) {
1182 /*
1183 * $B:G8e$N%Z!<%8$@$,!":G=i$N%Z!<%8$G$"$k(B
1184 * $B$7$?$,$C$FJQ99$9$k%Z!<%8$O$J$$!#(B
1185 */
1186 if (comm->kohoCurPage == 0) {
1187 move = TRUE;
1188 }
1189 else {
1190 comm->kohoCurPage--;
1191 move = FALSE;
1192 }
1193 }
1194 else if (comm->kohoCurPage == 0) {
1195 comm->kohoCurPage = comm->kohoPageNbr - 1;
1196 move = FALSE;
1197 }
1198 else {
1199 comm->kohoCurPage--;
1200 move = FALSE;
1201 }
1202 }
1203
1204 if (move == FALSE) {
1205 endSelection(obj, FALSE, FALSE);
1206 kohoNum = comm->kohoNum2 > (comm->kohoCurPage + 1) * pgMax ?
1207 pgMax - 1 : comm->kohoNum2 - (comm->kohoCurPage * pgMax) - 1;
1208 makeCandList(obj, obj->atok.cand_lists_ics, pgMax, pgMax + 1,
1209 comm->kohoCurPage, kohoNum, 1);
1210 return;
1211 }
1212
1213 moveSelection(obj, ICMoveLeft);
1214 }
1215
1216 static void
1217 moveRight(obj, cand_page)
1218 AtokObject obj;
1219 int cand_page;
1220 {
1221 _XatokRecPtr comm;
1222 int pgMax;
1223 int move = TRUE;
1224 int kohoNum;
1225 ICSelectionControlArg arg;
1226
1227 if (!cand_page) {
1228 moveSelection(obj, ICMoveRight);
1229 return;
1230 }
1231 comm = obj->atok.comm;
1232
1233 querySelection(obj);
1234 /* pgMax = CAND_COLS * CAND_ROWS; */
1235 pgMax = comm->kohoMax;
1236
1237 if (comm->kohoPos == pgMax - 1) {
1238 if (comm->kohoNum2 > (comm->kohoCurPage + 1) * pgMax) {
1239 comm->kohoCurPage++;
1240 }
1241 else {
1242 comm->kohoCurPage = 0;
1243 }
1244 move = FALSE;
1245 comm->kohoPos = 0;
1246 }
1247 else if (comm->kohoPos == comm->kohoNum2 - (comm->kohoCurPage * pgMax) - 1)
1248 {
1249 /* if (comm->kohoCurPage != 0) move = FALSE; */
1250 comm->kohoCurPage = 0;
1251 move = FALSE;
1252 comm->kohoPos = 0;
1253 }
1254 if (move == FALSE) {
1255 endSelection(obj, FALSE, FALSE);
1256 makeCandList(obj, obj->atok.cand_lists_ics, pgMax, pgMax + 1,
1257 comm->kohoCurPage, 0, 1);
1258 comm->kohoPos = 0;
1259 return;
1260
1261 }
1262
1263 moveSelection( obj, ICMoveRight );
1264 }
1265
1266 static void
1267 setSelection(obj, kohoNum)
1268 AtokObject obj;
1269 int kohoNum;
1270 {
1271 ICSelectionControlArg arg;
1272
1273 /* Set current candidate */
1274 arg.command = ICSelectionSet;
1275 arg.u.current_item = kohoNum; /* $B8uJd(BNO$B$r@_Dj$9$k;v(B */
1276 XtCallCallbackList((Widget)obj, obj->inputConv.selectioncallback,
1277 (XtPointer)&arg);
1278 }
1279
1280 static void
1281 moveSelection(obj, dir)
1282 AtokObject obj;
1283 int dir;
1284 {
1285 ICSelectionControlArg arg;
1286
1287 arg.command = ICSelectionMove;
1288 arg.u.dir = dir;
1289 XtCallCallbackList((Widget)obj, obj->inputConv.selectioncallback,
1290 (XtPointer)&arg);
1291 querySelection(obj);
1292 }
1293
1294 static void
1295 querySelection(obj)
1296 AtokObject obj;
1297 {
1298 ICSelectionControlArg arg;
1299 arg.command = ICSelectionGet;
1300 arg.u.current_item = -1;
1301 XtCallCallbackList((Widget)obj, obj->inputConv.selectioncallback,
1302 (XtPointer)&arg);
1303
1304 obj->atok.selected_cand = arg.u.current_item;
1305 obj->atok.comm->kohoPos = arg.u.current_item;
1306 }
1307
1308 static void
1309 endSelection(obj, isabort, modeChange)
1310 AtokObject obj;
1311 int isabort;
1312 int modeChange;
1313 {
1314 ICSelectionControlArg arg;
1315 int selected;
1316
1317 if (modeChange) {
1318 obj->atok.comm->convStatus ^= M_CAND;
1319 }
1320 arg.command = ICSelectionEnd;
1321 arg.u.current_item = -1;
1322 XtCallCallbackList((Widget)obj, obj->inputConv.selectioncallback,
1323 (XtPointer)&arg);
1324
1325 if (!isabort && (selected = arg.u.current_item) >= 0) {
1326 insertSelection(obj, selected);
1327 }
1328 }
1329
1330 static void
1331 insertSelection(obj, selected)
1332 AtokObject obj;
1333 int selected;
1334 {
1335 obj->atok.cur_cand = selected;
1336 obj->atok.comm->kohoPos = selected;
1337
1338 /*
1339 * ATOK CE $B$KA*Br$5$l$?$3$H$rDLCN$9$kI,MW$"$j(B
1340 * API$B$,2r$j<!Bh(B $B%3!<%G%#%s%0(B
1341 */
1342 return;
1343 }
1344
1345 /*
1346 * $B8uJd%j%9%H$N$?$a$N%P%C%U%!$rMQ0U$9$k!#(B
1347 */
1348 static int
1349 allocCandList(obj, nbr, cur)
1350 AtokObject obj;
1351 int nbr;
1352 int *cur;
1353 {
1354 ICString *p;
1355
1356 /*
1357 * $B4{$KI,MW$J%5%$%:0J>e(B $B3NJ]$5$l$F$$$k>l9g$K$O2?$b$7$J$$!#(B
1358 */
1359 if (nbr <= obj->atok.cand_list_size) {
1360 return nbr;
1361 }
1362
1363 /*
1364 * $B$^$@(B $B3NJ]$5$l$F$$$J$$;~$K$O!"?75,$K!"4{$K(B
1365 * $B3NJ]$5$l$F$$$kNN0h$r9-$2$?$$;~$K$O(B realloc $B$9$k!#(B
1366 */
1367 if (obj->atok.cand_list_size == 0) {
1368 p = (ICString *)XtMalloc(nbr * sizeof(ICString));
1369 }
1370 else {
1371 p = (ICString *)XtRealloc((char *)obj->atok.cand_lists_ics,
1372 nbr * sizeof(ICString));
1373 }
1374 obj->atok.cand_lists_ics = p;
1375 obj->atok.cand_list_size = nbr;
1376 *cur = 0;
1377
1378 return nbr;
1379 }
1380
1381 /*
1382 * $B%-!<F~NO8e!"(BCE$B$K$h$C$FJQ49$5$l$?%G!<%?$r2hLL$KI=<($9$k$?$a$N(B
1383 * $B%3%s%H%m!<%k$r9T$&=hM}$N%a%$%s$G$"$k!#(B
1384 * $BI=<(%;%0%a%s%H$N7W;;!"%,%$%I%i%$%s$J$I$NI=<(J8;zNs$N:n@.$r9T$C$F$$$k!#(B
1385 *
1386 * $B$3$3$G9T$&$N$OBg$-$/J,$1$F#3$D$N=hM}$G$"$k!#(B
1387 * 1 $BF~NOESCf$NJ8;zNs$N(BECHO BACK
1388 * 2 $BF~NO%b!<%I$,JQ49$5$l$?;~$N(B $BF~NO%b!<%II=<(J8;zNs$N@_Dj(B
1389 * 3 $B0lMwI=<($7$F$$$k;~$N(B
1390 */
1391 static int
1392 changeTextForAtok(obj, kstat)
1393 AtokObject obj;
1394 int *kstat;
1395 {
1396 _XatokRecPtr acomm = obj->atok.comm;
1397 int remain;
1398 int offset = acomm->offset;
1399 int len = acomm->echoLen;
1400 int i;
1401 wchar *wp;
1402
1403 if (len == 0) {
1404 acomm->cur_seg = offset;
1405 acomm->nbr_of_seg = offset;
1406 acomm->segments[offset+0].length
1407 = acomm->segments[offset+1].length
1408 = acomm->segments[offset+2].length = 0;
1409 if (*kstat == XKEY_FIX) {
1410 obj->atok.textchanged = TRUE;
1411 }
1412 obj->atok.textchanged = TRUE;
1413 }
1414 else if (len > 0) {
1415 /* $B%-!<F~NO$,$"$C$?>l9g(B */
1416 acomm->segments[offset+1].length
1417 = acomm->segments[offset+2].length = 0;
1418 if (acomm->revLen > 0) {
1419 if ( acomm->revPos == 0 ) {
1420 remain = acomm->echoLen - acomm->revLen;
1421 /*
1422 * REVERSE :
1423 * REVERSE : NORMAL
1424 * $BH?E>I=<($,#1%;%0%a%s%HL\$N>l9g$K$O(B
1425 * str[0] $B$KJ8;z$rB-$9(B
1426 */
1427 copyInWchar(acomm->echoStr, acomm->revLen,
1428 &(acomm->segments[offset+0].string),
1429 &(acomm->segments[offset+0].size),
1430 &(acomm->segments[offset+0].length));
1431 acomm->cur_seg = offset;
1432 acomm->nbr_of_seg = offset + 1;
1433 /*
1434 * $B#2%;%0%a%s%HL\$,B8:_$9$k>l9g$K$O!"(B
1435 * $B#2%;%0%a%s%HL\$b@_Dj$9$k!#(B
1436 */
1437 if (remain) {
1438 copyInWchar(acomm->echoStr + acomm->revLen, remain,
1439 &(acomm->segments[offset+1].string),
1440 &(acomm->segments[offset+1].size),
1441 &(acomm->segments[offset+1].length));
1442 acomm->nbr_of_seg = offset+2;
1443 }
1444 }
1445 else {
1446 /*
1447 * NORMAL : REVERSE
1448 * NORAML : REVERSE : NORMAL
1449 *
1450 * $B$3$3$K$/$k$H$-$O(B $B#2HVL\0J9_$J$N$G(B str0,
1451 * str1 $B$O@dBP$KB8:_$9$k!#(B
1452 * $BH?E>I=<($,$"$j!"3n$D#1%;%0%a%s%H$,%N!<%^%k(B
1453 * $BI=<($H$$$&;v$O#2%;%0%a%s%HL\$,H?E>I=<($G(B
1454 * $B$"$k!#(B
1455 */
1456 remain = acomm->echoLen - acomm->revPos - acomm->revLen;
1457 copyInWchar(acomm->echoStr, acomm->revPos,
1458 &(acomm->segments[offset+0].string),
1459 &(acomm->segments[offset+0].size),
1460 &(acomm->segments[offset+0].length));
1461 copyInWchar(acomm->echoStr + acomm->revPos, acomm->revLen,
1462 &(acomm->segments[offset+1].string),
1463 &(acomm->segments[offset+1].size),
1464 &(acomm->segments[offset+1].length));
1465 acomm->cur_seg = offset+1;
1466 acomm->nbr_of_seg = offset+2;
1467 /*
1468 * NORMAL : REVERSE : NORMAL $B$N>l9g(B
1469 */
1470 if (remain){
1471 copyInWchar(acomm->echoStr + acomm->revPos + acomm->revLen,
1472 remain,
1473 &(acomm->segments[offset+2].string),
1474 &(acomm->segments[offset+2].size),
1475 &(acomm->segments[offset+2].length));
1476 acomm->nbr_of_seg = offset+3;
1477 }
1478 }
1479 }
1480 else {
1481 /*
1482 * NORMAL $BI=<((BONLY
1483 */
1484 copyInWchar(acomm->echoStr, acomm->echoLen,
1485 &(acomm->segments[offset+0].string),
1486 &(acomm->segments[offset+0].size),
1487 &(acomm->segments[offset+0].length));
1488 acomm->segments[1].length = acomm->segments[2].length = 0;
1489 acomm->nbr_of_seg = offset+1;
1490 acomm->cur_seg = offset+1;
1491 }
1492 obj->atok.textchanged = TRUE;
1493 }
1494 }
1495
1496 static int
1497 changeTextForAtokAUX(obj)
1498 AtokPart *obj;
1499 {
1500 int remain;
1501 int len;
1502 int i;
1503 _XatokRecPtr acomm = obj->comm;
1504
1505 /*
1506 * $B$3$3$G(B AUX $B$KI=<($9$kJ8;z$r:n@.$9$k!#(B
1507 */
1508 if (obj->comm->convStatus & M_SYSLINE) {
1509 auxSyslineString(acomm, acomm->curAux,
1510 acomm->aux_echoStr, &acomm->aux_echoLen,
1511 &acomm->aux_revLen, &acomm->aux_revPos);
1512 }
1513 else {
1514 auxMenuString(acomm, acomm->curAux,
1515 acomm->aux_echoStr, &acomm->aux_echoLen,
1516 &acomm->aux_revLen, &acomm->aux_revPos);
1517 }
1518 /*
1519 * $BI=<($9$kJ8;z$,$J$$>l9g$O%j%?!<%s$9$k!#(B
1520 */
1521 if ( acomm->aux_echoLen == 0 ) {
1522 obj->aux_curseg = 0;
1523 obj->aux_nseg = 0;
1524 obj->aux_length[0] = obj->aux_length[1] = obj->aux_length[2] = 0;
1525 return 0;
1526 }
1527 obj->aux_length[1] = obj->aux_length[2] = 0;
1528 if (acomm->aux_revLen > 0) {
1529 if (acomm->aux_revPos == 0) {
1530 remain = acomm->aux_echoLen - acomm->aux_revLen;
1531 copyInWchar(acomm->aux_echoStr, acomm->aux_revLen,
1532 &obj->aux_string[0],
1533 &obj->aux_size[0],
1534 &obj->aux_length[0]);
1535 obj->aux_curseg = 0;
1536 obj->aux_nseg = 1;
1537 /*
1538 * $B#2%;%0%a%s%HL\$,B8:_$9$k>l9g$K$O!"(B
1539 * $B#2%;%0%a%s%HL\$b@_Dj$9$k!#(B
1540 */
1541 if (remain) {
1542 copyInWchar(acomm->aux_echoStr + acomm->aux_revLen, remain,
1543 &obj->aux_string[1],
1544 &obj->aux_size[1],
1545 &obj->aux_length[1]);
1546 obj->aux_nseg = 2;
1547 }
1548 }
1549 else {
1550 /*
1551 * NORMAL : REVERSE
1552 * NORAML : REVERSE : NORMAL
1553 *
1554 * $B$3$3$K$/$k$H$-$O(B $B#2HVL\0J9_$J$N$G(B str0,
1555 * str1 $B$O@dBP$KB8:_$9$k!#(B
1556 * $BH?E>I=<($,$"$j!"3n$D#1%;%0%a%s%H$,%N!<%^%k(B
1557 * $BI=<($H$$$&;v$O#2%;%0%a%s%HL\$,H?E>I=<($G(B
1558 * $B$"$k!#(B
1559 */
1560 remain = acomm->aux_echoLen - acomm->aux_revPos - acomm->aux_revLen;
1561 copyInWchar(acomm->aux_echoStr, acomm->aux_revPos,
1562 &obj->aux_string[0],
1563 &obj->aux_size[0],
1564 &obj->aux_length[0]);
1565 copyInWchar(acomm->aux_echoStr + acomm->aux_revPos,
1566 acomm->aux_revLen,
1567 &obj->aux_string[1],
1568 &obj->aux_size[1],
1569 &obj->aux_length[1]);
1570 obj->aux_curseg = 1;
1571 obj->aux_nseg = 2;
1572 /*
1573 * NORMAL : REVERSE : NORMAL $B$N>l9g(B
1574 */
1575 if (remain) {
1576 copyInWchar(acomm->aux_echoStr + acomm->aux_revPos
1577 + acomm->aux_revLen,
1578 remain,
1579 &obj->aux_string[2],
1580 &obj->aux_size[2],
1581 &obj->aux_length[2] );
1582 obj->aux_nseg = 3;
1583 }
1584 }
1585 }
1586 else {
1587 /*
1588 * NORMAL $BI=<((BONLY
1589 */
1590 copyInWchar(acomm->aux_echoStr, acomm->aux_echoLen,
1591 &obj->aux_string[0],
1592 &obj->aux_size[0],
1593 &obj->aux_length[0]);
1594 obj->aux_length[1] = obj->aux_length[1] = 0;
1595 obj->aux_nseg = 1;
1596 obj->aux_curseg = 1;
1597 }
1598
1599 for (i = 0; i < obj->aux_nseg; i++) {
1600 obj->aux_ics[i].data = (char *)obj->aux_string[i];
1601 obj->aux_ics[i].nchars = obj->aux_length[i];
1602 obj->aux_ics[i].nbytes = obj->aux_length[i] * sizeof(wchar);
1603 obj->aux_ics[i].attr = ICAttrConverted;
1604 }
1605 if (obj->aux_curseg < obj->aux_nseg) {
1606 obj->aux_ics[obj->aux_curseg].attr |= ICAttrCurrentSegment;
1607 }
1608 return obj->aux_nseg;
1609 }
1610
1611 /*
1612 * $B8uJdJ8;zNs4X78$N%=!<%9(B
1613 */
1614
1615 /* Page */
1616 /*
1617 * [$B4X?tL>(B]
1618 * ()
1619 * [$BI=Bj(B]
1620 *
1621 * [$B8F=P7A<0(B]
1622 *
1623 * [$B0z?t(B]
1624 * $B7?(B : $BL>(B $B>N(B : IO : $B@b(B $BL@(B
1625 *
1626 *
1627 * [$BJV$jCM(B]
1628 *
1629 * [$B;HMQ4X?t(B]
1630 *
1631 * [$B5!G=(B]
1632 * Event $B$,H/@8$7$F!"(B CE$B$h$j(B $B8uJd%j%9%H$,<hF@$7$?8e$KI=<($r(B
1633 * $B3+;O$9$k;~$K8F$S=P$5$l$k!#(B
1634 *
1635 */
1636 static void
1637 startSelection(obj, cand_page)
1638 AtokObject obj;
1639 int cand_page;
1640 {
1641 _XatokRecPtr comm = obj->atok.comm;
1642 ICString *icsp;
1643 int i, n;
1644 int pgMax;
1645 int oldSize;
1646
1647 n = obj->atok.nbr_of_cand = comm->kohoNum2;
1648 if (cand_page) {
1649 pgMax = CAND_COLS * CAND_ROWS;
1650 }
1651 else {
1652 pgMax = n;
1653 }
1654 comm->kohoMax = pgMax;
1655
1656 comm->kohoPageNbr = (comm->kohoNum2 + pgMax - 1) / pgMax;
1657 comm->kohoCurPage = 0; /* $B%Z!<%8$O#0$+$i;O$^$k!#(B*/
1658 /* comm->kohoPos = 1; /* ATOKCE $B$N%j%?!<%s$r@_Dj(B */
1659
1660 /*
1661 * $B$^$:$O(B $B8uJd$r@_Dj$9$k(BICSString $B$N%a%b%j!<$r3NJ]$7$F!"(B
1662 * $B=i4|2=$9$k!#(B
1663 */
1664 oldSize = obj->atok.cand_list_size;
1665 if (cand_page) {
1666 /*
1667 * $B8uJdI=<($N:GBg?t$,7h$^$C$F$$$k>l9g$O!"(B
1668 * $B8uJd$N$?$a$N(BICS $B$,<hF@$5$l$F$$$k$+!"$$$J$$$+$N>l9g$7$+$J$$(B
1669 */
1670 n = pgMax + 1; /* +1 $B$O8uJdHV9fI=<(MQ(B */
1671 if (obj->atok.cand_list_size == 0) {
1672 icsp = (ICString *)XtMalloc(n * sizeof(ICString));
1673 obj->atok.cand_list_size = n;
1674 obj->atok.cand_lists_ics = icsp;
1675 }
1676 }
1677 else {
1678 if (obj->atok.cand_list_size == 0) {
1679 icsp = (ICString *)XtMalloc(n * sizeof(ICString));
1680 obj->atok.cand_list_size = n;
1681 obj->atok.cand_lists_ics = icsp;
1682 }
1683 else if (obj->atok.cand_list_size < n) {
1684 icsp = (ICString *)XtRealloc((char *)obj->atok.cand_lists_ics,
1685 n * sizeof(ICString));
1686 obj->atok.cand_list_size = n;
1687 obj->atok.cand_lists_ics = icsp;
1688 }
1689 else {
1690 icsp = obj->atok.cand_lists_ics;
1691 }
1692 }
1693
1694 /*
1695 * $B<hF@$5$l$F$$$k8uJd$r@_Dj$9$k!#(B
1696 */
1697 icsp = obj->atok.cand_lists_ics;
1698 #ifdef CAND_PAGE
1699 makeCandList(obj, icsp, pgMax, n, comm->kohoPos / pgMax, comm->kohoPos, 1);
1700 #else
1701 makeCandList(obj, icsp, pgMax, n, comm->kohoPos / pgMax, comm->kohoPos, 0);
1702 #endif
1703 }
1704
1705 static int
1706 makeCandList(obj, icsp, pgMax, icsNum, page, kohoNum, cand_page)
1707 AtokObject obj;
1708 ICString *icsp; /* $BI=<(MQ%G!<%?(B */
1709 int pgMax; /* $B#1%Z!<%8$N:GBg?t(B */
1710 int icsNum;
1711 int page; /* $BI=<($9$k%Z!<%8(B */
1712 int kohoNum;
1713 int cand_page;
1714 {
1715 _XatokRecPtr comm = obj->atok.comm;
1716 int i, j, n;
1717 int len, ksize, klen;
1718 int bytes, chars;
1719 int es;
1720 unsigned char *ep;
1721 wchar wbuf[BUFSIZ];
1722 char euc[BUFSIZ];
1723 int stNbr;
1724 int maxCand = 0;
1725 ICSelectionControlArg arg;
1726 ICString *ticsp = icsp; /* $BI=<(MQ%G!<%?(B */
1727
1728 for (i = 0; i < icsNum; i++, ticsp++) {
1729 /* if (i < oldSize) continue; */
1730 ticsp->nbytes = (unsigned short)0;
1731 ticsp->nchars = (unsigned short)0;
1732 ticsp->data = (char *)0;
1733 ticsp->attr = 0;
1734 }
1735 stNbr = page * pgMax;
1736
1737 ksize = 0;
1738 for(i = 0; i < stNbr; i++) {
1739 ksize += comm->kohoLenPtr[i];
1740 }
1741 if (cand_page) {
1742 n = comm->kohoNum2 - stNbr > pgMax ? pgMax : comm->kohoNum2 - stNbr;
1743 }
1744 else {
1745 n = pgMax;
1746 }
1747 for (j = 0; j < n; j++) {
1748 bzero(euc, sizeof(euc));
1749 klen = comm->kohoLenPtr[i];
1750 es = klen * 3;
1751 ep = (unsigned char *)XtMalloc(es);
1752 bzero(ep, es);
1753 ucs2euc(&comm->kohoStrPtr[ksize], klen, ep, es, 0x0000a2ae);
1754 es = strlen(ep);
1755 ksize += klen;
1756 #ifdef CAND_PAGE
1757 sprintf(euc, "%2d %s", j + 1, ep);
1758 #else
1759 strcpy(euc, ep);
1760 #endif
1761 es = strlen(euc);
1762 es = euc2wcs(euc, es, wbuf);
1763 XtFree((char *)ep);
1764
1765 bytes = (int)icsp->nbytes;
1766 chars = (int)icsp->nchars;
1767 copyInWchar(wbuf, es, (wchar **)&(icsp->data), &bytes, &chars);
1768 icsp->nbytes = (unsigned short)bytes;
1769 icsp->nchars = (unsigned short)chars;
1770 if (chars > maxCand) {
1771 maxCand = chars;
1772 }
1773 icsp->attr = ICAttrNormalString;
1774 icsp++;
1775 i++;
1776 }
1777 for(; j < pgMax; j++) {
1778 icsp->nbytes = (unsigned short)0;
1779 icsp->nchars = (unsigned short)0;
1780 icsp->attr = ICAttrNormalString;
1781 icsp->data = (char *)0;
1782 icsp++;
1783 }
1784 if (cand_page) {
1785 #if SHOW_PAGE
1786 sprintf(euc, "%d/%d", page * pgMax + 1, comm->kohoNum2);
1787 #else
1788 sprintf(euc, "Page %d/%d", page + 1,
1789 (comm->kohoNum2 + pgMax - 1) / pgMax);
1790 #endif
1791 es = strlen(euc);
1792 es = euc2wcs(euc, es, wbuf);
1793 bytes = (int)icsp->nbytes;
1794 chars = (int)icsp->nchars;
1795 copyInWchar(wbuf, es, ( wchar ** )&( icsp->data ), &bytes, &chars);
1796
1797 icsp->nbytes = (unsigned short)bytes;
1798 icsp->nchars = (unsigned short)chars;
1799 icsp->attr = ICAttrNormalString;
1800 }
1801
1802 comm->kohoCurPage = page;
1803
1804 arg.command = ICSelectionStart;
1805 arg.u.selection_kind = ICSelectionCandidates;
1806 XtCallCallbackList((Widget)obj, obj->inputConv.selectioncallback,
1807 (XtPointer)&arg);
1808
1809 /* Set current candidate */
1810 arg.command = ICSelectionSet;
1811 arg.u.current_item = kohoNum; /* $B8uJd(BNO$B$r@_Dj$9$k;v(B */
1812 XtCallCallbackList((Widget)obj, obj->inputConv.selectioncallback,
1813 (XtPointer)&arg);
1814
1815 return page;
1816 }
1817
1818
1819 /*
1820 copyInWchar -- wchar $B$r%3%T!<$9$k!#(B
1821
1822 ws, wlen $B$G<($5$l$?(B wchar $BJ8;zNs$r(B wsbuf $B$N%]%$%s%H@h$N%P%C%U%!$K3J(B
1823 $BG<$9$k!#(Bwsbuf $B$N%5%$%:$O(B wssize $B$N%]%$%s%H@h$K3JG<$5$l$F$$$kCM$G;X(B
1824 $BDj$5$l$k$,!"$=$l$G$O>.$5$$;~$O(B copyInWchar $BFb$G(B XtRealloc $B$5$l!"?7(B
1825 $B$?$K%"%m%1!<%H$5$l$?%P%C%U%!$,(B wsbuf $B$N%]%$%s%H@h$K3JG<$5$l$k!#$^$?!"(B
1826 $B%P%C%U%!$N?7$?$J%5%$%:$,(B wssize $B$N%]%$%s%H@h$K3JG<$5$l$k!#F@$i$l$?(B
1827 $BJ8;z?t$,(Bwslen $B$N%]%$%s%H@h$K3JG<$5$l$k!#(B
1828 */
1829 static void
1830 copyInWchar(ws, wlen, wsbuf, wssize, wslen)
1831 wchar *ws;
1832 int wlen;
1833 wchar **wsbuf;
1834 int *wssize;
1835 int *wslen;
1836 {
1837 int i;
1838
1839 if (*wssize == 0) {
1840 *wsbuf = (wchar *)XtMalloc((wlen + 1) * sizeof(wchar));
1841 *wssize = wlen + 1;
1842 }
1843 if (wlen + 1 > *wssize) {
1844 *wsbuf = (wchar *)XtRealloc((char *)*wsbuf, (wlen + 1) * sizeof(wchar));
1845 *wssize = wlen + 1;
1846 }
1847 *wslen = wlen;
1848 (void)bcopy(ws, *wsbuf, wlen * sizeof(wchar));
1849 *(*wsbuf + wlen) = (wchar)0;
1850 }
1851 /* Atok.c */