comparison lib/OnConv.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 e55ccba56891 07a41a882b14
comparison
equal deleted inserted replaced
-1:000000000000 0:92745d501b9a
1 #ifndef lint
2 static char *rcsid = "$Id: OnConv.c,v 10.9 1999/05/19 08:52:42 ishisone Exp $";
3 #endif
4 /*
5 * Copyright (c) 1990 Software Research Associates, Inc.
6 * Copyright (c) 1999 Kazuki YASUMATSU
7 *
8 * Permission to use, copy, modify, and distribute this software and its
9 * documentation for any purpose and without fee is hereby granted, provided
10 * that the above copyright notice appear in all copies and that both that
11 * copyright notice and this permission notice appear in supporting
12 * documentation, and that the name of Software Research Associates not be
13 * used in advertising or publicity pertaining to distribution of the
14 * software without specific, written prior permission. Software Research
15 * Associates makes no representations about the suitability of this software
16 * for any purpose. It is provided "as is" without express or implied
17 * warranty.
18 *
19 * Author: Makoto Ishisone, Software Research Associates, Inc., Japan
20 * Author: Kazuki YASUMATSU (Kazuki.Yasumatsu@fujixerox.co.jp)
21 */
22
23
24 #include <X11/IntrinsicP.h>
25 #include <X11/StringDefs.h>
26 #include <X11/Xmu/Atoms.h>
27 #if XtSpecificationRelease > 4
28 #include <X11/Xfuncs.h>
29 #endif
30 #include "CachedAtom.h"
31 #include "AsyncErr.h"
32 #include "OnConvP.h"
33 #include "InputConv.h"
34 #include "ConvDisp.h"
35 #include "CandPanel.h"
36 #include "AuxPanel.h"
37 #include "ICLabel.h"
38
39 #define DEBUG_VAR debug_OnTheSpotConversion
40 #include "DebugPrint.h"
41
42 /*- resource table -*/
43 static XtResource resources[] = {
44 #define offset(field) XtOffset(OnTheSpotConversionWidget, onthespot.field)
45 { XtNpreeditStartCallback, XtCCallback, XtRCallback, sizeof(XtCallbackList),
46 offset(preeditstartcallback), XtRCallback, (XtPointer)NULL },
47 { XtNpreeditDoneCallback, XtCCallback, XtRCallback, sizeof(XtCallbackList),
48 offset(preeditdonecallback), XtRCallback, (XtPointer)NULL },
49 { XtNpreeditDrawCallback, XtCCallback, XtRCallback, sizeof(XtCallbackList),
50 offset(preeditdrawcallback), XtRCallback, (XtPointer)NULL },
51 { XtNpreeditCaretCallback, XtCCallback, XtRCallback, sizeof(XtCallbackList),
52 offset(preeditcaretcallback), XtRCallback, (XtPointer)NULL },
53 { XtNstatusStartCallback, XtCCallback, XtRCallback, sizeof(XtCallbackList),
54 offset(statusstartcallback), XtRCallback, (XtPointer)NULL },
55 { XtNstatusDoneCallback, XtCCallback, XtRCallback, sizeof(XtCallbackList),
56 offset(statusdonecallback), XtRCallback, (XtPointer)NULL },
57 { XtNstatusDrawCallback, XtCCallback, XtRCallback, sizeof(XtCallbackList),
58 offset(statusdrawcallback), XtRCallback, (XtPointer)NULL },
59 { XtNfeedbackAttributes, XtCFeedbackAttributes,
60 XtRFeedbackAttributes, sizeof(FeedbackAttributes),
61 offset(feedbackattrs), XtRString, (XtPointer)"U,,R,H" },
62 #undef offset
63 };
64
65 /*- default translations -*/
66 static char translations[] = "<Key>: to-inputobj()"; /* same as superclass's */
67
68 /*- declarations of local structures -*/
69 typedef struct {
70 int attrs_length;
71 int attrs_limit;
72 unsigned long *attrs_buffer;
73 } AttributeBuffer;
74
75 /*- declarations of static functions -*/
76 static void ClassInitialize();
77 static void Initialize();
78 static void Destroy();
79 static Boolean SetValues();
80
81 static void ConversionStartup();
82 static void ConversionFinish();
83 static void ChangeAttributes();
84 static void ChangeFocus();
85
86 static void StringToFeedbackAttrs();
87
88 static Widget CreateSelectionWidget();
89
90 static void UpdateText();
91 static void CommitText();
92 static void UpdateMode();
93 static void SelectionControl();
94
95 static void SelectionStart();
96 static void LocateSelectionPopup();
97 static void SelectionEnd();
98 static void SelectionSet();
99 static void SelectionGet();
100 static void SelectionMove();
101
102 static Widget CreateAuxWidget();
103 static void AuxControl();
104 static void AuxStart();
105 static void AuxEnd();
106 static void AuxChange();
107 static void LocateAuxPopup();
108
109 static void SelectionSelected();
110
111 static Boolean SafeGetWindowAttributes();
112 static void MoveShell();
113 static Window getToplevelWindow();
114 static void setTransientFor();
115 static void allocDisplaySegments();
116 static void freeDisplaySegment();
117 static void clearAllDisplaySegments();
118 static void copyString();
119 static void freeString();
120 static AttributeBuffer *allocAttributeBuffer();
121 static void destroyAttributeBuffer();
122 static void addAttributeBuffer();
123 static unsigned long attrToFeedback();
124 static void CBPreeditStart();
125 static void CBPreeditDone();
126 static void CBPreeditDraw();
127 static void CBPreeditCaret();
128 static void CBStatusStart();
129 static void CBStatusDone();
130 static void CBStatusDraw();
131
132 /*- composite-extension rec: for enabling non-widget children -*/
133 static CompositeClassExtensionRec CompositeExtension = {
134 /* next_extension */ NULL,
135 /* record_type */ NULLQUARK,
136 /* version */ XtCompositeExtensionVersion,
137 /* record_size */ sizeof(CompositeClassExtensionRec),
138 /* accept_objects */ True,
139 };
140
141 /*- onTheSpotConversionClass record -*/
142 OnTheSpotConversionClassRec onTheSpotConversionClassRec = {
143 { /* core fields */
144 /* superclass */ (WidgetClass)&conversionControlClassRec,
145 /* class_name */ "OnTheSpotConversion",
146 /* widget_size */ sizeof(OnTheSpotConversionRec),
147 /* class_initialize */ ClassInitialize,
148 /* class_part_initialize */ NULL,
149 /* class_inited */ FALSE,
150 /* initialize */ Initialize,
151 /* initialize_hook */ NULL,
152 /* realize */ XtInheritRealize,
153 /* actions */ NULL,
154 /* num_actions */ 0,
155 /* resources */ resources,
156 /* num_resources */ XtNumber(resources),
157 /* xrm_class */ NULLQUARK,
158 /* compress_motion */ TRUE,
159 /* compress_exposure */ TRUE,
160 /* compress_enterleave */ TRUE,
161 /* visible_interest */ FALSE,
162 /* destroy */ Destroy,
163 /* resize */ XtInheritResize,
164 /* expose */ NULL,
165 /* set_values */ SetValues,
166 /* set_values_hook */ NULL,
167 /* set_values_almost */ XtInheritSetValuesAlmost,
168 /* get_values_hook */ NULL,
169 /* accept_focus */ NULL,
170 /* version */ XtVersion,
171 /* callback_private */ NULL,
172 /* tm_table */ translations,
173 /* query_geometry */ XtInheritQueryGeometry,
174 /* display_accelerator */ XtInheritDisplayAccelerator,
175 /* extension */ NULL
176 },
177 { /* composite fields */
178 /* geometry_manager */ XtInheritGeometryManager,
179 /* change_managed */ XtInheritChangeManaged,
180 /* insert_child */ XtInheritInsertChild,
181 /* delete_child */ XtInheritDeleteChild,
182 /* extension */ (XtPointer)&CompositeExtension,
183 },
184 { /* shell fields */
185 /* extension */ NULL
186 },
187 { /* wm_shell fields */
188 /* extension */ NULL
189 },
190 { /* vendor_shell fields */
191 /* extension */ NULL
192 },
193 { /* transient_shell fields */
194 /* extension */ NULL
195 },
196 { /* conversionControl fields */
197 /* Startup */ ConversionStartup,
198 /* Finish */ ConversionFinish,
199 /* ChangeAttributes */ ChangeAttributes,
200 /* ChangeFocus */ ChangeFocus,
201 /* TextChange */ UpdateText,
202 /* Fix */ CommitText,
203 /* ModeChange */ UpdateMode,
204 /* SelectionControl */ SelectionControl,
205 /* AuxControl */ AuxControl,
206 },
207 { /* onTheSpotConversion fields */
208 /* empty */ 0
209 },
210 };
211
212 WidgetClass onTheSpotConversionWidgetClass = (WidgetClass)&onTheSpotConversionClassRec;
213
214 /*
215 *+ Core class method
216 */
217
218 /*- ClassInitialize: class initializer -*/
219 /* ARGSUSED */
220 static void
221 ClassInitialize()
222 {
223 /* add String -> FeedbackAttributes converter */
224 XtAddConverter(XtRString, XtRFeedbackAttributes, StringToFeedbackAttrs,
225 (XtConvertArgList)NULL, (Cardinal)0);
226 }
227
228 /*- Initialize: initalize method -*/
229 /* ARGSUSED */
230 static void
231 Initialize(req, new, args, num_args)
232 Widget req;
233 Widget new;
234 ArgList args;
235 Cardinal *num_args;
236 {
237 OnTheSpotConversionWidget ocw = (OnTheSpotConversionWidget)new;
238
239 (void)CreateSelectionWidget(ocw);
240 (void)CreateAuxWidget(ocw);
241
242 ocw->onthespot.dispsegments = NULL;
243 ocw->onthespot.numsegments = 0;
244 ocw->onthespot.dispsegmentsize = 0;
245 ocw->onthespot.candlist = NULL;
246 ocw->onthespot.numcands = 0;
247 ocw->onthespot.selectionpoppedup = False;
248 ocw->onthespot.auxpoppedup = False;
249 ocw->onthespot.lastcaret = 0;
250 ocw->onthespot.fixnotify = False;
251 }
252
253 /*- Destroy: destroy method -*/
254 static void
255 Destroy(w)
256 Widget w;
257 {
258 OnTheSpotConversionWidget ocw = (OnTheSpotConversionWidget)w;
259
260 /* $B%G%#%9%W%l%$%;%0%a%s%H$NNN0h$r2rJ|(B */
261 if (ocw->onthespot.dispsegments) {
262 DisplaySegment *dsp = ocw->onthespot.dispsegments;
263 int i;
264
265 for (i = 0; i < ocw->onthespot.numsegments; i++) {
266 freeString(&dsp[i].seg);
267 }
268 XtFree((char *)dsp);
269 }
270 }
271
272 /*- SetValues: setvalues method -*/
273 /* ARGSUSED */
274 static Boolean
275 SetValues(cur, req, new, args, num_args)
276 Widget cur;
277 Widget req;
278 Widget new;
279 ArgList args;
280 Cardinal *num_args;
281 {
282 /* OnTheSpotConversionWidget ocw = (OnTheSpotConversionWidget)new; */
283 return False;
284 }
285
286 /*
287 *+ ConversionControl class method
288 */
289
290 /*- ConversionStartup: class specific conversion startup -*/
291 static void
292 ConversionStartup(widget, valuemask, value)
293 Widget widget;
294 unsigned long valuemask;
295 ConversionAttributes *value;
296 {
297 OnTheSpotConversionWidget ocw = (OnTheSpotConversionWidget)widget;
298 Widget inputobj = ocw->ccontrol.inputobj;
299 Window toplevel;
300
301 TRACE(("OnTheSpot:ConversionStartup()\n"));
302
303 /* $BFbIt$N%P%C%U%!$r%/%j%"$9$k(B */
304 clearAllDisplaySegments(ocw);
305
306 /* WM_TRANSIENT_FOR $B%W%m%Q%F%#$r@5$7$/%;%C%H$9$k(B */
307 toplevel = getToplevelWindow(XtDisplay(widget),
308 ocw->ccontrol.clientwindow);
309 setTransientFor(ocw->onthespot.selectionshell, toplevel);
310 setTransientFor(ocw->onthespot.auxshell, toplevel);
311
312 /*
313 * OnTheSpotConvesion $B$N(B widget $B<+BN$O%]%C%W%"%C%W$5$;$J$$$,!"(B
314 * $B%P%C%/%(%s%I%?%$%W$N;~$K$O%/%i%$%"%s%H$,$3$N(B widget $B$N(B
315 * $B%&%#%s%I%&$KBP$7$F%$%Y%s%H$rAw$k$N$G(B Realize $B$@$1$7$F$*$/(B
316 */
317 if (!XtIsRealized(widget)) {
318 Arg args[2];
319
320 XtSetArg(args[0], XtNwidth, 1);
321 XtSetArg(args[1], XtNheight, 1);
322 XtSetValues(widget, args, 2);
323 XtRealizeWidget(widget);
324 }
325
326 ocw->onthespot.lastcaret = 0;
327 ocw->onthespot.fixnotify = False;
328
329 /* $B%9%F!<%?%9$r99?7$9$k(B */
330 UpdateMode(widget);
331
332 /* $B%W%l%(%G%#%C%H$r3+;O$9$k(B */
333 CBPreeditStart(widget);
334 }
335
336 /*- ConversionFinish: class specific conversion finish -*/
337 /* ARGSUSED */
338 static void
339 ConversionFinish(w)
340 Widget w;
341 {
342 OnTheSpotConversionWidget ocw = (OnTheSpotConversionWidget)w;
343 Atom encoding = XA_COMPOUND_TEXT(XtDisplayOfObject(w));
344 int format = 8;
345
346 if (!ocw->onthespot.fixnotify) {
347 /* $B3NDj$7$F$$$J$$(B */
348 DisplaySegment *dseg = ocw->onthespot.dispsegments;
349 int i, len = 0;
350 for (i = 0; i < ocw->onthespot.numsegments; i++, dseg++) {
351 len += dseg->seg.nchars;
352 }
353 if (len > 0) {
354 /* $B%W%l%(%G%#%C%H%P%C%U%!$N>C5n(B */
355 unsigned long attr = 0;
356 CBPreeditDraw(ocw, 0, 0, len, encoding, format, 0, (XPointer)"",
357 0, &attr);
358 }
359 }
360
361 /* $B%W%l%(%G%#%C%H$r=*N;$9$k(B */
362 CBPreeditDone(w);
363
364 /* $B%9%F!<%?%9$r99?7(B($B=i4|2=(B)$B$9$k(B */
365 CBStatusDraw(ocw, encoding, format, 0, (XPointer)"", 0);
366
367 if (ocw->onthespot.selectionpoppedup) {
368 XtPopdown(ocw->onthespot.selectionshell);
369 ocw->onthespot.selectionpoppedup = False;
370 }
371 if (ocw->onthespot.auxpoppedup) {
372 XtPopdown(ocw->onthespot.auxshell);
373 ocw->onthespot.auxpoppedup = False;
374 }
375 }
376
377 /*- ChangeAttributes: class specific conversion attribute change routine -*/
378 /* ARGSUSED */
379 static void
380 ChangeAttributes(w, valuemask, value)
381 Widget w;
382 unsigned long valuemask;
383 ConversionAttributes *value;
384 {
385 /* do nothing */
386 }
387
388 /*- ChangeFocus: class specific conversion attribute change routine -*/
389 static void
390 ChangeFocus(w, set)
391 Widget w;
392 int set;
393 {
394 if (set) {
395 UpdateMode(w);
396 } else {
397 #if 0
398 /* $B%U%)!<%+%9$r<:$C$?>l9g$K$O2?$b$7$J$$(B */
399 OnTheSpotConversionWidget ocw = (OnTheSpotConversionWidget)w;
400 Atom encoding = XA_COMPOUND_TEXT(XtDisplayOfObject(w));
401 int format = 8;
402
403 CBStatusDraw(ocw, encoding, format, 0, (XPointer)"", 0);
404 #endif
405 }
406 }
407
408 /*
409 *+ resource converter
410 */
411
412 /*- StringToFeedbackAttrs: string to feedback attiributes converter -*/
413 static void
414 StringToFeedbackAttrs(args, num_args, from, to)
415 XrmValue *args;
416 Cardinal *num_args;
417 XrmValue *from;
418 XrmValue *to;
419 {
420 char *s = (char *)from->addr;
421 int idx;
422 int invalid = 0;
423 static FeedbackAttributes fba;
424
425 for (idx = 0; idx < 4; idx++) fba.feedbacks[idx] = 0;
426
427 for (idx = 0; idx < 4; idx++) {
428 int c;
429 unsigned long fb = 0;
430
431 while ((c = *s++) != ',' && c != '\0') {
432 switch (c) {
433 case 'R': case 'r': fb |= XIMReverse; break;
434 case 'U': case 'u': fb |= XIMUnderline; break;
435 case 'H': case 'h': fb |= XIMHighlight; break;
436 case 'P': case 'p': fb |= XIMPrimary; break;
437 case 'S': case 's': fb |= XIMSecondary; break;
438 case 'T': case 't': fb |= XIMTertiary; break;
439 case ' ': case '\t':
440 break;
441 default:
442 invalid++;
443 break;
444 }
445 }
446 fba.feedbacks[idx] = fb;
447 if (c == '\0') break;
448 }
449
450 if (invalid) {
451 XtStringConversionWarning((char *)from->addr, XtRFeedbackAttributes);
452 }
453 to->size = sizeof(fba);
454 to->addr = (caddr_t)&fba;
455 }
456
457 /*
458 *+ sub-widget creation
459 */
460
461 /*- CreateSelectionWidget: create selection widget for selecting candidates -*/
462 static Widget
463 CreateSelectionWidget(ocw)
464 OnTheSpotConversionWidget ocw;
465 {
466 Widget shell, sel;
467
468 /* set width/height so that XtRealizeWidget() doesn't cause error */
469 shell = XtVaCreatePopupShell("selectionShell",
470 transientShellWidgetClass,
471 (Widget)ocw,
472 XtNwidth, 1,
473 XtNheight, 1,
474 NULL);
475 ocw->onthespot.selectionshell = shell;
476
477 sel = XtCreateManagedWidget("selection", candidatePanelWidgetClass,
478 shell, NULL, 0);
479 (void)XtCreateWidget("display", ocw->ccontrol.displayobjclass, sel,
480 NULL, 0);
481 XtAddCallback(sel, XtNcallback, SelectionSelected, (XtPointer)ocw);
482 XtInstallAccelerators(sel, (Widget)ocw);
483
484 ocw->onthespot.selectionwidget = sel;
485
486 return shell;
487 }
488
489 /*- CreateAuxWidget: create aux widget for display auxiliary data -*/
490 static Widget
491 CreateAuxWidget(ocw)
492 OnTheSpotConversionWidget ocw;
493 {
494 Widget shell, sel;
495
496 /* set width/height so that XtRealizeWidget() doesn't cause error */
497 shell = XtVaCreatePopupShell("auxShell",
498 transientShellWidgetClass,
499 (Widget)ocw,
500 XtNwidth, 1,
501 XtNheight, 1,
502 XtNallowShellResize, True,
503 NULL);
504 ocw->onthespot.auxshell = shell;
505
506 sel = XtCreateManagedWidget("aux", auxPanelWidgetClass,
507 shell, NULL, 0);
508 (void)XtCreateWidget("display", ocw->ccontrol.displayobjclass, sel,
509 NULL, 0);
510 XtAddCallback(sel, XtNcallback, SelectionSelected, (XtPointer)ocw);
511 XtInstallAccelerators(sel, (Widget)ocw);
512
513 ocw->onthespot.auxwidget = sel;
514
515 return shell;
516 }
517
518 /*
519 *+ inputobject callback
520 */
521
522 /*- UpdateText: update text -*/
523 static void
524 UpdateText(w)
525 Widget w;
526 {
527 OnTheSpotConversionWidget ocw = (OnTheSpotConversionWidget)w;
528 Widget inputobj = ocw->ccontrol.inputobj;
529 int nnew = ICNumSegments(inputobj);
530 int nold = ocw->onthespot.numsegments;
531 FeedbackAttributes *fba = &ocw->onthespot.feedbackattrs;
532 Cardinal cseg, caret;
533 ICString *newseg;
534 DisplaySegment *dseg;
535 Boolean changed;
536 int chgseg, chgoffset;
537 int oldlen;
538 AttributeBuffer *buffer;
539 int i;
540 int diff;
541 Cardinal nsame;
542
543 TRACE(("OnTheSpotConversion:UpdateText() nnew=%d\n", nnew));
544
545 ocw->onthespot.fixnotify = False;
546
547 if (!ICCursorPos(inputobj, &cseg, &caret)) {
548 cseg = nnew;
549 caret = 0;
550 }
551
552 allocDisplaySegments(ocw, nnew);
553
554 changed = False;
555 chgseg = chgoffset = 0;
556 oldlen = 0;
557 buffer = allocAttributeBuffer();
558 for (i = 0, dseg = ocw->onthespot.dispsegments; i < nnew; i++, dseg++) {
559 newseg = ICGetSegment(inputobj, i);
560 if (i < cseg) {
561 caret += newseg->nchars;
562 }
563 if (i >= nold) {
564 copyString(newseg, &dseg->seg);
565 addAttributeBuffer(buffer, inputobj, newseg, 0, fba);
566 if (!changed) {
567 chgseg = i;
568 chgoffset = 0;
569 changed = True;
570 }
571 } else {
572 oldlen += dseg->seg.nchars;
573 diff = ICCompareSegment(inputobj, newseg, &dseg->seg, &nsame);
574 switch (diff) {
575 case ICSame:
576 if (changed) {
577 addAttributeBuffer(buffer, inputobj, newseg, 0, fba);
578 }
579 break;
580 case ICAttrChanged:
581 dseg->seg.attr = newseg->attr;
582 addAttributeBuffer(buffer, inputobj, newseg, 0, fba);
583 if (!changed) {
584 chgseg = i;
585 chgoffset = 0;
586 changed = True;
587 }
588 break;
589 case ICStringChanged:
590 freeString(&dseg->seg);
591 copyString(newseg, &dseg->seg);
592 if (!changed) {
593 addAttributeBuffer(buffer, inputobj, newseg, nsame, fba);
594 chgseg = i;
595 chgoffset = nsame;
596 changed = True;
597 }
598 else {
599 addAttributeBuffer(buffer, inputobj, newseg, 0, fba);
600 }
601 break;
602 default: /* ICAttrChanged | ICStringChanged */
603 freeString(&dseg->seg);
604 copyString(newseg, &dseg->seg);
605 addAttributeBuffer(buffer, inputobj, newseg, 0, fba);
606 if (!changed) {
607 chgseg = i;
608 chgoffset = 0;
609 changed = True;
610 }
611 break;
612 }
613 }
614 }
615
616 for (; i < nold; i++, dseg++) {
617 oldlen += dseg->seg.nchars;
618 if (!changed) {
619 chgseg = i;
620 chgoffset = 0;
621 changed = True;
622 }
623 freeDisplaySegment(dseg);
624 }
625
626 ocw->onthespot.numsegments = nnew;
627
628 if (!changed) {
629 if (ocw->onthespot.lastcaret != caret) {
630 CBPreeditCaret(ocw, caret);
631 }
632 }
633 else { /* changed */
634 Atom encoding = ocw->ccontrol.textencoding;
635 int format;
636 int length;
637 XtPointer string;
638
639 if (ICGetPreeditString(inputobj, chgseg, chgoffset, &encoding, &format,
640 &length, &string) == 0) {
641
642 dseg = ocw->onthespot.dispsegments;
643 for (i = 0; i < chgseg; i++, dseg++) {
644 chgoffset += dseg->seg.nchars;
645 }
646 CBPreeditDraw(ocw, caret, chgoffset, oldlen - chgoffset,
647 encoding, format, length, string,
648 buffer->attrs_length, buffer->attrs_buffer);
649
650 /* string $B$r(B free $B$7$F$*$/(B */
651 XtFree((char *)string);
652 }
653 }
654
655 ocw->onthespot.lastcaret = caret;
656
657 /* buffer $B$r(B destroy $B$7$F$*$/(B */
658 destroyAttributeBuffer(buffer);
659 }
660
661 /*- CommitText: commit text -*/
662 static void
663 CommitText(w, arg)
664 Widget w;
665 CCTextCallbackArg *arg;
666 {
667 OnTheSpotConversionWidget ocw = (OnTheSpotConversionWidget)w;
668 DisplaySegment *dseg;
669 int i, len;
670
671 dseg = ocw->onthespot.dispsegments;
672 len = 0;
673 for (i = 0; i < ocw->onthespot.numsegments; i++, dseg++) {
674 len += dseg->seg.nchars;
675 }
676 if (len > 0) {
677 /* $B%W%l%(%G%#%C%H%P%C%U%!$N>C5n(B */
678 Atom encoding = XA_COMPOUND_TEXT(XtDisplayOfObject(w));
679 int format = 8;
680 unsigned long attr = 0;
681 CBPreeditDraw(ocw, 0, 0, len, encoding, format, 0, (XPointer)"",
682 0, &attr);
683 }
684 /* $BFbIt$N%P%C%U%!$r%/%j%"$9$k(B */
685 clearAllDisplaySegments(ocw);
686 ocw->onthespot.lastcaret = 0;
687
688 XtCallCallbackList((Widget)ocw, ocw->ccontrol.textcallback,
689 (XtPointer)arg);
690
691 ocw->onthespot.fixnotify = True;
692 }
693
694 /*- UpdateMode: update mode -*/
695 static void
696 UpdateMode(w)
697 Widget w;
698 {
699 OnTheSpotConversionWidget ocw = (OnTheSpotConversionWidget)w;
700 Widget inputobj = ocw->ccontrol.inputobj;
701 Atom encoding = ocw->ccontrol.textencoding;
702 int format;
703 int length;
704 XtPointer string;
705 int nchars;
706
707 TRACE(("OnTheSpotConversion:UpdateMode()\n"));
708
709 if (ICGetStatusString(inputobj, &encoding, &format, &length, &string,
710 &nchars) == -1)
711 return;
712
713 CBStatusDraw(ocw, encoding, format, length, string, nchars);
714
715 /* string $B$r(B free $B$7$F$*$/(B */
716 XtFree((char *)string);
717 }
718
719 /*- SelectionControl: selection control -*/
720 static void
721 SelectionControl(w, arg)
722 Widget w;
723 ICSelectionControlArg *arg;
724 {
725 OnTheSpotConversionWidget ocw = (OnTheSpotConversionWidget)w;
726 String params[1];
727 Cardinal num_params;
728
729 switch (arg->command) {
730 case ICSelectionStart:
731 SelectionStart(ocw, arg->u.selection_kind);
732 break;
733 case ICSelectionEnd:
734 SelectionEnd(ocw, &arg->u.current_item);
735 break;
736 case ICSelectionSet:
737 SelectionSet(ocw, arg->u.current_item);
738 break;
739 case ICSelectionMove:
740 SelectionMove(ocw, arg->u.dir);
741 break;
742 case ICSelectionGet:
743 SelectionGet(ocw, &arg->u.current_item);
744 break;
745 default:
746 params[0] = XtClass(w)->core_class.class_name;
747 num_params = 1;
748 XtAppWarningMsg(XtWidgetToApplicationContext(w),
749 "parameterError", "SelectionControl", "WidgetError",
750 "%s: unknown selection control command",
751 params, &num_params);
752 break;
753 }
754 }
755
756 /*- SelectionStart: selection startup -*/
757 /* ARGSUSED */
758 static void
759 SelectionStart(ocw, kind)
760 OnTheSpotConversionWidget ocw;
761 int kind;
762 {
763 Cardinal ncand;
764
765 TRACE(("OnTheSpotConversion:SelectionStart()\n"));
766 if (ocw->onthespot.selectionpoppedup) {
767 TRACE(("\tselection already started -- ignored\n"));
768 return;
769 }
770
771 ocw->onthespot.candlist = ICGetItemList(ocw->ccontrol.inputobj, &ncand);
772 ocw->onthespot.numcands = ncand;
773
774 TRACE(("\tnumcands=%d\n", ocw->onthespot.numcands));
775 CPanelSetList(ocw->onthespot.selectionwidget,
776 ocw->onthespot.candlist,
777 ocw->onthespot.numcands, 0, True);
778
779 LocateSelectionPopup(ocw);
780 XtPopup(ocw->onthespot.selectionshell, XtGrabNone);
781 ocw->onthespot.selectionpoppedup = True;
782 }
783
784 /*- LocateSelectionPopup: put selection popup at an appropriate position -*/
785 static void
786 LocateSelectionPopup(ocw)
787 OnTheSpotConversionWidget ocw;
788 {
789 Position x, y;
790 int clx, cly;
791 Dimension dpyWidth, dpyHeight;
792 Widget panel = ocw->onthespot.selectionwidget;
793 Widget shell = ocw->onthespot.selectionshell;
794 Window junk;
795 int barheight = ocw->ccontrol.titlebarheight;
796
797 (void)XTranslateCoordinates(XtDisplay(ocw),
798 ocw->ccontrol.clientwindow,
799 RootWindowOfScreen(XtScreen(ocw)),
800 0, 0, &clx, &cly, &junk);
801
802 (void)SafeGetWindowAttributes(XtDisplay(ocw), ocw->ccontrol.clientwindow,
803 &(ocw->ccontrol.client_attr));
804
805 x = clx;
806 y = cly + ocw->ccontrol.client_attr.height;
807
808 dpyWidth = WidthOfScreen(XtScreen(shell));
809 dpyHeight = HeightOfScreen(XtScreen(shell));
810
811 if (x + panel->core.width > (int)dpyWidth) x = dpyWidth - panel->core.width;
812 if (x < 0) x = 0;
813 #if 0
814 if (y + panel->core.height + barheight > (int)dpyHeight) {
815 y = cly - panel->core.height - 8 - barheight - 20; /* XXX */
816 if (y < 0) y = dpyHeight - panel->core.height - barheight;
817 }
818 #endif
819 if (y + panel->core.height + barheight > (int)dpyHeight)
820 y = dpyHeight - panel->core.height - 8 - barheight - 20; /* XXX */
821 if (y < 0) y = 0;
822 MoveShell(shell, x, y);
823 }
824
825 /*- SelectionEnd: selection finish -*/
826 static void
827 SelectionEnd(ocw, current)
828 OnTheSpotConversionWidget ocw;
829 int *current;
830 {
831 TRACE(("OnTheSpotConversion:SelectionEnd()\n"));
832
833 if (!ocw->onthespot.selectionpoppedup) { /* for safe */
834 TRACE(("\tnot in selection mode -- ignored\n"));
835 return;
836 }
837
838 XtVaGetValues(ocw->onthespot.selectionwidget,
839 XtNcurrentItem, current,
840 NULL);
841
842 XtPopdown(ocw->onthespot.selectionshell);
843
844 ocw->onthespot.selectionpoppedup = False;
845 }
846
847 /*- SelectionSet: set current selection item -*/
848 static void
849 SelectionSet(ocw, current)
850 OnTheSpotConversionWidget ocw;
851 int current;
852 {
853 TRACE(("OnTheSpotConversion:SelectionSet()\n"));
854
855 if (!ocw->onthespot.selectionpoppedup) { /* for safe */
856 TRACE(("\tnot in selection mode -- ignored\n"));
857 return;
858 }
859
860 XtVaSetValues(ocw->onthespot.selectionwidget,
861 XtNcurrentItem, current,
862 NULL);
863 }
864
865 /*- SelectionGet: get current selection item -*/
866 static void
867 SelectionGet(ocw, current)
868 OnTheSpotConversionWidget ocw;
869 int *current;
870 {
871 TRACE(("OnTheSpotConversion:SelectionGet()\n"));
872
873 if (!ocw->onthespot.selectionpoppedup) { /* for safe */
874 TRACE(("\tnot in selection mode -- ignored\n"));
875 return;
876 }
877
878 XtVaGetValues(ocw->onthespot.selectionwidget,
879 XtNcurrentItem, current,
880 NULL);
881 }
882
883 /*- SelectionMove: move crrent selection to specified direction -*/
884 static void
885 SelectionMove(ocw, dir)
886 OnTheSpotConversionWidget ocw;
887 int dir;
888 {
889 TRACE(("OnTheSpotConversion:SelectionMove()\n"));
890
891 if (!ocw->onthespot.selectionpoppedup) { /* for safe */
892 TRACE(("\tnot in selection mode -- ignored\n"));
893 return;
894 }
895
896 CPanelMoveCurrent(ocw->onthespot.selectionwidget, dir);
897 }
898
899 /*
900 * Aux Callback
901 */
902
903 static void
904 AuxControl(w, arg)
905 Widget w;
906 ICAuxControlArg *arg;
907 {
908 OnTheSpotConversionWidget ocw = (OnTheSpotConversionWidget)w;
909 String params[1];
910 Cardinal num_params;
911
912 switch (arg->command) {
913 case ICAuxStart:
914 AuxStart(ocw);
915 break;
916 case ICAuxEnd:
917 AuxEnd(ocw);
918 break;
919 case ICAuxChange:
920 AuxChange(ocw);
921 break;
922 default:
923 params[0] = XtClass(w)->core_class.class_name;
924 num_params = 1;
925 XtAppWarningMsg(XtWidgetToApplicationContext(w),
926 "parameterError", "AuxControl", "WidgetError",
927 "%s: unknown aux control command",
928 params, &num_params);
929 break;
930 }
931 }
932
933 /* ARGSUSED */
934 static void
935 AuxStart(ocw)
936 OnTheSpotConversionWidget ocw;
937 {
938 ICString *auxstr;
939 Cardinal ncand, curseg, cursorpos;
940
941 if (ocw->onthespot.auxpoppedup) return;
942
943 /* $B%F%-%9%H%3!<%k%P%C%/$N;~$N$h$&$J=hM}$r$9$k(B
944 $B$N$O(B AuxPanel.c $B$K$^$+$;$h$&(B */
945
946 auxstr = ICGetAuxSegments(ocw->ccontrol.inputobj,
947 &ncand, &curseg, &cursorpos);
948
949 APanelStart(ocw->onthespot.auxwidget, auxstr, ncand, curseg, cursorpos);
950
951 /* $B%]%C%W%"%C%W$9$k>l=j$r7h$a$k(B */
952 LocateAuxPopup(ocw);
953
954 XtPopup(ocw->onthespot.auxshell, XtGrabNone);
955 ocw->onthespot.auxpoppedup = True;
956 }
957
958 /* ARGSUSED */
959 static void
960 AuxEnd(ocw)
961 OnTheSpotConversionWidget ocw;
962 {
963 if (!ocw->onthespot.auxpoppedup) return; /* for safe */
964
965 /* APanelEnd(ocw->onthespot.auxwidget); */
966
967 XtPopdown(ocw->onthespot.auxshell);
968
969 ocw->onthespot.auxpoppedup = False;
970 }
971
972 /* ARGSUSED */
973 static void
974 AuxChange(ocw)
975 OnTheSpotConversionWidget ocw;
976 {
977 Cardinal ncand, curseg, cursorpos;
978 ICString *auxstr;
979
980 if (!ocw->onthespot.auxpoppedup) return; /* for safe */
981
982 auxstr = ICGetAuxSegments(ocw->ccontrol.inputobj,
983 &ncand, &curseg, &cursorpos);
984
985 APanelChange(ocw->onthespot.auxwidget, auxstr, ncand, curseg, cursorpos);
986 }
987
988 /*- LocateAuxPopup: put aux popup at an appropriate position -*/
989 static void
990 LocateAuxPopup(ocw)
991 OnTheSpotConversionWidget ocw;
992 {
993 Position x, y;
994 int clx, cly;
995 Dimension dpyWidth, dpyHeight;
996 Widget panel = ocw->onthespot.auxwidget;
997 Widget shell = ocw->onthespot.auxshell;
998 Window junk;
999 int barheight = ocw->ccontrol.titlebarheight;
1000
1001 (void)XTranslateCoordinates(XtDisplay(ocw),
1002 ocw->ccontrol.clientwindow,
1003 RootWindowOfScreen(XtScreen(ocw)),
1004 0, 0, &clx, &cly, &junk);
1005
1006 (void)SafeGetWindowAttributes(XtDisplay(ocw), ocw->ccontrol.clientwindow,
1007 &(ocw->ccontrol.client_attr));
1008
1009 x = clx;
1010 y = cly + ocw->ccontrol.client_attr.height;
1011
1012 dpyWidth = WidthOfScreen(XtScreen(shell));
1013 dpyHeight = HeightOfScreen(XtScreen(shell));
1014
1015 if (x + panel->core.width > (int)dpyWidth) x = dpyWidth - panel->core.width;
1016 if (x < 0) x = 0;
1017 #if 0
1018 if (y + panel->core.height + barheight > (int)dpyHeight) {
1019 y = cly - panel->core.height - 8 - barheight - 20; /* XXX */
1020 if (y < 0) y = dpyHeight - panel->core.height - barheight;
1021 }
1022 #endif
1023 if (y + panel->core.height + barheight > (int)dpyHeight)
1024 y = dpyHeight - panel->core.height - 8 - barheight - 20; /* XXX */
1025 if (y < 0) y = 0;
1026 MoveShell(shell, x, y);
1027 }
1028
1029 /*
1030 *+ Selection Widget callback
1031 */
1032
1033 /*- SelectionSelected: selection selected callback -*/
1034 /* ARGSUSED */
1035 static void
1036 SelectionSelected(w, client_data, call_data)
1037 Widget w;
1038 XtPointer client_data;
1039 XtPointer call_data;
1040 {
1041 OnTheSpotConversionWidget ocw = (OnTheSpotConversionWidget)client_data;
1042 int current = (int)call_data;
1043
1044 TRACE(("OnTheSpotConversion:SelectionSelected()\n"));
1045 XtPopdown(ocw->onthespot.selectionshell);
1046 ocw->onthespot.selectionpoppedup = False;
1047 ICSelectItem(ocw->ccontrol.inputobj, current);
1048 }
1049
1050 /*
1051 *+ miscelaneous functions
1052 */
1053
1054 /*- SafeGetWindowAttributes: get window attributes -*/
1055 static Boolean
1056 SafeGetWindowAttributes(dpy, w, attr)
1057 Display *dpy;
1058 Window w;
1059 XWindowAttributes *attr;
1060 {
1061 XAEHandle h;
1062 unsigned long errbits = 0;
1063
1064 h = XAESetRecordErrors(dpy, &errbits);
1065 (void)XGetWindowAttributes(dpy, w, attr);
1066 XAEUnset(h);
1067
1068 return (errbits == 0);
1069 }
1070
1071 /*- MoveShell: move shell widget -*/
1072 static void
1073 MoveShell(w, x, y)
1074 Widget w;
1075 Position x;
1076 Position y;
1077 {
1078 XtWidgetGeometry req;
1079
1080 /*
1081 * calling XtMoveWidget() is NOT enough to move shell widgets.
1082 * we must use XtMakeGeometryRequest() or XtSetValues() to
1083 * invoke root-geometry-manager which modifies the size hint
1084 * appropriately.
1085 */
1086 req.request_mode = CWX | CWY;
1087 req.x = x;
1088 req.y = y;
1089 (void)XtMakeGeometryRequest(w, &req, (XtWidgetGeometry *)NULL);
1090 }
1091
1092 /*- getToplevelWindow: get top-level window of a given window -*/
1093 static Window
1094 getToplevelWindow(dpy, win)
1095 Display *dpy;
1096 Window win;
1097 {
1098 Atom wm_state;
1099 Atom type;
1100 int format;
1101 unsigned long nitems, bytesafter;
1102 unsigned char *data;
1103 Window root, parent;
1104 Window *children;
1105 unsigned int nchildren;
1106
1107 /*
1108 * find toplevel window which has WM_STATE property or if no exists,
1109 * direct subwindow of the root window. (ie I assume that if a
1110 * window manager is running, that is a ICCCM compliant one)
1111 */
1112 wm_state = CachedInternAtom(dpy, "WM_STATE", True);
1113 for (;;) {
1114 type = None;
1115 if (wm_state != None) {
1116 data = NULL;
1117 XGetWindowProperty(dpy, win, wm_state, 0L, 0L, False,
1118 AnyPropertyType, &type, &format,
1119 &nitems, &bytesafter, &data);
1120 if (data != NULL) XtFree((char *)data);
1121 if (type != None) break;
1122 }
1123 if (!XQueryTree(dpy, win, &root, &parent, &children, &nchildren)) break;
1124 if (nchildren > 0) XtFree((char *)children);
1125 if (root == parent) break;
1126 win = parent;
1127 }
1128 return win;
1129 }
1130
1131 /*- setTransientFor: set WM_TRANSIENT_FOR property to specified widget -*/
1132 static void
1133 setTransientFor(w, win)
1134 Widget w;
1135 Window win;
1136 {
1137 if (!XtIsRealized(w)) XtRealizeWidget(w);
1138 XSetTransientForHint(XtDisplay(w), XtWindow(w), win);
1139 }
1140
1141 /*- allocDisplaySegments: prepare specified number of display segments -*/
1142 static void
1143 allocDisplaySegments(ocw, n)
1144 OnTheSpotConversionWidget ocw;
1145 Cardinal n;
1146 {
1147 if (ocw->onthespot.dispsegmentsize > n) return;
1148 n = ((n + 3) / 4) * 4 ;
1149 if (ocw->onthespot.dispsegments == NULL) {
1150 ocw->onthespot.dispsegments = (DisplaySegment *)XtMalloc(n * sizeof(DisplaySegment));
1151 } else {
1152 ocw->onthespot.dispsegments = (DisplaySegment *)XtRealloc((char *)ocw->onthespot.dispsegments, n * sizeof(DisplaySegment));
1153 }
1154 ocw->onthespot.dispsegmentsize = n;
1155 }
1156
1157 /*- freeDisplaySegment: free display segment's contents -*/
1158 static void
1159 freeDisplaySegment(dsp)
1160 DisplaySegment *dsp;
1161 {
1162 freeString(&dsp->seg);
1163 }
1164
1165 /*- clearAllDisplaySegments: clear all display segment's -*/
1166 static void
1167 clearAllDisplaySegments(ocw)
1168 OnTheSpotConversionWidget ocw;
1169 {
1170 DisplaySegment *dsp = ocw->onthespot.dispsegments;
1171 int i;
1172
1173 for (i = 0; i < ocw->onthespot.numsegments; i++) {
1174 freeDisplaySegment(dsp++);
1175 }
1176 ocw->onthespot.numsegments = 0;
1177 }
1178
1179 /*- copyString: copy ICString -*/
1180 static void
1181 copyString(from, to)
1182 ICString *from;
1183 ICString *to;
1184 {
1185 *to = *from;
1186 to->data = XtMalloc(to->nbytes);
1187 (void)bcopy(from->data, to->data, to->nbytes);
1188 }
1189
1190 /*- freeString: free ICString -*/
1191 static void
1192 freeString(seg)
1193 ICString *seg;
1194 {
1195 XtFree(seg->data);
1196 seg->data = NULL;
1197 seg->nbytes = 0;
1198 }
1199
1200 /*- allocAttributeBuffer: allocate attribute buffer -*/
1201 static AttributeBuffer *
1202 allocAttributeBuffer()
1203 {
1204 AttributeBuffer *buffer;
1205
1206 buffer = (AttributeBuffer *)XtMalloc(sizeof(AttributeBuffer));
1207 buffer->attrs_length = 0;
1208 buffer->attrs_limit = 64;
1209 buffer->attrs_buffer = (unsigned long *)XtMalloc(buffer->attrs_limit * sizeof(unsigned long));
1210 return buffer;
1211 }
1212
1213 /*- destroyAttributeBuffer: destroy draw string buffer's contents -*/
1214 static void
1215 destroyAttributeBuffer(buffer)
1216 AttributeBuffer *buffer;
1217 {
1218 XtFree((char *)buffer->attrs_buffer);
1219 XtFree((char *)buffer);
1220 }
1221
1222 /*- addAttributeBuffer: add segment to draw string buffer's contents -*/
1223 static void
1224 addAttributeBuffer(buffer, inputobj, seg, offset, fba)
1225 AttributeBuffer *buffer;
1226 Widget inputobj;
1227 ICString *seg;
1228 int offset;
1229 FeedbackAttributes *fba;
1230 {
1231 int nchars = seg->nchars - offset;
1232 unsigned long fb;
1233 int i;
1234
1235 if (buffer->attrs_length + nchars > buffer->attrs_limit) {
1236 unsigned long *new_attrs_buffer;
1237 int new_limit = buffer->attrs_limit * 2;
1238 if (new_limit < buffer->attrs_length + nchars)
1239 new_limit = buffer->attrs_length + nchars + 8;
1240 new_attrs_buffer = (unsigned long *)XtMalloc(new_limit * sizeof(unsigned long));
1241 bcopy(buffer->attrs_buffer, new_attrs_buffer,
1242 buffer->attrs_length * sizeof(unsigned long));
1243 XtFree((char *)buffer->attrs_buffer);
1244 buffer->attrs_limit = new_limit;
1245 buffer->attrs_buffer = new_attrs_buffer;
1246 }
1247 fb = attrToFeedback(fba, seg->attr);
1248 for (i = 0; i < nchars; i++) {
1249 buffer->attrs_buffer[buffer->attrs_length + i] = fb;
1250 }
1251 buffer->attrs_length += nchars;
1252 }
1253
1254 /*- attrToFeedback: ICString attribute -> XIMFeedback attribute converter -*/
1255 static unsigned long
1256 attrToFeedback(fba, attr)
1257 FeedbackAttributes *fba;
1258 int attr;
1259 {
1260 int idx;
1261
1262 if (attr == ICAttrNormalString) return 0;
1263
1264 if (!(attr & ICAttrConverted)) {
1265 /* Not yet converted */
1266 idx = FEEDBACK_NOCONV;
1267 } else if (attr & ICAttrCurrentSegment) {
1268 /* it's converted and the current segment */
1269 idx = FEEDBACK_CURRENT;
1270 } else if (attr & ICAttrCurrentSubSegment) {
1271 /* it's converted and the current sub segment */
1272 idx = FEEDBACK_CURRENTSUB;
1273 } else {
1274 /* converted, not current */
1275 idx = FEEDBACK_CONV;
1276 }
1277 return fba->feedbacks[idx];
1278 }
1279
1280 /*- CBPreeditStart: callback preedit start -*/
1281 static void
1282 CBPreeditStart(ocw)
1283 OnTheSpotConversionWidget ocw;
1284 {
1285 if (ocw->onthespot.preeditstartcallback == NULL ||
1286 XtHasCallbacks((Widget)ocw, XtNpreeditStartCallback) != XtCallbackHasSome)
1287 {
1288 /* no callback */
1289 return;
1290 }
1291
1292 TRACE(("OnTheSpot:CBPreeditStart()\n"));
1293
1294 XtCallCallbackList((Widget)ocw, ocw->onthespot.preeditstartcallback,
1295 (XtPointer)NULL);
1296 }
1297
1298 /*- CBPreeditDone: callback preedit done -*/
1299 static void
1300 CBPreeditDone(ocw)
1301 OnTheSpotConversionWidget ocw;
1302 {
1303 if (ocw->onthespot.preeditdonecallback == NULL ||
1304 XtHasCallbacks((Widget)ocw, XtNpreeditDoneCallback) != XtCallbackHasSome)
1305 {
1306 /* no callback */
1307 return;
1308 }
1309
1310 TRACE(("OnTheSpot:CBPreeditDone()\n"));
1311
1312 XtCallCallbackList((Widget)ocw, ocw->onthespot.preeditdonecallback,
1313 (XtPointer)NULL);
1314 }
1315
1316 /*- CBPreeditDraw: callback preedit draw -*/
1317 static void
1318 CBPreeditDraw(ocw, caret, chg_first, chg_length, encoding, format, text_length, text, attrs_length, attrs)
1319 OnTheSpotConversionWidget ocw;
1320 int caret;
1321 int chg_first;
1322 int chg_length;
1323 Atom encoding;
1324 int format;
1325 int text_length;
1326 XtPointer text;
1327 int attrs_length;
1328 unsigned long *attrs;
1329 {
1330 OCCPreeditDrawArg arg;
1331
1332 if (ocw->onthespot.preeditdrawcallback == NULL ||
1333 XtHasCallbacks((Widget)ocw, XtNpreeditDrawCallback) != XtCallbackHasSome)
1334 {
1335 /* no callback */
1336 return;
1337 }
1338
1339 TRACE(("OnTheSpot:CBPreeditDraw()\n"));
1340
1341 arg.caret = caret;
1342 arg.chg_first = chg_first;
1343 arg.chg_length = chg_length;
1344 arg.encoding = encoding;
1345 arg.format = format;
1346 arg.text_length = text_length;
1347 arg.text = text;
1348 arg.attrs_length = attrs_length;
1349 arg.attrs = attrs;
1350 XtCallCallbackList((Widget)ocw, ocw->onthespot.preeditdrawcallback,
1351 (XtPointer)&arg);
1352 }
1353
1354 /*- CBPreeditCaret: callback preedit caret -*/
1355 static void
1356 CBPreeditCaret(ocw, caret)
1357 OnTheSpotConversionWidget ocw;
1358 int caret;
1359 {
1360 if (ocw->onthespot.preeditcaretcallback == NULL ||
1361 XtHasCallbacks((Widget)ocw, XtNpreeditCaretCallback) != XtCallbackHasSome)
1362 {
1363 /* no callback */
1364 return;
1365 }
1366
1367 TRACE(("OnTheSpot:CBPreeditCaret()\n"));
1368
1369 XtCallCallbackList((Widget)ocw, ocw->onthespot.preeditcaretcallback,
1370 (XtPointer)caret);
1371 }
1372
1373 /*- CBStatusStart: callback status start -*/
1374 static void
1375 CBStatusStart(ocw)
1376 OnTheSpotConversionWidget ocw;
1377 {
1378 if (ocw->onthespot.statusstartcallback == NULL ||
1379 XtHasCallbacks((Widget)ocw, XtNstatusStartCallback) != XtCallbackHasSome)
1380 {
1381 /* no callback */
1382 return;
1383 }
1384
1385 TRACE(("OnTheSpot:CBStatusStart()\n"));
1386
1387 XtCallCallbackList((Widget)ocw, ocw->onthespot.statusstartcallback,
1388 (XtPointer)NULL);
1389 }
1390
1391 /*- CBStatusDone: callback status done -*/
1392 static void
1393 CBStatusDone(ocw)
1394 OnTheSpotConversionWidget ocw;
1395 {
1396 if (ocw->onthespot.statusdonecallback == NULL ||
1397 XtHasCallbacks((Widget)ocw, XtNstatusDoneCallback) != XtCallbackHasSome)
1398 {
1399 /* no callback */
1400 return;
1401 }
1402
1403 TRACE(("OnTheSpot:CBStatusDone()\n"));
1404
1405 XtCallCallbackList((Widget)ocw, ocw->onthespot.statusdonecallback,
1406 (XtPointer)NULL);
1407 }
1408
1409 /*- CBStatusDraw: callback status draw -*/
1410 static void
1411 CBStatusDraw(ocw, encoding, format, length, text, nchars)
1412 OnTheSpotConversionWidget ocw;
1413 Atom encoding;
1414 int format;
1415 int length;
1416 XtPointer text;
1417 int nchars;
1418 {
1419 OCCPreeditDrawArg arg;
1420
1421 if (ocw->onthespot.statusdrawcallback == NULL ||
1422 XtHasCallbacks((Widget)ocw, XtNstatusDrawCallback) != XtCallbackHasSome)
1423 {
1424 /* no callback */
1425 return;
1426 }
1427
1428 TRACE(("OnTheSpot:CBStatusDraw()\n"));
1429
1430 arg.caret = 0; /* ignored */
1431 arg.chg_first = 0; /* ignored */
1432 arg.chg_length = 0; /* ignored */
1433 arg.encoding = encoding;
1434 arg.format = format;
1435 arg.text_length = length;
1436 arg.text = text;
1437 arg.attrs_length = nchars;
1438 arg.attrs = NULL; /* ignored */
1439 XtCallCallbackList((Widget)ocw, ocw->onthespot.statusdrawcallback,
1440 (XtPointer)&arg);
1441 }
1442