Mercurial > kinput2.yaz
comparison lib/Canna.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 | 56c98768f86b 1f1719e33c62 |
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 /* $BD>$5$J$1$l$P$J$i$J$$$H$3$m(B | |
43 | |
44 $B!&(BDestroy $B$,8F$P$l$J$$$N$G(B CloseUIContext $B$G$-$J$$!#(B | |
45 $B!&%b!<%INN0h$NBg$-$5!#(B($B$3$l$OB>$N%U%!%$%k$@$m$&$J(B) | |
46 | |
47 */ | |
48 | |
49 #ifndef lint | |
50 static char *rcsid = "$Id: Canna.c,v 1.55 1999/05/25 08:13:03 ishisone Exp $"; | |
51 #endif | |
52 | |
53 #include <X11/IntrinsicP.h> | |
54 #include <X11/StringDefs.h> | |
55 #include <X11/Xmu/Atoms.h> | |
56 #define XK_KATAKANA | |
57 #include <X11/keysym.h> | |
58 #if XtSpecificationRelease > 4 | |
59 #include <X11/Xfuncs.h> | |
60 #endif | |
61 #include "CannaP.h" | |
62 #include "DebugPrint.h" | |
63 | |
64 #define _WCHAR_T /* $B$3$NDj5A$O(B jrkanji.h $B$G(B wcKanjiStatus $B$J$I$rDj5A$9$k$?$a(B */ | |
65 #define wchar_t wchar | |
66 | |
67 #include <canna/jrkanji.h> | |
68 | |
69 static XtResource resources[] = { | |
70 #define offset(field) XtOffset(CannaObject, canna.field) | |
71 { XtNcannahost, XtCCannahost, XtRString, sizeof(String), | |
72 offset(cannahost), XtRString, NULL }, | |
73 { XtNcannafile, XtCCannafile, XtRString, sizeof(String), | |
74 offset(cannafile), XtRString, NULL }, | |
75 { XtNsendReturnByString, XtCSendReturnByString, | |
76 XtRBoolean, sizeof(Boolean), | |
77 offset(sendReturnByString), XtRBoolean, False }, | |
78 #undef offset | |
79 }; | |
80 | |
81 static void ClassInitialize(); | |
82 static void Initialize(), Destroy(); | |
83 static Boolean SetValues(); | |
84 static int InputEvent(); | |
85 static ICString *GetMode(); | |
86 static int CursorPos(); | |
87 static int NumSegments(); | |
88 static ICString *GetSegment(); | |
89 static int CompareSegment(); | |
90 static ICString *GetItemList(); | |
91 static int SelectItem(); | |
92 static int ConvertedString(); | |
93 static int ClearConversion(); | |
94 static void displayPreEdit(); | |
95 static int GetTriggerKeys(); | |
96 static int PreeditString(); | |
97 static int StatusString(); | |
98 | |
99 static initializeCannaConnection(); | |
100 static toJapaneseMode(); | |
101 static void convend(); | |
102 static changeTextForCanna(); | |
103 static copyInWchar(); | |
104 static fixProcForCanna(); | |
105 static shiftRight(), shiftLeft(), shiftLeftAll(); | |
106 static ibufInitialize(), freeIBuf(); | |
107 | |
108 #ifdef KC_SETLISTCALLBACK | |
109 #ifdef CANNA_LIST_Convert | |
110 #define CANNA_LISTFUNCTYPE int | |
111 #else | |
112 #define CANNA_LISTFUNCTYPE void | |
113 #endif | |
114 static CANNA_LISTFUNCTYPE listfunc(); | |
115 | |
116 static void openSelection(); | |
117 #define SELECTION_SET 0 /* SelectionStart $B$r$7$F$bNI$$$H8@$&>pJs$r@_Dj$9$k(B */ | |
118 #define SELECTION_DO 1 /* $B<B:]$K(B SelectionStart $B$r3+;O$9$k(B */ | |
119 #else /* !KC_SETLISTCALLBACK */ | |
120 #define openSelection(x, y, z) | |
121 #endif /* !KC_SETLISTCALLBACK */ | |
122 | |
123 static ICString *GetAuxSegments(); | |
124 | |
125 CannaClassRec cannaClassRec = { | |
126 { /* object fields */ | |
127 /* superclass */ (WidgetClass) &inputConvClassRec, | |
128 /* class_name */ "Canna", | |
129 /* widget_size */ sizeof(CannaRec), | |
130 /* class_initialize */ ClassInitialize, | |
131 /* class_part_initialize */ NULL, | |
132 /* class_inited */ FALSE, | |
133 /* initialize */ Initialize, | |
134 /* initialize_hook */ NULL, | |
135 /* obj1 */ NULL, | |
136 /* obj2 */ NULL, | |
137 /* obj3 */ 0, | |
138 /* resources */ resources, | |
139 /* num_resources */ XtNumber(resources), | |
140 /* xrm_class */ NULLQUARK, | |
141 /* obj4 */ FALSE, | |
142 /* obj5 */ FALSE, | |
143 /* obj6 */ FALSE, | |
144 /* obj7 */ FALSE, | |
145 /* destroy */ Destroy, | |
146 /* obj8 */ NULL, | |
147 /* obj9 */ NULL, | |
148 /* set_values */ SetValues, | |
149 /* set_values_hook */ NULL, | |
150 /* obj10 */ NULL, | |
151 /* get_values_hook */ NULL, | |
152 /* obj11 */ NULL, | |
153 /* version */ XtVersion, | |
154 /* callback_private */ NULL, | |
155 /* obj12 */ NULL, | |
156 /* obj13 */ NULL, | |
157 /* obj14 */ NULL, | |
158 /* extension */ NULL | |
159 }, | |
160 { /* inputConv fields */ | |
161 /* InputEvent */ InputEvent, | |
162 /* GetMode */ GetMode, | |
163 /* CursorPos */ CursorPos, | |
164 /* NumSegments */ NumSegments, | |
165 /* GetSegment */ GetSegment, | |
166 /* CompareSegment */ CompareSegment, | |
167 /* GetItemList */ GetItemList, | |
168 /* SelectItem */ SelectItem, | |
169 /* GetConvertedString */ ConvertedString, | |
170 /* ClearConversion */ ClearConversion, | |
171 /* GetAuxSegments */ GetAuxSegments, | |
172 /* SupportMultipleObjects */ True, | |
173 /* GetTriggerKeys */ GetTriggerKeys, | |
174 /* num_trigger_keys */ 0, | |
175 /* trigger_keys */ NULL, | |
176 /* GetPreeditString */ PreeditString, | |
177 /* GetStatusString */ StatusString, | |
178 /* NoMoreObjects */ False, | |
179 }, | |
180 { /* canna fields */ | |
181 /* foo */ 0, | |
182 } | |
183 }; | |
184 | |
185 WidgetClass cannaObjectClass = (WidgetClass)&cannaClassRec; | |
186 | |
187 static void fix(); | |
188 | |
189 static ICString *SymbolList; | |
190 static int NumSymbols; | |
191 | |
192 static void addObject(); | |
193 static void deleteObject(); | |
194 | |
195 static int checkIfFunctionalChar(); | |
196 | |
197 static int ignoreListfunc = 0; | |
198 | |
199 static Display *displaybell = (Display *)0; | |
200 | |
201 static void | |
202 ClassInitialize() | |
203 { | |
204 TRACE(("CannaObjectClass initialized\n")); | |
205 /* $B2?$b$7$J$$(B */ | |
206 } | |
207 | |
208 static int | |
209 XKanaLookup(event_struct, buffer_return, bytes_buffer, | |
210 keysym, status_return) | |
211 XKeyEvent *event_struct; | |
212 char *buffer_return; | |
213 int bytes_buffer; | |
214 KeySym *keysym; | |
215 XComposeStatus *status_return; | |
216 { | |
217 int res; | |
218 res = XLookupString(event_struct, buffer_return, bytes_buffer, | |
219 keysym, status_return); | |
220 if (!res && XK_overline <= *keysym && *keysym <= XK_semivoicedsound) { | |
221 buffer_return[0] = (unsigned long)(*keysym) & 0xff; | |
222 res = 1; | |
223 } | |
224 return res; | |
225 } | |
226 | |
227 static int | |
228 InputEvent(w, event) | |
229 Widget w; | |
230 XEvent *event; | |
231 { | |
232 CannaObject obj = (CannaObject)w; | |
233 wchar buf[1024]; | |
234 char kanabuf[20]; | |
235 KeySym ks; | |
236 XComposeStatus compose_status; | |
237 wcKanjiStatus kanji_status; | |
238 int len, nbytes, functionalChar; | |
239 | |
240 /* KeyPress$B0J30$O<N$F$k(B */ | |
241 if (event->type != KeyPress /*&& event->type != KeyRelease*/) return 0; | |
242 | |
243 obj->canna.textchanged = False; | |
244 | |
245 /* $B<h$j$"$($:J8;z$KD>$7$F$7$^$&(B */ | |
246 kanabuf[0] = '\0'; | |
247 nbytes = XKanaLookup(event, kanabuf, 20, &ks, &compose_status); | |
248 | |
249 buf[0] = (wchar)kanabuf[0]; /* $B$-$?$J$$(B */ | |
250 | |
251 if (ks == XK_space && (event->xkey.state & ShiftMask)) { | |
252 void convend(); | |
253 | |
254 convend(obj); | |
255 return 0; | |
256 } | |
257 | |
258 /* $BD9$5$,%<%m$N$b$N$K4X$7$F$O$A$g$C$H5_:Q(B */ | |
259 functionalChar = checkIfFunctionalChar(event, ks, buf, 1024); | |
260 /* shift+$B"*$N$h$&$JJ8;z$@$C$?$i#1J8;z$H?t$($k(B */ | |
261 if ( !nbytes && functionalChar ) { | |
262 nbytes = 1; | |
263 } | |
264 | |
265 /* $BMW$i$J$$>l9g$OL5;k$9$k(B */ | |
266 if (nbytes == 0) return 1; | |
267 | |
268 /* $B%Y%k$rLD$i$9%G%#%9%W%l%$$N@_Dj(B */ | |
269 | |
270 displaybell = XtDisplayOfObject((Widget)obj); | |
271 | |
272 /* $B$+$J4A;zJQ49$9$k(B */ | |
273 len = wcKanjiString((int)obj, (int)buf[0], | |
274 (wchar_t *)buf, 1024, &kanji_status); | |
275 | |
276 displayPreEdit(obj, len, buf, &kanji_status); | |
277 return (kanji_status.info & KanjiThroughInfo) ? 1 : 0; | |
278 } | |
279 | |
280 static void | |
281 displayPreEdit(obj, len, buf, ks) | |
282 CannaObject obj; | |
283 int len; | |
284 wchar *buf; | |
285 wcKanjiStatus *ks; | |
286 { | |
287 Widget w = (Widget)obj; | |
288 | |
289 if (len > 0) { /* $B3NDjJ8;z$,$"$k>l9g(B */ | |
290 if (len == 1 && (ks->info & KanjiThroughInfo) && | |
291 (obj->canna.sendReturnByString == False || | |
292 (((buf[0] & 0x7f) < (unsigned)0x20 && | |
293 buf[0] != '\r' && buf[0] != '\t') || | |
294 buf[0] == '\177'))) { | |
295 ;/* XSendEvent$B$GAw$C$F$b$i$&$h$&$JJ8;z(B($B2?$b$7$J$$(B) */ | |
296 } | |
297 else { | |
298 ks->info &= ~KanjiThroughInfo; | |
299 fixProcForCanna(obj, buf, len); | |
300 fix(obj); | |
301 } | |
302 } | |
303 | |
304 changeTextForCanna(obj, ks); | |
305 | |
306 /* $B%F%-%9%H$NJQ2=$r%A%'%C%/$9$k(B */ | |
307 if (obj->canna.textchanged) { | |
308 XtCallCallbackList(w, obj->inputConv.textchangecallback, | |
309 (XtPointer)NULL); | |
310 obj->canna.textchanged = False; | |
311 } | |
312 | |
313 /* $BF~NO%b!<%I$r%A%'%C%/$9$k(B */ | |
314 if (ks->info & KanjiModeInfo) { | |
315 XtCallCallbackList(w, obj->inputConv.modechangecallback, | |
316 (XtPointer)NULL); | |
317 } | |
318 | |
319 if (ks->info & KanjiGLineInfo) { /* $B0lMw9T$,$"$k>l9g(B */ | |
320 ICAuxControlArg arg; | |
321 | |
322 switch (obj->canna.ibuf->candstat) { | |
323 case CANNA_GLINE_Start: | |
324 arg.command = ICAuxStart; | |
325 XtCallCallbackList((Widget)obj, obj->inputConv.auxcallback, | |
326 (XtPointer)&arg); | |
327 break; | |
328 case CANNA_GLINE_End: | |
329 arg.command = ICAuxEnd; | |
330 XtCallCallbackList((Widget)obj, obj->inputConv.auxcallback, | |
331 (XtPointer)&arg); | |
332 break; | |
333 case CANNA_GLINE_Change: | |
334 arg.command = ICAuxChange; | |
335 XtCallCallbackList((Widget)obj, obj->inputConv.auxcallback, | |
336 (XtPointer)&arg); | |
337 break; | |
338 } | |
339 } | |
340 | |
341 /* $B=*$o$j$+$I$&$+%A%'%C%/$9$k(B */ | |
342 if (ks->info & KanjiModeInfo) { | |
343 wchar modeinfo[4]; | |
344 | |
345 wcKanjiControl((int)obj, KC_SETMODEINFOSTYLE, (char *)1); | |
346 wcKanjiControl((int)obj, KC_QUERYMODE, (char *)modeinfo); | |
347 wcKanjiControl((int)obj, KC_SETMODEINFOSTYLE, (char *)0); | |
348 if (modeinfo[0] - '@' == CANNA_MODE_AlphaMode) { | |
349 toJapaneseMode(obj); | |
350 convend(obj); | |
351 } | |
352 } | |
353 openSelection(obj, SELECTION_DO, 0/* dummy */); | |
354 } | |
355 | |
356 static ICString * | |
357 GetMode(w) | |
358 Widget w; | |
359 { | |
360 CannaObject obj = (CannaObject)w; | |
361 wchar *mode; | |
362 static ICString icstr; | |
363 | |
364 icstr.nchars = obj->canna.ibuf->modelen; | |
365 if (icstr.nchars > 0) { | |
366 mode = obj->canna.ibuf->curmode; | |
367 icstr.data = (char *)mode; | |
368 icstr.nbytes = icstr.nchars * sizeof(wchar); | |
369 icstr.attr = ICAttrNormalString; | |
370 } | |
371 return &icstr; | |
372 } | |
373 | |
374 static int | |
375 CursorPos(w, nsegp, ncharp) | |
376 Widget w; | |
377 Cardinal *nsegp; | |
378 Cardinal *ncharp; | |
379 { | |
380 CannaObject obj = (CannaObject)w; | |
381 iBuf *ib = obj->canna.ibuf; | |
382 Cardinal nseg, nchar; | |
383 int ret = 0; | |
384 | |
385 if (ib->curseg < ib->nseg) { | |
386 nseg = ib->curseg; | |
387 nchar = 0; | |
388 } | |
389 else { | |
390 nseg = ib->offset; | |
391 nchar = ib->len[0 + ib->offset]; | |
392 ret = 1; | |
393 } | |
394 if (nsegp) { | |
395 *nsegp = nseg; | |
396 } | |
397 if (ncharp) { | |
398 *ncharp = nchar; | |
399 } | |
400 | |
401 return ret; | |
402 } | |
403 | |
404 static int | |
405 NumSegments(w) | |
406 Widget w; | |
407 { | |
408 CannaObject obj = (CannaObject)w; | |
409 iBuf *ib = obj->canna.ibuf; | |
410 | |
411 return ib->nseg; | |
412 } | |
413 | |
414 static ICString * | |
415 GetSegment(w, n) | |
416 Widget w; | |
417 Cardinal n; | |
418 { | |
419 CannaObject obj = (CannaObject)w; | |
420 iBuf *ib = obj->canna.ibuf; | |
421 static ICString seg; | |
422 | |
423 seg.data = (char *)ib->str[n]; | |
424 seg.nchars = ib->len[n]; | |
425 seg.nbytes = seg.nchars * sizeof(wchar); | |
426 if (ib->curseg == n) { | |
427 seg.attr = ICAttrConverted | ICAttrCurrentSegment; | |
428 } | |
429 else if (n < ib->offset) { | |
430 seg.attr = ICAttrConverted; | |
431 } | |
432 else { | |
433 seg.attr = ICAttrNotConverted; | |
434 } | |
435 | |
436 return &seg; | |
437 } | |
438 | |
439 /* ARGSUSED */ | |
440 static int | |
441 CompareSegment(w, seg1, seg2, n) | |
442 Widget w; | |
443 ICString *seg1; | |
444 ICString *seg2; | |
445 Cardinal *n; | |
446 { | |
447 wchar *p, *q; | |
448 int len, nsame; | |
449 int result = 0; | |
450 | |
451 if (seg1->attr != seg2->attr) result |= ICAttrChanged; | |
452 | |
453 len = seg1->nchars > seg2->nchars ? seg2->nchars : seg1->nchars; | |
454 nsame = 0; | |
455 p = (wchar *)seg1->data; | |
456 q = (wchar *)seg2->data; | |
457 while (nsame < len && *p++ == *q++) nsame++; | |
458 | |
459 if (nsame != len || len != seg1->nchars || len != seg2->nchars) | |
460 result |= ICStringChanged; | |
461 | |
462 if (n) *n = nsame; | |
463 | |
464 return result; | |
465 } | |
466 | |
467 static ICString * | |
468 GetItemList(w, n) | |
469 Widget w; | |
470 Cardinal *n; | |
471 { | |
472 CannaObject obj = (CannaObject)w; | |
473 | |
474 *n = obj->canna.numcand; | |
475 return obj->canna.candlist; | |
476 } | |
477 | |
478 #define SELECTBUFSIZE 1024 | |
479 | |
480 static int | |
481 SelectItem(w, n) | |
482 Widget w; | |
483 int n; | |
484 { | |
485 CannaObject obj = (CannaObject)w; | |
486 wcKanjiStatus ks; | |
487 wcKanjiStatusWithValue ksv; | |
488 wchar buf[SELECTBUFSIZE]; | |
489 | |
490 if (n >= 0) | |
491 *(obj->canna.cur_addr) = n; | |
492 | |
493 ksv.ks = &ks; | |
494 buf[0] = (wchar)'\r'; | |
495 ksv.buffer = buf; | |
496 ksv.n_buffer = SELECTBUFSIZE; | |
497 ksv.val = CANNA_FN_Kakutei; | |
498 { | |
499 ignoreListfunc = 1; | |
500 wcKanjiControl((int)obj, KC_DO, (char *)&ksv); | |
501 ignoreListfunc = 0; | |
502 } | |
503 displayPreEdit(obj, ksv.val, buf, ksv.ks); | |
504 return 0; | |
505 } | |
506 | |
507 static int | |
508 ConvertedString(w, encoding, format, length, string) | |
509 Widget w; | |
510 Atom *encoding; | |
511 int *format; | |
512 int *length; | |
513 XtPointer *string; | |
514 { | |
515 CannaObject obj = (CannaObject)w; | |
516 iBuf *ib = obj->canna.ibuf; | |
517 wchar *wbuf, *wp; | |
518 int len, wlen; | |
519 extern int convJWStoCT(); | |
520 int offset = ib->offset; | |
521 | |
522 if (ib == NULL) return -1; | |
523 | |
524 if (ib->nseg == 0 || ib->offset == 0) return -1; | |
525 | |
526 wlen = ib->len[offset - 1]; | |
527 if (wlen == 0) return -1; | |
528 | |
529 wbuf = ib->str[offset - 1]; | |
530 | |
531 /* | |
532 * Canna $B%*%V%8%'%/%H$O(B COMPOUND_TEXT $B%(%s%3!<%G%#%s%0$7$+%5%]!<%H$7$J$$(B | |
533 * COMPOUND_TEXT $B$KJQ49$9$k(B | |
534 */ | |
535 *encoding = XA_COMPOUND_TEXT(XtDisplayOfObject((Widget)obj)); | |
536 *format = 8; | |
537 | |
538 /* COMPOUND_TEXT $B$O(B \r $B$,Aw$l$J$$$N$G(B \n $B$KJQ49$7$F$*$/(B */ | |
539 for (wp = wbuf; *wp != 0; wp++) { | |
540 if (*wp == '\r') *wp = '\n'; | |
541 } | |
542 | |
543 *length = len = convJWStoCT(wbuf, (unsigned char *)NULL, 0); | |
544 *string = XtMalloc(len + 1); | |
545 (void)convJWStoCT(wbuf, (unsigned char *)*string, 0); | |
546 | |
547 shiftLeftAll(ib); | |
548 | |
549 return 0; | |
550 } | |
551 | |
552 static int | |
553 ClearConversion(w) | |
554 Widget w; | |
555 { | |
556 CannaObject obj = (CannaObject)w; | |
557 | |
558 wcKanjiStatus ks; | |
559 wcKanjiStatusWithValue ksv; | |
560 wchar buf[SELECTBUFSIZE]; | |
561 | |
562 ksv.ks = &ks; | |
563 ksv.buffer = buf; | |
564 ksv.n_buffer = SELECTBUFSIZE; | |
565 wcKanjiControl((int)obj, KC_KILL, (char *)&ksv); | |
566 displayPreEdit(obj, ksv.val, buf, ksv.ks); | |
567 return 0; | |
568 } | |
569 | |
570 static ICString * | |
571 GetAuxSegments(w, n, ns, nc) | |
572 Widget w; | |
573 Cardinal *n, *ns, *nc; | |
574 { | |
575 CannaObject obj = (CannaObject)w; | |
576 iBuf *ib = obj->canna.ibuf; | |
577 Cardinal nseg, nchar; | |
578 | |
579 if (n) { | |
580 *n = ib->ngseg; | |
581 } | |
582 | |
583 if (ib->curgseg < ib->ngseg) { | |
584 nseg = ib->curgseg; | |
585 nchar = 0; | |
586 } | |
587 else { | |
588 nseg = 0; | |
589 nchar = ib->gllen[0]; | |
590 } | |
591 if (ns) { | |
592 *ns = nseg; | |
593 } | |
594 if (nc) { | |
595 *nc = nchar; | |
596 } | |
597 | |
598 return ib->ics; | |
599 } | |
600 | |
601 /* ARGSUSED */ | |
602 static void | |
603 Initialize(req, new, args, num_args) | |
604 Widget req; | |
605 Widget new; | |
606 ArgList args; | |
607 Cardinal *num_args; | |
608 { | |
609 CannaObject obj = (CannaObject)new; | |
610 | |
611 obj->canna.selectionending = False; | |
612 obj->canna.textchanged = False; | |
613 obj->canna.symbollist = SymbolList; | |
614 obj->canna.numsymbols = NumSymbols; | |
615 obj->canna.cursymbol = 0; | |
616 obj->canna.candlist = NULL; | |
617 obj->canna.candlistsize = 0; | |
618 obj->canna.numcand = 0; | |
619 obj->canna.lastTextLengthIsZero = False; | |
620 | |
621 ibufInitialize(obj); | |
622 | |
623 /* $BJQ49$N=i4|2=(B */ | |
624 initializeCannaConnection(obj); | |
625 | |
626 addObject(obj); | |
627 } | |
628 | |
629 static int | |
630 bell() | |
631 { | |
632 if (displaybell) { | |
633 XBell(displaybell, 0); | |
634 } | |
635 return 0; | |
636 } | |
637 | |
638 static int nCannaContexts = 0; | |
639 | |
640 static | |
641 initializeCannaConnection(obj) | |
642 CannaObject obj; | |
643 { | |
644 char **warn = 0; | |
645 extern (*jrBeepFunc)(); | |
646 | |
647 if (nCannaContexts == 0) { | |
648 #ifdef KC_SETSERVERNAME | |
649 if (obj->canna.cannahost != NULL) { | |
650 wcKanjiControl((int)obj, KC_SETSERVERNAME, obj->canna.cannahost); | |
651 } | |
652 #endif /* KC_SETSERVERNAME */ | |
653 #ifdef KC_SETINITFILENAME | |
654 if (obj->canna.cannafile != NULL) { | |
655 wcKanjiControl((int)obj, KC_SETINITFILENAME, obj->canna.cannafile); | |
656 } | |
657 #endif /* KC_SETINITFILENAME */ | |
658 | |
659 wcKanjiControl((int)obj, KC_INITIALIZE, (char *)&warn); | |
660 TRACE(("Canna initialized\n")); | |
661 | |
662 if (warn) { | |
663 char **p; | |
664 | |
665 for (p = warn; *p ; p++) { | |
666 XtAppWarning(XtWidgetToApplicationContext((Widget)obj), *p); | |
667 } | |
668 } | |
669 } | |
670 nCannaContexts++; | |
671 | |
672 #ifdef KC_SETAPPNAME | |
673 wcKanjiControl((int)obj, KC_SETAPPNAME, "kinput2"); | |
674 #endif | |
675 | |
676 #ifdef DONT_USE_HANKAKU_KATAKANA | |
677 /* $BH>3Q%+%?%+%J$N6X;_(B */ | |
678 wcKanjiControl((int)obj, KC_INHIBITHANKAKUKANA, (char *)1); | |
679 #endif | |
680 | |
681 /* $B0lMw9T$r#7#8%3%i%`$K@_Dj(B */ | |
682 wcKanjiControl((int)obj, KC_SETWIDTH, (char *)78); | |
683 | |
684 /* $B8uJd0lMw%3!<%k%P%C%/$r@_Dj(B */ | |
685 | |
686 #ifdef KC_SETLISTCALLBACK | |
687 { | |
688 jrListCallbackStruct lcs; | |
689 | |
690 lcs.client_data = (char *)obj; | |
691 lcs.callback_func = listfunc; | |
692 wcKanjiControl((int)obj, KC_SETLISTCALLBACK, (char *)&lcs); | |
693 } | |
694 #endif /* KC_SETLISTCALLBACK */ | |
695 | |
696 jrBeepFunc = bell; | |
697 | |
698 /* $B$5$i$KF|K\8lF~NO%b!<%I$K$7$F$*$/(B */ | |
699 toJapaneseMode(obj); | |
700 } | |
701 | |
702 | |
703 static void | |
704 Destroy(w) | |
705 Widget w; | |
706 { | |
707 CannaObject obj = (CannaObject)w; | |
708 wcKanjiStatusWithValue ksv; | |
709 wcKanjiStatus ks; | |
710 wchar buf[512]; | |
711 int i; | |
712 | |
713 /* $B%P%C%U%!$N2rJ|(B */ | |
714 | |
715 freeIBuf(obj->canna.ibuf); | |
716 | |
717 if (obj->canna.candlist) { | |
718 for (i = 0 ; i < obj->canna.candlistsize ; i++) { | |
719 if ((obj->canna.candlist + i)->data) { | |
720 XtFree((obj->canna.candlist + i)->data); | |
721 } | |
722 } | |
723 | |
724 XtFree((char *)obj->canna.candlist); | |
725 } | |
726 | |
727 /* $B!X$+$s$J!Y$N=hM}(B */ | |
728 ksv.buffer = buf; | |
729 ksv.n_buffer = 512; | |
730 ksv.ks = &ks; | |
731 | |
732 wcKanjiControl((int)obj, KC_CLOSEUICONTEXT, (char *)&ksv); | |
733 | |
734 if (--nCannaContexts == 0) { | |
735 char **warn = 0; | |
736 | |
737 wcKanjiControl(0, KC_FINALIZE, (char *)&warn); | |
738 if (warn) { | |
739 char **p; | |
740 | |
741 for (p = warn; *p ; p++) { | |
742 XtAppWarning(XtWidgetToApplicationContext((Widget)obj), *p); | |
743 } | |
744 } | |
745 } | |
746 | |
747 deleteObject(obj); | |
748 } | |
749 | |
750 static Boolean | |
751 SetValues(cur, req, wid, args, num_args) | |
752 Widget cur; | |
753 Widget req; | |
754 Widget wid; | |
755 ArgList args; | |
756 Cardinal *num_args; | |
757 /* ARGSUSED */ | |
758 { | |
759 CannaObject old = (CannaObject)cur; | |
760 CannaObject new = (CannaObject)wid; | |
761 | |
762 return False; | |
763 } | |
764 | |
765 static void | |
766 fix(obj) | |
767 CannaObject obj; | |
768 { | |
769 /* $B3NDj$N=hM}(B */ | |
770 XtCallCallbackList((Widget)obj, obj->inputConv.fixcallback, | |
771 (XtPointer)NULL); /* $B!)!)!)(B */ | |
772 } | |
773 | |
774 static void | |
775 convend(obj) | |
776 CannaObject obj; | |
777 { | |
778 XtCallCallbackList((Widget)obj, obj->inputConv.endcallback, | |
779 (XtPointer)NULL); | |
780 } | |
781 | |
782 /* | |
783 * keeping list of objects | |
784 */ | |
785 typedef struct _oblist_ { | |
786 CannaObject obj; | |
787 struct _oblist_ *next; | |
788 } ObjRec; | |
789 | |
790 static ObjRec *ObjList = NULL; | |
791 | |
792 static void | |
793 addObject(obj) | |
794 CannaObject obj; | |
795 { | |
796 ObjRec *objp = XtNew(ObjRec); | |
797 | |
798 objp->obj = obj; | |
799 objp->next = ObjList; | |
800 ObjList = objp; | |
801 } | |
802 | |
803 static void | |
804 deleteObject(obj) | |
805 CannaObject obj; | |
806 { | |
807 ObjRec *objp, *objp0; | |
808 | |
809 for (objp0 = NULL, objp = ObjList; | |
810 objp != NULL; | |
811 objp0 = objp, objp = objp->next) { | |
812 if (objp->obj == obj) { | |
813 if (objp0 == NULL) { | |
814 ObjList = objp->next; | |
815 } else { | |
816 objp0->next = objp->next; | |
817 } | |
818 XtFree((char *)objp); | |
819 return; | |
820 } | |
821 } | |
822 } | |
823 | |
824 /* | |
825 * Operations to canna.ibuf | |
826 */ | |
827 | |
828 /* cfuncdef | |
829 | |
830 changeTextForCanna -- ibuf $B$NFbMF$r(B kanji_status $B$rMQ$$$F=q$-49$($k!#(B | |
831 | |
832 | |
833 $B4pK\E*$K$O8uJdJ8;zNs$H8uJd0lMw9TJ8;zNs$K4X$7$F0J2<$N=hM}$r9T$&!#(B | |
834 | |
835 (1) $B$$$:$l$NJ8;zNs$b%F%-%9%H$,H?E>$7$F$$$kItJ,$H$=$&$G$J$$ItJ,(B | |
836 $B$,B8:_$7!"H?E>$7$F$$$kItJ,$O#1%+=j$7$+B8:_$7$J$$!#(B | |
837 (2) $B$7$?$,$C$F$$$:$l$NJ8;zNs$bH?E>$7$F$$$k$H$3$m$H$=$NN>C<$KH?E>(B | |
838 $B$7$F$$$J$$ItJ,$H$,B8:_$9$k>l9g$K#3ItJ,$KJ,$+$l$k$3$H$K$J$j!"(B | |
839 $BH?E>$7$F$$$kItJ,$N0LCV$d!"H?E>$7$F$$$k2U=j$,$J$$>l9g$J$I$r(B | |
840 $B9g$o$;$F9M$($F$b#3ItJ,0J>e$KJ,$+$l$k$3$H$O$J$$!#(B | |
841 (3) $B$7$?$,$C$F!"$$$:$l$NJ8;zNs$b:GBg#3$D$N%;%0%a%s%H$KJ,$1$FI=<((B | |
842 $B%&%#%8%'%C%H$KEO$9$h$&$K$9$k!#(B | |
843 | |
844 */ | |
845 | |
846 static | |
847 changeTextForCanna(cldata, ksp) | |
848 caddr_t cldata; | |
849 wcKanjiStatus *ksp; | |
850 { | |
851 CannaObject obj = (CannaObject)cldata; | |
852 iBuf *ibuf = obj->canna.ibuf; | |
853 int offset = ibuf->offset, i; | |
854 | |
855 if (ksp->length == 0) { | |
856 ibuf->curseg = offset; | |
857 ibuf->nseg = offset; | |
858 ibuf->len[0 + offset] = ibuf->len[1 + offset] = | |
859 ibuf->len[2 + offset] = 0; | |
860 if (!obj->canna.lastTextLengthIsZero) { | |
861 obj->canna.textchanged = True; | |
862 obj->canna.lastTextLengthIsZero = True; | |
863 } | |
864 } | |
865 else if (ksp->length > 0) { | |
866 obj->canna.lastTextLengthIsZero = False; | |
867 ibuf->len[1 + offset] = ibuf->len[2 + offset] = 0; | |
868 if (ksp->revLen > 0) { | |
869 if (ksp->revPos == 0) { | |
870 int remain = ksp->length - ksp->revLen; | |
871 | |
872 copyInWchar(ksp->echoStr, ksp->revLen, | |
873 &(ibuf->str[0 + offset]), &(ibuf->size[0 + offset]), | |
874 &(ibuf->len[0 + offset])); | |
875 ibuf->curseg = offset; | |
876 ibuf->nseg = offset + 1; | |
877 if (remain) { | |
878 copyInWchar(ksp->echoStr + ksp->revLen, remain, | |
879 &(ibuf->str[1 + offset]), &(ibuf->size[1 + offset]), | |
880 &(ibuf->len[1 + offset])); | |
881 ibuf->nseg = offset + 2; | |
882 } | |
883 } | |
884 else { | |
885 int remain = ksp->length - ksp->revPos - ksp->revLen; | |
886 | |
887 copyInWchar(ksp->echoStr, ksp->revPos, | |
888 &(ibuf->str[0 + offset]), &(ibuf->size[0 + offset]), | |
889 &(ibuf->len[0 + offset])); | |
890 copyInWchar(ksp->echoStr + ksp->revPos, ksp->revLen, | |
891 &(ibuf->str[1 + offset]), &(ibuf->size[1 + offset]), | |
892 &(ibuf->len[1 + offset])); | |
893 ibuf->curseg = offset + 1; | |
894 ibuf->nseg = offset + 2; | |
895 if (remain) { | |
896 copyInWchar(ksp->echoStr + ksp->revPos + ksp->revLen, | |
897 remain, | |
898 &(ibuf->str[2 + offset]), &(ibuf->size[2 + offset]), | |
899 &(ibuf->len[2 + offset])); | |
900 ibuf->nseg = offset + 3; | |
901 } | |
902 } | |
903 } | |
904 else { | |
905 copyInWchar(ksp->echoStr, ksp->length, | |
906 &(ibuf->str[0 + offset]), &(ibuf->size[0 + offset]), | |
907 &(ibuf->len[0 + offset])); | |
908 ibuf->len[1 + offset] = ibuf->len[2 + offset] = 0; | |
909 ibuf->nseg = offset + 1; | |
910 ibuf->curseg = offset + 1; | |
911 } | |
912 obj->canna.textchanged = True; | |
913 } | |
914 /* $B%b!<%I(B */ | |
915 if (ksp->info & KanjiModeInfo) { | |
916 int modelen = 0; | |
917 | |
918 while (ksp->mode[modelen]) modelen++; | |
919 copyInWchar(ksp->mode, modelen, | |
920 &(ibuf->curmode), &(ibuf->modesize), &(ibuf->modelen)); | |
921 } | |
922 /* $B0lMw9T(B */ | |
923 if (ksp->info & KanjiGLineInfo) { | |
924 if (ksp->gline.length == 0) { | |
925 switch (ibuf->candstat) { | |
926 case CANNA_GLINE_Empty: | |
927 case CANNA_GLINE_End: | |
928 ibuf->candstat = CANNA_GLINE_Empty; | |
929 break; | |
930 case CANNA_GLINE_Start: | |
931 case CANNA_GLINE_Change: | |
932 ibuf->candstat = CANNA_GLINE_End; | |
933 break; | |
934 } | |
935 ibuf->curgseg = 0; | |
936 ibuf->ngseg = 0; | |
937 ibuf->gllen[0] = ibuf->gllen[1] = ibuf->gllen[2] = 0; | |
938 } | |
939 else if (ksp->gline.length > 0) { | |
940 switch (ibuf->candstat) { | |
941 case CANNA_GLINE_Empty: | |
942 case CANNA_GLINE_End: | |
943 ibuf->candstat = CANNA_GLINE_Start; | |
944 break; | |
945 case CANNA_GLINE_Start: | |
946 case CANNA_GLINE_Change: | |
947 ibuf->candstat = CANNA_GLINE_Change; | |
948 break; | |
949 } | |
950 ibuf->gllen[1] = ibuf->gllen[2] = 0; | |
951 if (ksp->gline.revLen > 0) { | |
952 if (ksp->gline.revPos == 0) { | |
953 int remain = ksp->gline.length - ksp->gline.revLen; | |
954 | |
955 copyInWchar(ksp->gline.line, ksp->gline.revLen, | |
956 &(ibuf->gline[0]), &(ibuf->glsize[0]), | |
957 &(ibuf->gllen[0])); | |
958 ibuf->curgseg = 0; | |
959 ibuf->ngseg = 1; | |
960 if (remain) { | |
961 copyInWchar(ksp->gline.line + ksp->gline.revLen, remain, | |
962 &(ibuf->gline[1]), &(ibuf->glsize[1]), | |
963 &(ibuf->gllen[1])); | |
964 ibuf->ngseg = 2; | |
965 } | |
966 } | |
967 else { | |
968 int remain = ksp->gline.length | |
969 - ksp->gline.revPos - ksp->gline.revLen; | |
970 | |
971 copyInWchar(ksp->gline.line, ksp->gline.revPos, | |
972 &(ibuf->gline[0]), &(ibuf->glsize[0]), | |
973 &(ibuf->gllen[0])); | |
974 copyInWchar(ksp->gline.line + ksp->gline.revPos, ksp->gline.revLen, | |
975 &(ibuf->gline[1]), &(ibuf->glsize[1]), | |
976 &(ibuf->gllen[1])); | |
977 ibuf->curgseg = 1; | |
978 ibuf->ngseg = 2; | |
979 if (remain) { | |
980 copyInWchar(ksp->gline.line | |
981 + ksp->gline.revPos + ksp->gline.revLen, | |
982 remain, | |
983 &(ibuf->gline[2]), &(ibuf->glsize[2]), | |
984 &(ibuf->gllen[2])); | |
985 ibuf->ngseg = 3; | |
986 } | |
987 } | |
988 } | |
989 else { | |
990 copyInWchar(ksp->gline.line, ksp->gline.length, | |
991 &(ibuf->gline[0]), &(ibuf->glsize[0]), | |
992 &(ibuf->gllen[0])); | |
993 ibuf->gllen[1] = ibuf->gllen[2] = 0; | |
994 ibuf->ngseg = 1; | |
995 ibuf->curgseg = 1; | |
996 } | |
997 } | |
998 for (i = 0 ; i < ibuf->ngseg ; i++) { | |
999 ibuf->ics[i].data = (char *)ibuf->gline[i]; | |
1000 ibuf->ics[i].nchars = ibuf->gllen[i]; | |
1001 ibuf->ics[i].nbytes = ibuf->gllen[i] * sizeof(wchar); | |
1002 ibuf->ics[i].attr = ICAttrConverted; | |
1003 } | |
1004 if (ibuf->curgseg < ibuf->ngseg) { | |
1005 ibuf->ics[ibuf->curgseg].attr |= ICAttrCurrentSegment; | |
1006 } | |
1007 } | |
1008 } | |
1009 | |
1010 /* cfuncdef | |
1011 | |
1012 copyInWchar -- wchar $B$r%3%T!<$9$k!#(B | |
1013 | |
1014 ws, wlen $B$G<($5$l$?(B wchar $BJ8;zNs$r(B wsbuf $B$N%]%$%s%H@h$N%P%C%U%!$K3J(B | |
1015 $BG<$9$k!#(Bwsbuf $B$N%5%$%:$O(B wssize $B$N%]%$%s%H@h$K3JG<$5$l$F$$$kCM$G;X(B | |
1016 $BDj$5$l$k$,!"$=$l$G$O>.$5$$;~$O(B copyInWchar $BFb$G(B XtRealloc $B$5$l!"?7(B | |
1017 $B$?$K%"%m%1!<%H$5$l$?%P%C%U%!$,(B wsbuf $B$N%]%$%s%H@h$K3JG<$5$l$k!#$^$?!"(B | |
1018 $B%P%C%U%!$N?7$?$J%5%$%:$,(B wssize $B$N%]%$%s%H@h$K3JG<$5$l$k!#F@$i$l$?(B | |
1019 $BJ8;z?t$,(Bwslen $B$N%]%$%s%H@h$K3JG<$5$l$k!#(B | |
1020 | |
1021 */ | |
1022 | |
1023 static | |
1024 copyInWchar(ws, wlen, wsbuf, wssize, wslen) | |
1025 wchar *ws; | |
1026 int wlen; | |
1027 wchar **wsbuf; | |
1028 int *wssize, *wslen; | |
1029 { | |
1030 int i; | |
1031 | |
1032 if (*wssize == 0) { | |
1033 if ((*wsbuf = (wchar *)XtMalloc((wlen + 1) * sizeof(wchar))) | |
1034 == (wchar *)0) { | |
1035 /* $B%(%i!<$@(B */ | |
1036 } | |
1037 else { | |
1038 *wssize = wlen + 1; | |
1039 } | |
1040 } | |
1041 if (wlen + 1 > *wssize) { | |
1042 if ((*wsbuf = (wchar *)XtRealloc((char *)*wsbuf, | |
1043 (wlen + 1) * sizeof(wchar))) | |
1044 == (wchar *)0) { | |
1045 /* $B%(%i!<$@!#$I$&$9$l$PNI$$!)(B */ | |
1046 } | |
1047 else { | |
1048 *wssize = wlen + 1; | |
1049 } | |
1050 } | |
1051 *wslen = wlen; | |
1052 (void)bcopy(ws, *wsbuf, wlen * sizeof(wchar)); | |
1053 *(*wsbuf + wlen) = (wchar)0; | |
1054 | |
1055 return 0; /* $B#0$OFC$K0UL#$,L5$$(B */ | |
1056 } | |
1057 | |
1058 /* cfuncdef | |
1059 | |
1060 fixProcForCanna -- $B3NDj$7$?J8;z$N=hM}$r9T$&(B | |
1061 | |
1062 */ | |
1063 | |
1064 static | |
1065 fixProcForCanna(cldata, fixedstr, fixedlen) | |
1066 caddr_t cldata; | |
1067 wchar *fixedstr; | |
1068 int fixedlen; | |
1069 { | |
1070 CannaObject obj = (CannaObject)cldata; | |
1071 iBuf *ib = obj->canna.ibuf; | |
1072 int offset = ib->offset; | |
1073 | |
1074 if (offset < NConvertedSegments) { | |
1075 shiftRight(ib); | |
1076 offset = ib->offset; | |
1077 } | |
1078 else { | |
1079 shiftLeft(ib); | |
1080 } | |
1081 copyInWchar(fixedstr, fixedlen, | |
1082 &(ib->str[offset - 1]), &(ib->size[offset - 1]), | |
1083 &(ib->len[offset - 1])); | |
1084 } | |
1085 | |
1086 /* cfuncdef | |
1087 | |
1088 shiftRight -- ibuf $B$NJ8;z%P%C%U%!$N(B offset $B0J9_$r1&$K%7%U%H$9$k(B | |
1089 | |
1090 */ | |
1091 | |
1092 static | |
1093 shiftRight(ib) | |
1094 iBuf *ib; | |
1095 { | |
1096 int i; | |
1097 wchar *tmpbuf; | |
1098 int tmpsize, tmplen; | |
1099 int offset = ib->offset; | |
1100 | |
1101 tmpbuf = ib->str[ib->nseg]; | |
1102 tmpsize = ib->size[ib->nseg]; | |
1103 for (i = ib->nseg ; offset < i ; i--) { | |
1104 ib->str[i] = ib->str[i - 1]; | |
1105 ib->size[i] = ib->size[i - 1]; | |
1106 ib->len[i] = ib->len[i - 1]; | |
1107 } | |
1108 ib->str[offset] = tmpbuf; | |
1109 ib->size[offset] = tmpsize; | |
1110 ib->offset++; | |
1111 ib->nseg++; | |
1112 ib->curseg++; | |
1113 } | |
1114 | |
1115 /* cfuncdef | |
1116 | |
1117 shiftLeft -- ibuf $B$NJ8;z%P%C%U%!$N(B offset $B0JA0$r:8$K%7%U%H$9$k(B | |
1118 | |
1119 */ | |
1120 | |
1121 static | |
1122 shiftLeft(ib) | |
1123 iBuf *ib; | |
1124 { | |
1125 int i; | |
1126 wchar *tmpbuf; | |
1127 int tmpsize, tmplen; | |
1128 int offset = ib->offset; | |
1129 | |
1130 tmpbuf = ib->str[0]; | |
1131 tmpsize = ib->size[0]; | |
1132 for (i = 0 ; i < offset - 1 ; i++) { | |
1133 ib->str[i] = ib->str[i + 1]; | |
1134 ib->size[i] = ib->size[i + 1]; | |
1135 ib->len[i] = ib->len[i + 1]; | |
1136 } | |
1137 ib->str[offset - 1] = tmpbuf; | |
1138 ib->size[offset - 1] = tmpsize; | |
1139 } | |
1140 | |
1141 /* cfuncdef | |
1142 | |
1143 shiftLeftAll -- ibuf $B$NJ8;z%P%C%U%!A4BN$r:8$K%7%U%H$9$k(B | |
1144 | |
1145 */ | |
1146 | |
1147 static | |
1148 shiftLeftAll(ib) | |
1149 iBuf *ib; | |
1150 { | |
1151 int i; | |
1152 wchar *tmpbuf; | |
1153 int tmpsize, tmplen; | |
1154 int nseg = ib->nseg; | |
1155 | |
1156 tmpbuf = ib->str[0]; | |
1157 tmpsize = ib->size[0]; | |
1158 for (i = 0 ; i < nseg - 1 ; i++) { | |
1159 ib->str[i] = ib->str[i + 1]; | |
1160 ib->size[i] = ib->size[i + 1]; | |
1161 ib->len[i] = ib->len[i + 1]; | |
1162 } | |
1163 ib->str[nseg - 1] = tmpbuf; | |
1164 ib->size[nseg - 1] = tmpsize; | |
1165 ib->nseg--; | |
1166 ib->curseg--; | |
1167 ib->offset--; | |
1168 } | |
1169 | |
1170 /* cfuncdef | |
1171 | |
1172 ibufInitialize -- ibuf $B$N=i4|2==hM}(B | |
1173 */ | |
1174 | |
1175 static | |
1176 ibufInitialize(obj) | |
1177 CannaObject obj; | |
1178 { | |
1179 int i; | |
1180 iBuf *ib; | |
1181 | |
1182 ib = obj->canna.ibuf = (iBuf *)XtMalloc(sizeof(iBuf)); | |
1183 if (ib == 0) { | |
1184 /* $B%(%i!<$@!#$I$&$9$Y(B */ | |
1185 } | |
1186 for (i = 0 ; i < NConvertedSegments + 3 ; i++) { | |
1187 ib->size[i] = 0; | |
1188 ib->len[i] = 0; | |
1189 } | |
1190 ib->offset = ib->curseg = ib->nseg = 0; | |
1191 ib->candstat = CANNA_GLINE_Empty; | |
1192 for (i = 0 ; i < 3 ; i++) { | |
1193 ib->gline[i] = 0; | |
1194 ib->glsize[i] = ib->gllen[i] = 0; | |
1195 } | |
1196 ib->modesize = 0; | |
1197 ib->modelen = 0; | |
1198 } | |
1199 | |
1200 /* cfuncdef | |
1201 | |
1202 freeIBuf -- ibuf $B$N(B free | |
1203 | |
1204 */ | |
1205 | |
1206 static | |
1207 freeIBuf(ib) | |
1208 iBuf *ib; | |
1209 { | |
1210 int i; | |
1211 | |
1212 if (ib == 0) { | |
1213 return 0; | |
1214 } | |
1215 for (i = 0 ; i < NConvertedSegments + 3 ; i++) { | |
1216 if (ib->size[i] > 0) { | |
1217 XtFree((char *)ib->str[i]); | |
1218 } | |
1219 } | |
1220 for (i = 0 ; i < 3 ; i++) { | |
1221 if (ib->glsize[i] > 0) { | |
1222 XtFree((char *)ib->gline[i]); | |
1223 } | |
1224 } | |
1225 if (ib->modesize > 0) { | |
1226 XtFree((char *)ib->curmode); | |
1227 } | |
1228 free(ib); | |
1229 return 0; | |
1230 } | |
1231 | |
1232 static | |
1233 toJapaneseMode(obj) | |
1234 CannaObject obj; | |
1235 { | |
1236 wcKanjiStatusWithValue ksv; | |
1237 wcKanjiStatus ks; | |
1238 wchar buf[1024]; | |
1239 | |
1240 buf[0] = '@'; | |
1241 ksv.ks = &ks; | |
1242 ksv.buffer = buf; | |
1243 ksv.n_buffer = 1024; | |
1244 #ifndef KC_DO | |
1245 ksv.val = CANNA_MODE_HenkanMode; | |
1246 wcKanjiControl((int)obj, KC_CHANGEMODE, (char *)&ksv); | |
1247 #else | |
1248 ksv.val = CANNA_FN_JapaneseMode; | |
1249 wcKanjiControl((int)obj, KC_DO, (char *)&ksv); | |
1250 #endif | |
1251 changeTextForCanna(obj, &ks); | |
1252 } | |
1253 | |
1254 /* checkIfFunctionalChar -- $B%7%U%H%-!<$N$h$&$KL50UL#$J%-!<$+$I$&$+$NH=JL(B | |
1255 | |
1256 $BCM(B: $B#1(B $B0UL#$,$"$k(B | |
1257 $B#0(B $BL50UL#(B($B%b%G%#%U%!%$%"%-!<$J$I(B) | |
1258 */ | |
1259 | |
1260 static int | |
1261 checkIfFunctionalChar(event_struct, keysym, buffer_return, n_buffer) | |
1262 XKeyEvent *event_struct; | |
1263 KeySym keysym; | |
1264 wchar *buffer_return; | |
1265 int n_buffer; | |
1266 { | |
1267 int functionalChar = 0; | |
1268 | |
1269 switch ((int)keysym) | |
1270 { | |
1271 case XK_KP_F1: | |
1272 case XK_KP_F2: | |
1273 case XK_KP_F3: | |
1274 case XK_KP_F4: | |
1275 *buffer_return = CANNA_KEY_PF1 + (int)keysym - (int)XK_KP_F1; | |
1276 functionalChar = 1; | |
1277 break; | |
1278 case XK_F1: | |
1279 case XK_F2: | |
1280 case XK_F3: | |
1281 case XK_F4: | |
1282 case XK_F5: | |
1283 case XK_F6: | |
1284 case XK_F7: | |
1285 case XK_F8: | |
1286 case XK_F9: | |
1287 case XK_F10: | |
1288 case XK_F11: | |
1289 case XK_F12: | |
1290 case XK_F13: | |
1291 case XK_F14: | |
1292 case XK_F15: | |
1293 case XK_F16: | |
1294 *buffer_return = CANNA_KEY_F1 + (int)keysym - (int)XK_F1; | |
1295 functionalChar = 1; | |
1296 break; | |
1297 case XK_Insert: | |
1298 *buffer_return = CANNA_KEY_Insert; | |
1299 functionalChar = 1; | |
1300 break; | |
1301 case XK_Prior: | |
1302 *buffer_return = CANNA_KEY_Rollup; | |
1303 functionalChar = 1; | |
1304 break; | |
1305 case XK_Next: | |
1306 *buffer_return = CANNA_KEY_Rolldown; | |
1307 functionalChar = 1; | |
1308 break; | |
1309 case XK_Muhenkan: | |
1310 if (event_struct->state & 4 /* control-shifted */) | |
1311 *buffer_return = CANNA_KEY_Cntrl_Nfer; | |
1312 else if (event_struct->state & 1 /* shifted */) | |
1313 *buffer_return = CANNA_KEY_Shift_Nfer; | |
1314 else | |
1315 *buffer_return = CANNA_KEY_Nfer; | |
1316 functionalChar = 1; | |
1317 break; | |
1318 case XK_Kanji: | |
1319 if (event_struct->state & 4 /* control-shifted */) | |
1320 *buffer_return = CANNA_KEY_Cntrl_Xfer; | |
1321 else if (event_struct->state & 1 /* shifted */) | |
1322 *buffer_return = CANNA_KEY_Shift_Xfer; | |
1323 else | |
1324 *buffer_return = CANNA_KEY_Xfer; | |
1325 functionalChar = 1; | |
1326 break; | |
1327 case XK_Up: | |
1328 if (event_struct->state & 4 /* control-shifted */) | |
1329 *buffer_return = CANNA_KEY_Cntrl_Up; | |
1330 else if (event_struct->state & 1 /* shifted */) | |
1331 *buffer_return = CANNA_KEY_Shift_Up; | |
1332 else | |
1333 *buffer_return = CANNA_KEY_Up; | |
1334 functionalChar = 1; | |
1335 break; | |
1336 case XK_Down: | |
1337 if (event_struct->state & 4 /* control-shifted */) | |
1338 *buffer_return = CANNA_KEY_Cntrl_Down; | |
1339 else if (event_struct->state & 1 /* shifted */) | |
1340 *buffer_return = CANNA_KEY_Shift_Down; | |
1341 else | |
1342 *buffer_return = CANNA_KEY_Down; | |
1343 functionalChar = 1; | |
1344 break; | |
1345 case XK_Right: | |
1346 if (event_struct->state & 4 /* control-shifted */) | |
1347 *buffer_return = CANNA_KEY_Cntrl_Right; | |
1348 else if (event_struct->state & 1 /* shifted */) | |
1349 *buffer_return = CANNA_KEY_Shift_Right; | |
1350 else | |
1351 *buffer_return = CANNA_KEY_Right; | |
1352 functionalChar = 1; | |
1353 break; | |
1354 case XK_Left: | |
1355 if (event_struct->state & 4 /* control-shifted */) | |
1356 *buffer_return = CANNA_KEY_Cntrl_Left; | |
1357 else if (event_struct->state & 1 /* shifted */) | |
1358 *buffer_return = CANNA_KEY_Shift_Left; | |
1359 else | |
1360 *buffer_return = CANNA_KEY_Left; | |
1361 functionalChar = 1; | |
1362 break; | |
1363 case XK_Help: | |
1364 *buffer_return = CANNA_KEY_Help; | |
1365 functionalChar = 1; | |
1366 break; | |
1367 case XK_Home: | |
1368 *buffer_return = CANNA_KEY_Home; | |
1369 functionalChar = 1; | |
1370 break; | |
1371 } | |
1372 return functionalChar; | |
1373 } | |
1374 | |
1375 #ifdef KC_SETLISTCALLBACK | |
1376 | |
1377 static void | |
1378 moveSelection(obj, dir) | |
1379 CannaObject obj; | |
1380 int dir; | |
1381 { | |
1382 ICSelectionControlArg arg; | |
1383 | |
1384 arg.command = ICSelectionMove; | |
1385 arg.u.dir = dir; | |
1386 XtCallCallbackList((Widget)obj, obj->inputConv.selectioncallback, | |
1387 (XtPointer)&arg); | |
1388 } | |
1389 | |
1390 static int | |
1391 insertSelection(obj, selected) | |
1392 CannaObject obj; | |
1393 int selected; | |
1394 { | |
1395 obj->canna.curcand = selected; | |
1396 *(obj->canna.cur_addr) = selected; | |
1397 | |
1398 return 0; | |
1399 } | |
1400 | |
1401 static void | |
1402 endSelection(obj, abort) | |
1403 CannaObject obj; | |
1404 int abort; | |
1405 { | |
1406 ICSelectionControlArg arg; | |
1407 int selected; | |
1408 | |
1409 if (ignoreListfunc) return; /* SelectItem $B$G=hM}$5$l$k$N$G$3$3$OITMW(B */ | |
1410 arg.command = ICSelectionEnd; | |
1411 arg.u.current_item = -1; | |
1412 XtCallCallbackList((Widget)obj, obj->inputConv.selectioncallback, | |
1413 (XtPointer)&arg); | |
1414 | |
1415 if (!abort && (selected = arg.u.current_item) >= 0) { | |
1416 insertSelection(obj, selected); | |
1417 } | |
1418 } | |
1419 | |
1420 #ifdef CANNA_LIST_Query | |
1421 static void | |
1422 querySelection(obj) | |
1423 CannaObject obj; | |
1424 { | |
1425 ICSelectionControlArg arg; | |
1426 int selected; | |
1427 | |
1428 if (ignoreListfunc) return; /* SelectItem $B$G=hM}$5$l$k$N$G$3$3$OITMW(B */ | |
1429 arg.command = ICSelectionGet; | |
1430 arg.u.current_item = -1; | |
1431 XtCallCallbackList((Widget)obj, obj->inputConv.selectioncallback, | |
1432 (XtPointer)&arg); | |
1433 | |
1434 if ((selected = arg.u.current_item) >= 0) { | |
1435 insertSelection(obj, selected); | |
1436 } | |
1437 } | |
1438 #endif | |
1439 | |
1440 static void | |
1441 openSelection(obj, func, curitem) | |
1442 CannaObject obj; | |
1443 int func; /* $B0lHV>e$r8+$h(B */ | |
1444 int curitem; | |
1445 { | |
1446 ICSelectionControlArg arg; | |
1447 static int current = 0; | |
1448 static int doit = 0; | |
1449 | |
1450 if (func == SELECTION_SET) { | |
1451 current = curitem; | |
1452 doit = 1; | |
1453 } | |
1454 else if (func == SELECTION_DO && doit) { | |
1455 doit = 0; | |
1456 arg.command = ICSelectionStart; | |
1457 arg.u.selection_kind = ICSelectionCandidates; | |
1458 XtCallCallbackList((Widget)obj, obj->inputConv.selectioncallback, | |
1459 (XtPointer)&arg); | |
1460 | |
1461 /* set current item */ | |
1462 arg.command = ICSelectionSet; | |
1463 arg.u.current_item = current; | |
1464 XtCallCallbackList((Widget)obj, obj->inputConv.selectioncallback, | |
1465 (XtPointer)&arg); | |
1466 } | |
1467 } | |
1468 | |
1469 static void getAllCandidates(); | |
1470 | |
1471 /* listfunc -- $B8uJd0lMw%b!<%I$K$J$C$?;~$K8F$S=P$5$l$k4X?t(B | |
1472 * | |
1473 * obj : KC_SETLISTCALLBACK $B$G@_Dj$7$?%/%i%$%"%s%H%G!<%?(B | |
1474 * func : $B8uJd0lMw5!G=$N8GM-$N5!G=$rI=$9#I#D(B | |
1475 * items : Start $B$N;~$K$O8uJd0lMw$NA4%"%$%F%`$,F~$k(B | |
1476 * nitems : $B!7(B $BA4%"%$%F%`$N?t$,F~$k(B | |
1477 * cur_item : $B!7(B $B%+%l%s%H%"%$%F%`HV9f$r3JG<$9$k%"%I%l%9$,F~$k(B | |
1478 */ | |
1479 | |
1480 static CANNA_LISTFUNCTYPE | |
1481 listfunc(obj, func, items, nitems, cur_item) | |
1482 CannaObject obj; | |
1483 int func; | |
1484 wchar **items; | |
1485 int nitems, *cur_item; | |
1486 { | |
1487 ICSelectionControlArg arg; | |
1488 int i; | |
1489 wchar **p; | |
1490 | |
1491 switch (func) { | |
1492 case CANNA_LIST_Start: | |
1493 getAllCandidates(obj, nitems, items); | |
1494 obj->canna.numcand = nitems; | |
1495 obj->canna.curcand = *cur_item; | |
1496 obj->canna.cur_addr = cur_item; | |
1497 openSelection(obj, SELECTION_SET, *cur_item); | |
1498 break; | |
1499 case CANNA_LIST_Select: | |
1500 endSelection(obj, False); | |
1501 break; | |
1502 case CANNA_LIST_Quit: | |
1503 endSelection(obj, True); | |
1504 break; | |
1505 #ifdef CANNA_LIST_Query | |
1506 case CANNA_LIST_Query: | |
1507 querySelection(obj); | |
1508 break; | |
1509 #endif | |
1510 #ifdef CANNA_LIST_Convert | |
1511 case CANNA_LIST_Convert: | |
1512 #endif | |
1513 case CANNA_LIST_Forward: | |
1514 moveSelection(obj, ICMoveRight); | |
1515 break; | |
1516 case CANNA_LIST_Backward: | |
1517 moveSelection(obj, ICMoveLeft); | |
1518 break; | |
1519 case CANNA_LIST_Next: | |
1520 moveSelection(obj, ICMoveDown); | |
1521 break; | |
1522 case CANNA_LIST_Prev: | |
1523 moveSelection(obj, ICMoveUp); | |
1524 break; | |
1525 case CANNA_LIST_BeginningOfLine: | |
1526 moveSelection(obj, ICMoveLeftMost); | |
1527 break; | |
1528 case CANNA_LIST_EndOfLine: | |
1529 moveSelection(obj, ICMoveRightMost); | |
1530 break; | |
1531 #ifdef CANNA_LIST_Insert | |
1532 case CANNA_LIST_Insert: | |
1533 return 0; | |
1534 #endif | |
1535 } | |
1536 #ifdef CANNA_LIST_Convert | |
1537 return 1; | |
1538 #endif | |
1539 } | |
1540 | |
1541 static void | |
1542 allocCandlist(obj, n) | |
1543 CannaObject obj; | |
1544 int n; | |
1545 { | |
1546 ICString *p; | |
1547 int i; | |
1548 | |
1549 if (n <= obj->canna.candlistsize) return; | |
1550 | |
1551 if (obj->canna.candlistsize == 0) { | |
1552 p = (ICString *)XtMalloc(n * sizeof(ICString)); | |
1553 } else { | |
1554 p = (ICString *)XtRealloc((char *)obj->canna.candlist, | |
1555 n * sizeof(ICString)); | |
1556 } | |
1557 for (i = obj->canna.candlistsize ; i < n ; i++) { | |
1558 p[i].nbytes = p[i].nchars = (unsigned short)0; | |
1559 p[i].data = (char *)0; | |
1560 p[i].attr = 0; | |
1561 } | |
1562 | |
1563 obj->canna.candlist = p; | |
1564 obj->canna.candlistsize = n; | |
1565 } | |
1566 | |
1567 static void | |
1568 getAllCandidates(obj, ncand, items) | |
1569 CannaObject obj; | |
1570 int ncand; | |
1571 wchar **items; | |
1572 { | |
1573 ICString *strp; | |
1574 wchar **p; | |
1575 int i, bytes, chars; | |
1576 | |
1577 allocCandlist(obj, ncand); | |
1578 | |
1579 for (i = 0, strp = obj->canna.candlist, p = items ; | |
1580 i < ncand; i++, strp++, p++) { | |
1581 int len = 0; | |
1582 | |
1583 bytes = strp->nbytes; | |
1584 chars = strp->nchars; | |
1585 while ((*p)[len]) len++; | |
1586 copyInWchar(*p, len, (wchar **)&(strp->data), &bytes, &chars); | |
1587 strp->nbytes = bytes; | |
1588 strp->nchars = chars; | |
1589 strp->attr = ICAttrNormalString; | |
1590 } | |
1591 } | |
1592 #endif /* KC_SETLISTCALLBACK */ | |
1593 | |
1594 struct _keymap { | |
1595 unsigned char cannakey; | |
1596 KeySym keysym; | |
1597 long modifier; | |
1598 } cannakeymap[] = { | |
1599 {(unsigned char)'\b', XK_BackSpace, 0}, | |
1600 {(unsigned char)'\t', XK_Tab, 0}, | |
1601 {(unsigned char)'\n', XK_Linefeed, 0}, | |
1602 {(unsigned char)'\013', XK_Clear, 0}, | |
1603 {(unsigned char)'\r', XK_Return, 0}, | |
1604 {(unsigned char)'\023', XK_Pause, 0}, | |
1605 {(unsigned char)'\024', XK_Scroll_Lock, 0}, | |
1606 {(unsigned char)'\e', XK_Escape, 0}, | |
1607 {(unsigned char)CANNA_KEY_Nfer, XK_Muhenkan, 0}, | |
1608 {(unsigned char)CANNA_KEY_Xfer, XK_Kanji, 0}, | |
1609 {(unsigned char)CANNA_KEY_Up, XK_Up, 0}, | |
1610 {(unsigned char)CANNA_KEY_Left, XK_Left, 0}, | |
1611 {(unsigned char)CANNA_KEY_Right, XK_Right, 0}, | |
1612 {(unsigned char)CANNA_KEY_Down, XK_Down, 0}, | |
1613 {(unsigned char)CANNA_KEY_Insert, XK_Insert, 0}, | |
1614 {(unsigned char)CANNA_KEY_Rollup, XK_Prior, 0}, | |
1615 {(unsigned char)CANNA_KEY_Rolldown, XK_Next, 0}, | |
1616 {(unsigned char)CANNA_KEY_Home, XK_Home, 0}, | |
1617 {(unsigned char)CANNA_KEY_Help, XK_Help, 0}, | |
1618 {(unsigned char)CANNA_KEY_KP_Key, XK_KP_Space, 0}, /* ? */ | |
1619 {(unsigned char)CANNA_KEY_Shift_Nfer, XK_Muhenkan, ShiftMask}, | |
1620 {(unsigned char)CANNA_KEY_Shift_Xfer, XK_Kanji, ShiftMask}, | |
1621 {(unsigned char)CANNA_KEY_Shift_Up, XK_Up, ShiftMask}, | |
1622 {(unsigned char)CANNA_KEY_Shift_Left, XK_Left, ShiftMask}, | |
1623 {(unsigned char)CANNA_KEY_Shift_Right, XK_Right, ShiftMask}, | |
1624 {(unsigned char)CANNA_KEY_Shift_Down, XK_Down, ShiftMask}, | |
1625 {(unsigned char)CANNA_KEY_Cntrl_Nfer, XK_Muhenkan, ControlMask}, | |
1626 {(unsigned char)CANNA_KEY_Cntrl_Xfer, XK_Kanji, ControlMask}, | |
1627 {(unsigned char)CANNA_KEY_Cntrl_Up, XK_Up, ControlMask}, | |
1628 {(unsigned char)CANNA_KEY_Cntrl_Left, XK_Left, ControlMask}, | |
1629 {(unsigned char)CANNA_KEY_Cntrl_Right, XK_Right, ControlMask}, | |
1630 {(unsigned char)CANNA_KEY_Cntrl_Down, XK_Down, ControlMask}, | |
1631 {(unsigned char)CANNA_KEY_F1, XK_F1, 0}, | |
1632 {(unsigned char)CANNA_KEY_F2, XK_F2, 0}, | |
1633 {(unsigned char)CANNA_KEY_F3, XK_F3, 0}, | |
1634 {(unsigned char)CANNA_KEY_F4, XK_F4, 0}, | |
1635 {(unsigned char)CANNA_KEY_F5, XK_F5, 0}, | |
1636 {(unsigned char)CANNA_KEY_F6, XK_F6, 0}, | |
1637 {(unsigned char)CANNA_KEY_F7, XK_F7, 0}, | |
1638 {(unsigned char)CANNA_KEY_F8, XK_F8, 0}, | |
1639 {(unsigned char)CANNA_KEY_F9, XK_F9, 0}, | |
1640 {(unsigned char)CANNA_KEY_F10, XK_F10, 0}, | |
1641 {(unsigned char)CANNA_KEY_PF1, XK_KP_F1, 0}, | |
1642 {(unsigned char)CANNA_KEY_PF2, XK_KP_F2, 0}, | |
1643 {(unsigned char)CANNA_KEY_PF3, XK_KP_F3, 0}, | |
1644 {(unsigned char)CANNA_KEY_PF4, XK_KP_F4, 0}, | |
1645 {(unsigned char)CANNA_KEY_PF5, XK_F15, 0}, | |
1646 {(unsigned char)CANNA_KEY_PF6, XK_F16, 0}, | |
1647 {(unsigned char)CANNA_KEY_PF7, XK_F17, 0}, | |
1648 {(unsigned char)CANNA_KEY_PF8, XK_F18, 0}, | |
1649 {(unsigned char)CANNA_KEY_PF9, XK_F19, 0}, | |
1650 {(unsigned char)CANNA_KEY_PF10, XK_F20, 0}, | |
1651 }; | |
1652 | |
1653 #define NCANNAKEYMAP (sizeof(cannakeymap) / sizeof(struct _keymap)) | |
1654 | |
1655 /* ARGSUSED */ | |
1656 static int | |
1657 GetTriggerKeys(w, keys_return) | |
1658 Widget w; | |
1659 ICTriggerKey **keys_return; | |
1660 { | |
1661 CannaObject obj = (CannaObject)w; | |
1662 ICTriggerKey *keys; | |
1663 unsigned char c, mkeys[256], *p, *ekeys; /* enough */ | |
1664 int n; | |
1665 struct _keymap *pk, *ek; | |
1666 | |
1667 n = wcKanjiControl((int)obj, KC_MODEKEYS, (char *)mkeys); | |
1668 | |
1669 *keys_return = keys = | |
1670 (ICTriggerKey *)XtMalloc(2 * n * sizeof(ICTriggerKey)); | |
1671 /* $B!V(B2 *$B!W$N0UL#(B: | |
1672 $B0l$D$N%3!<%I$K(B2$B$D$N(B X $B$N%-!<$,B8:_$7$F$$$?$j$9$k;v$,$"$k!#(B | |
1673 ($BNc(B) C-h $B"*(B Ctl<Key>h, <Key>Backspace */ | |
1674 | |
1675 if (keys) { | |
1676 for (p = mkeys, ekeys = p + n ; p < ekeys ; p++, keys++) { | |
1677 c = *p; | |
1678 if (c == (unsigned char)0) { | |
1679 keys->keysym = XK_space; | |
1680 keys->modifiers = keys->modifiermask = ControlMask; | |
1681 keys++; | |
1682 keys->keysym = XK_at; | |
1683 keys->modifiers = keys->modifiermask = ControlMask; | |
1684 } | |
1685 else if (c < ' ') { | |
1686 keys->keysym = XK_quoteleft + c; | |
1687 keys->modifiers = keys->modifiermask = ControlMask; | |
1688 for (pk = cannakeymap, ek = cannakeymap + NCANNAKEYMAP ; | |
1689 pk < ek ; pk++) { | |
1690 if (c == pk->cannakey) { | |
1691 keys++; | |
1692 keys->keysym = pk->keysym; | |
1693 keys->modifiers = keys->modifiermask = pk->modifier; | |
1694 } | |
1695 } | |
1696 } | |
1697 else if (c <= '~') { | |
1698 keys->keysym = XK_space + (c - (unsigned char)' '); | |
1699 keys->modifiers = keys->modifiermask = 0; | |
1700 } | |
1701 else if (c == 0x7f) { | |
1702 keys->keysym = XK_Delete; | |
1703 keys->modifiers = keys->modifiermask = 0; | |
1704 } | |
1705 else if ((unsigned char)0xa1 <= c && c <= (unsigned char)0xdf) { | |
1706 keys->keysym = XK_kana_fullstop + (c - (unsigned char)0xa1); | |
1707 keys->modifiers = keys->modifiermask = pk->modifier; | |
1708 } | |
1709 else { | |
1710 keys--; | |
1711 for (pk = cannakeymap, ek = cannakeymap + NCANNAKEYMAP ; | |
1712 pk < ek ; pk++) { | |
1713 if (c == pk->cannakey) { | |
1714 keys++; | |
1715 keys->keysym = pk->keysym; | |
1716 keys->modifiers = keys->modifiermask = pk->modifier; | |
1717 } | |
1718 } | |
1719 } | |
1720 } | |
1721 return n; | |
1722 } | |
1723 return 0; | |
1724 } | |
1725 | |
1726 /* ARGSUSED */ | |
1727 static int | |
1728 PreeditString(w, segn, offset, encoding, format, length, string) | |
1729 Widget w; | |
1730 int segn; | |
1731 int offset; | |
1732 Atom *encoding; | |
1733 int *format; | |
1734 int *length; | |
1735 XtPointer *string; | |
1736 { | |
1737 CannaObject obj = (CannaObject)w; | |
1738 iBuf *ib = obj->canna.ibuf; | |
1739 int i; | |
1740 wchar *wbuf, *wp; | |
1741 int len, wlen; | |
1742 extern int convJWStoCT(); | |
1743 | |
1744 if (ib == NULL) return -1; | |
1745 if (segn < ib->nseg && offset >= ib->len[segn]) { | |
1746 /* $B%;%0%a%s%H$N:G8e(B */ | |
1747 ++segn; | |
1748 offset = 0; | |
1749 } | |
1750 if (segn >= ib->nseg || offset >= ib->len[segn]) { | |
1751 /* $B:o=|$5$l$?(B */ | |
1752 *encoding = XA_COMPOUND_TEXT(XtDisplayOfObject(w)); | |
1753 *format = 8; | |
1754 *length = 0; | |
1755 *string = (XtPointer)XtMalloc(1); | |
1756 return 0; | |
1757 } | |
1758 | |
1759 wlen = 0; | |
1760 for (i = segn; i < ib->nseg; i++) { | |
1761 wlen += ib->len[i]; | |
1762 } | |
1763 wlen -= offset; | |
1764 | |
1765 wp = wbuf = (wchar *)XtMalloc((wlen + 1) * sizeof(wchar)); | |
1766 len = ib->len[segn] - offset; | |
1767 (void)bcopy((char *)(ib->str[segn] + offset), (char *)wp, sizeof(wchar) * len); | |
1768 wp += len; | |
1769 for (i = segn + 1; i < ib->nseg; i++) { | |
1770 len = ib->len[i]; | |
1771 (void)bcopy((char *)ib->str[i], (char *)wp, sizeof(wchar) * len); | |
1772 wp += len; | |
1773 } | |
1774 wbuf[wlen] = 0; | |
1775 | |
1776 /* | |
1777 * Canna $B%*%V%8%'%/%H$O(B COMPOUND_TEXT $B%(%s%3!<%G%#%s%0$7$+%5%]!<%H$7$J$$(B | |
1778 * COMPOUND_TEXT $B$KJQ49$9$k(B | |
1779 */ | |
1780 *encoding = XA_COMPOUND_TEXT(XtDisplayOfObject(w)); | |
1781 *format = 8; | |
1782 | |
1783 /* COMPOUND_TEXT $B$O(B \r $B$,Aw$l$J$$$N$G(B \n $B$KJQ49$7$F$*$/(B */ | |
1784 for (wp = wbuf; *wp != 0; wp++) { | |
1785 if (*wp == '\r') *wp = '\n'; | |
1786 } | |
1787 | |
1788 *length = len = convJWStoCT(wbuf, (unsigned char *)NULL, 0); | |
1789 *string = (XtPointer)XtMalloc(len + 1); | |
1790 (void)convJWStoCT(wbuf, (unsigned char *)*string, 0); | |
1791 | |
1792 /* wbuf $B$r(B free $B$7$F$*$/(B */ | |
1793 XtFree((char *)wbuf); | |
1794 | |
1795 return 0; | |
1796 } | |
1797 | |
1798 /* ARGSUSED */ | |
1799 static int | |
1800 StatusString(w, encoding, format, length, string, nchars) | |
1801 Widget w; | |
1802 Atom *encoding; | |
1803 int *format; | |
1804 int *length; | |
1805 XtPointer *string; | |
1806 int *nchars; | |
1807 { | |
1808 ICString *seg; | |
1809 wchar *wbuf, *wp; | |
1810 int len, wlen; | |
1811 extern int convJWStoCT(); | |
1812 | |
1813 seg = GetMode(w); | |
1814 if (seg == NULL) { | |
1815 *length = *nchars = 0; | |
1816 return -1; | |
1817 } | |
1818 | |
1819 wlen = seg->nchars; | |
1820 if (wlen <= 0) { | |
1821 *length = *nchars = 0; | |
1822 return -1; | |
1823 } | |
1824 | |
1825 /* | |
1826 * data $B$KF~$C$F$$$kJQ49%F%-%9%H$O(B null $B%?!<%_%M!<%H$5$l$F$$$J$$$+$b(B | |
1827 * $B$7$l$J$$$N$G!"$^$:%3%T!<$7$F(B null $B%?!<%_%M!<%H$9$k(B | |
1828 */ | |
1829 wbuf = (wchar *)XtMalloc((wlen + 1) * sizeof(wchar)); | |
1830 (void)bcopy(seg->data, (char *)wbuf, sizeof(wchar) * wlen); | |
1831 wbuf[wlen] = 0; | |
1832 | |
1833 /* | |
1834 * Canna $B%*%V%8%'%/%H$O(B COMPOUND_TEXT $B%(%s%3!<%G%#%s%0$7$+%5%]!<%H$7$J$$(B | |
1835 * COMPOUND_TEXT $B$KJQ49$9$k(B | |
1836 */ | |
1837 *encoding = XA_COMPOUND_TEXT(XtDisplayOfObject(w)); | |
1838 *format = 8; | |
1839 | |
1840 /* COMPOUND_TEXT $B$O(B \r $B$,Aw$l$J$$$N$G(B \n $B$KJQ49$7$F$*$/(B */ | |
1841 for (wp = wbuf; *wp != 0; wp++) { | |
1842 if (*wp == '\r') *wp = '\n'; | |
1843 } | |
1844 | |
1845 *length = len = convJWStoCT(wbuf, (unsigned char *)NULL, 0); | |
1846 *string = XtMalloc(len + 1); | |
1847 (void)convJWStoCT(wbuf, (unsigned char *)*string, 0); | |
1848 *nchars = seg->nchars; | |
1849 | |
1850 /* wbuf $B$r(B free $B$7$F$*$/(B */ | |
1851 XtFree((char *)wbuf); | |
1852 | |
1853 return 0; | |
1854 } |