Mercurial > kinput2.yaz
view lib/Canna.c @ 8:8b176cdf6319
imported patch 10_kinput2-v3.1-jp106_xfer.patch
author | Yoshiki Yazawa <yaz@honeyplanet.jp> |
---|---|
date | Mon, 08 Mar 2010 20:07:06 +0900 |
parents | 56c98768f86b |
children |
line wrap: on
line source
/* * Copyright (c) 1990 Software Research Associates, Inc. * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, provided * that the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of Software Research Associates not be * used in advertising or publicity pertaining to distribution of the * software without specific, written prior permission. Software Research * Associates makes no representations about the suitability of this software * for any purpose. It is provided "as is" without express or implied * warranty. * * Author: Makoto Ishisone, Software Research Associates, Inc., Japan */ /* Copyright 1991 NEC Corporation, Tokyo, Japan. * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, * provided that the above copyright notice appear in all copies and that * both that copyright notice and this permission notice appear in * supporting documentation, and that the name of NEC Corporation * not be used in advertising or publicity pertaining to distribution * of the software without specific, written prior permission. NEC * Corporation makes no representations about the suitability of this * software for any purpose. It is provided "as is" without express * or implied warranty. * * NEC CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN * NO EVENT SHALL NEC CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR * OTHER TORTUOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. * * Author: Akira Kon, NEC Corporation. (kon@d1.bs2.mt.nec.co.jp) */ /* $BD>$5$J$1$l$P$J$i$J$$$H$3$m(B $B!&(BDestroy $B$,8F$P$l$J$$$N$G(B CloseUIContext $B$G$-$J$$!#(B $B!&%b!<%INN0h$NBg$-$5!#(B($B$3$l$OB>$N%U%!%$%k$@$m$&$J(B) */ #ifndef lint static char *rcsid = "$Id: Canna.c,v 1.55 1999/05/25 08:13:03 ishisone Exp $"; #endif #include <X11/IntrinsicP.h> #include <X11/StringDefs.h> #include <X11/Xmu/Atoms.h> #define XK_KATAKANA #include <X11/keysym.h> #if XtSpecificationRelease > 4 #include <X11/Xfuncs.h> #endif #include "CannaP.h" #include "DebugPrint.h" #define _WCHAR_T /* $B$3$NDj5A$O(B jrkanji.h $B$G(B wcKanjiStatus $B$J$I$rDj5A$9$k$?$a(B */ #define wchar_t wchar #include <canna/jrkanji.h> static XtResource resources[] = { #define offset(field) XtOffset(CannaObject, canna.field) { XtNcannahost, XtCCannahost, XtRString, sizeof(String), offset(cannahost), XtRString, NULL }, { XtNcannafile, XtCCannafile, XtRString, sizeof(String), offset(cannafile), XtRString, NULL }, { XtNsendReturnByString, XtCSendReturnByString, XtRBoolean, sizeof(Boolean), offset(sendReturnByString), XtRBoolean, False }, #undef offset }; static void ClassInitialize(); static void Initialize(), Destroy(); static Boolean SetValues(); static int InputEvent(); static ICString *GetMode(); static int CursorPos(); static int NumSegments(); static ICString *GetSegment(); static int CompareSegment(); static ICString *GetItemList(); static int SelectItem(); static int ConvertedString(); static int ClearConversion(); static void displayPreEdit(); static int GetTriggerKeys(); static int PreeditString(); static int StatusString(); static void initializeCannaConnection(); static void toJapaneseMode(); static void convend(); static void changeTextForCanna(); static int copyInWchar(); static void fixProcForCanna(); static void shiftRight(); static void shiftLeft(); static void shiftLeftAll(); static void ibufInitialize(); static int freeIBuf(); #ifdef KC_SETLISTCALLBACK #ifdef CANNA_LIST_Convert #define CANNA_LISTFUNCTYPE int #else #define CANNA_LISTFUNCTYPE void #endif static CANNA_LISTFUNCTYPE listfunc(); static void openSelection(); #define SELECTION_SET 0 /* SelectionStart $B$r$7$F$bNI$$$H8@$&>pJs$r@_Dj$9$k(B */ #define SELECTION_DO 1 /* $B<B:]$K(B SelectionStart $B$r3+;O$9$k(B */ #else /* !KC_SETLISTCALLBACK */ #define openSelection(x, y, z) #endif /* !KC_SETLISTCALLBACK */ static ICString *GetAuxSegments(); CannaClassRec cannaClassRec = { { /* object fields */ /* superclass */ (WidgetClass) &inputConvClassRec, /* class_name */ "Canna", /* widget_size */ sizeof(CannaRec), /* class_initialize */ ClassInitialize, /* class_part_initialize */ NULL, /* class_inited */ FALSE, /* initialize */ Initialize, /* initialize_hook */ NULL, /* obj1 */ NULL, /* obj2 */ NULL, /* obj3 */ 0, /* resources */ resources, /* num_resources */ XtNumber(resources), /* xrm_class */ NULLQUARK, /* obj4 */ FALSE, /* obj5 */ FALSE, /* obj6 */ FALSE, /* obj7 */ FALSE, /* destroy */ Destroy, /* obj8 */ NULL, /* obj9 */ NULL, /* set_values */ SetValues, /* set_values_hook */ NULL, /* obj10 */ NULL, /* get_values_hook */ NULL, /* obj11 */ NULL, /* version */ XtVersion, /* callback_private */ NULL, /* obj12 */ NULL, /* obj13 */ NULL, /* obj14 */ NULL, /* extension */ NULL }, { /* inputConv fields */ /* InputEvent */ InputEvent, /* GetMode */ GetMode, /* CursorPos */ CursorPos, /* NumSegments */ NumSegments, /* GetSegment */ GetSegment, /* CompareSegment */ CompareSegment, /* GetItemList */ GetItemList, /* SelectItem */ SelectItem, /* GetConvertedString */ ConvertedString, /* ClearConversion */ ClearConversion, /* GetAuxSegments */ GetAuxSegments, /* SupportMultipleObjects */ True, /* GetTriggerKeys */ GetTriggerKeys, /* num_trigger_keys */ 0, /* trigger_keys */ NULL, /* GetPreeditString */ PreeditString, /* GetStatusString */ StatusString, /* NoMoreObjects */ False, }, { /* canna fields */ /* foo */ 0, } }; WidgetClass cannaObjectClass = (WidgetClass)&cannaClassRec; static void fix(); static ICString *SymbolList; static int NumSymbols; static void addObject(); static void deleteObject(); static int checkIfFunctionalChar(); static int ignoreListfunc = 0; static Display *displaybell = (Display *)0; static void ClassInitialize() { TRACE(("CannaObjectClass initialized\n")); /* $B2?$b$7$J$$(B */ } static int XKanaLookup(event_struct, buffer_return, bytes_buffer, keysym, status_return) XKeyEvent *event_struct; char *buffer_return; int bytes_buffer; KeySym *keysym; XComposeStatus *status_return; { int res; res = XLookupString(event_struct, buffer_return, bytes_buffer, keysym, status_return); if (!res && XK_overline <= *keysym && *keysym <= XK_semivoicedsound) { buffer_return[0] = (unsigned long)(*keysym) & 0xff; res = 1; } return res; } static int InputEvent(w, event) Widget w; XEvent *event; { CannaObject obj = (CannaObject)w; wchar buf[1024]; char kanabuf[20]; KeySym ks; XComposeStatus compose_status; wcKanjiStatus kanji_status; int len, nbytes, functionalChar; /* KeyPress$B0J30$O<N$F$k(B */ if (event->type != KeyPress /*&& event->type != KeyRelease*/) return 0; obj->canna.textchanged = False; /* $B<h$j$"$($:J8;z$KD>$7$F$7$^$&(B */ kanabuf[0] = '\0'; nbytes = XKanaLookup(event, kanabuf, 20, &ks, &compose_status); buf[0] = (wchar)kanabuf[0]; /* $B$-$?$J$$(B */ if (ks == XK_space && (event->xkey.state & ShiftMask)) { void convend(); convend(obj); return 0; } /* $BD9$5$,%<%m$N$b$N$K4X$7$F$O$A$g$C$H5_:Q(B */ functionalChar = checkIfFunctionalChar(event, ks, buf, 1024); /* shift+$B"*$N$h$&$JJ8;z$@$C$?$i#1J8;z$H?t$($k(B */ if ( !nbytes && functionalChar ) { nbytes = 1; } /* $BMW$i$J$$>l9g$OL5;k$9$k(B */ if (nbytes == 0) return 1; /* $B%Y%k$rLD$i$9%G%#%9%W%l%$$N@_Dj(B */ displaybell = XtDisplayOfObject((Widget)obj); /* $B$+$J4A;zJQ49$9$k(B */ len = wcKanjiString((int)obj, (int)buf[0], (wchar_t *)buf, 1024, &kanji_status); displayPreEdit(obj, len, buf, &kanji_status); return (kanji_status.info & KanjiThroughInfo) ? 1 : 0; } static void displayPreEdit(obj, len, buf, ks) CannaObject obj; int len; wchar *buf; wcKanjiStatus *ks; { Widget w = (Widget)obj; if (len > 0) { /* $B3NDjJ8;z$,$"$k>l9g(B */ if (len == 1 && (ks->info & KanjiThroughInfo) && (obj->canna.sendReturnByString == False || (((buf[0] & 0x7f) < (unsigned)0x20 && buf[0] != '\r' && buf[0] != '\t') || buf[0] == '\177'))) { ;/* XSendEvent$B$GAw$C$F$b$i$&$h$&$JJ8;z(B($B2?$b$7$J$$(B) */ } else { ks->info &= ~KanjiThroughInfo; fixProcForCanna(obj, buf, len); fix(obj); } } changeTextForCanna(obj, ks); /* $B%F%-%9%H$NJQ2=$r%A%'%C%/$9$k(B */ if (obj->canna.textchanged) { XtCallCallbackList(w, obj->inputConv.textchangecallback, (XtPointer)NULL); obj->canna.textchanged = False; } /* $BF~NO%b!<%I$r%A%'%C%/$9$k(B */ if (ks->info & KanjiModeInfo) { XtCallCallbackList(w, obj->inputConv.modechangecallback, (XtPointer)NULL); } if (ks->info & KanjiGLineInfo) { /* $B0lMw9T$,$"$k>l9g(B */ ICAuxControlArg arg; switch (obj->canna.ibuf->candstat) { case CANNA_GLINE_Start: arg.command = ICAuxStart; XtCallCallbackList((Widget)obj, obj->inputConv.auxcallback, (XtPointer)&arg); break; case CANNA_GLINE_End: arg.command = ICAuxEnd; XtCallCallbackList((Widget)obj, obj->inputConv.auxcallback, (XtPointer)&arg); break; case CANNA_GLINE_Change: arg.command = ICAuxChange; XtCallCallbackList((Widget)obj, obj->inputConv.auxcallback, (XtPointer)&arg); break; } } /* $B=*$o$j$+$I$&$+%A%'%C%/$9$k(B */ if (ks->info & KanjiModeInfo) { wchar modeinfo[4]; wcKanjiControl((int)obj, KC_SETMODEINFOSTYLE, (char *)1); wcKanjiControl((int)obj, KC_QUERYMODE, (char *)modeinfo); wcKanjiControl((int)obj, KC_SETMODEINFOSTYLE, (char *)0); if (modeinfo[0] - '@' == CANNA_MODE_AlphaMode) { toJapaneseMode(obj); convend(obj); } } openSelection(obj, SELECTION_DO, 0/* dummy */); } static ICString * GetMode(w) Widget w; { CannaObject obj = (CannaObject)w; wchar *mode; static ICString icstr; icstr.nchars = obj->canna.ibuf->modelen; if (icstr.nchars > 0) { mode = obj->canna.ibuf->curmode; icstr.data = (char *)mode; icstr.nbytes = icstr.nchars * sizeof(wchar); icstr.attr = ICAttrNormalString; } return &icstr; } static int CursorPos(w, nsegp, ncharp) Widget w; Cardinal *nsegp; Cardinal *ncharp; { CannaObject obj = (CannaObject)w; iBuf *ib = obj->canna.ibuf; Cardinal nseg, nchar; int ret = 0; if (ib->curseg < ib->nseg) { nseg = ib->curseg; nchar = 0; } else { nseg = ib->offset; nchar = ib->len[0 + ib->offset]; ret = 1; } if (nsegp) { *nsegp = nseg; } if (ncharp) { *ncharp = nchar; } return ret; } static int NumSegments(w) Widget w; { CannaObject obj = (CannaObject)w; iBuf *ib = obj->canna.ibuf; return ib->nseg; } static ICString * GetSegment(w, n) Widget w; Cardinal n; { CannaObject obj = (CannaObject)w; iBuf *ib = obj->canna.ibuf; static ICString seg; seg.data = (char *)ib->str[n]; seg.nchars = ib->len[n]; seg.nbytes = seg.nchars * sizeof(wchar); if (ib->curseg == n) { seg.attr = ICAttrConverted | ICAttrCurrentSegment; } else if (n < ib->offset) { seg.attr = ICAttrConverted; } else { seg.attr = ICAttrNotConverted; } return &seg; } /* ARGSUSED */ static int CompareSegment(w, seg1, seg2, n) Widget w; ICString *seg1; ICString *seg2; Cardinal *n; { wchar *p, *q; int len, nsame; int result = 0; if (seg1->attr != seg2->attr) result |= ICAttrChanged; len = seg1->nchars > seg2->nchars ? seg2->nchars : seg1->nchars; nsame = 0; p = (wchar *)seg1->data; q = (wchar *)seg2->data; while (nsame < len && *p++ == *q++) nsame++; if (nsame != len || len != seg1->nchars || len != seg2->nchars) result |= ICStringChanged; if (n) *n = nsame; return result; } static ICString * GetItemList(w, n) Widget w; Cardinal *n; { CannaObject obj = (CannaObject)w; *n = obj->canna.numcand; return obj->canna.candlist; } #define SELECTBUFSIZE 1024 static int SelectItem(w, n) Widget w; int n; { CannaObject obj = (CannaObject)w; wcKanjiStatus ks; wcKanjiStatusWithValue ksv; wchar buf[SELECTBUFSIZE]; if (n >= 0) *(obj->canna.cur_addr) = n; ksv.ks = &ks; buf[0] = (wchar)'\r'; ksv.buffer = buf; ksv.n_buffer = SELECTBUFSIZE; ksv.val = CANNA_FN_Kakutei; { ignoreListfunc = 1; wcKanjiControl((int)obj, KC_DO, (char *)&ksv); ignoreListfunc = 0; } displayPreEdit(obj, ksv.val, buf, ksv.ks); return 0; } static int ConvertedString(w, encoding, format, length, string) Widget w; Atom *encoding; int *format; int *length; XtPointer *string; { CannaObject obj = (CannaObject)w; iBuf *ib = obj->canna.ibuf; wchar *wbuf, *wp; int len, wlen; extern int convJWStoCT(); int offset = ib->offset; if (ib == NULL) return -1; if (ib->nseg == 0 || ib->offset == 0) return -1; wlen = ib->len[offset - 1]; if (wlen == 0) return -1; wbuf = ib->str[offset - 1]; /* * Canna $B%*%V%8%'%/%H$O(B COMPOUND_TEXT $B%(%s%3!<%G%#%s%0$7$+%5%]!<%H$7$J$$(B * COMPOUND_TEXT $B$KJQ49$9$k(B */ *encoding = XA_COMPOUND_TEXT(XtDisplayOfObject((Widget)obj)); *format = 8; /* COMPOUND_TEXT $B$O(B \r $B$,Aw$l$J$$$N$G(B \n $B$KJQ49$7$F$*$/(B */ for (wp = wbuf; *wp != 0; wp++) { if (*wp == '\r') *wp = '\n'; } *length = len = convJWStoCT(wbuf, (unsigned char *)NULL, 0); *string = XtMalloc(len + 1); (void)convJWStoCT(wbuf, (unsigned char *)*string, 0); shiftLeftAll(ib); return 0; } static int ClearConversion(w) Widget w; { CannaObject obj = (CannaObject)w; wcKanjiStatus ks; wcKanjiStatusWithValue ksv; wchar buf[SELECTBUFSIZE]; ksv.ks = &ks; ksv.buffer = buf; ksv.n_buffer = SELECTBUFSIZE; wcKanjiControl((int)obj, KC_KILL, (char *)&ksv); displayPreEdit(obj, ksv.val, buf, ksv.ks); return 0; } static ICString * GetAuxSegments(w, n, ns, nc) Widget w; Cardinal *n, *ns, *nc; { CannaObject obj = (CannaObject)w; iBuf *ib = obj->canna.ibuf; Cardinal nseg, nchar; if (n) { *n = ib->ngseg; } if (ib->curgseg < ib->ngseg) { nseg = ib->curgseg; nchar = 0; } else { nseg = 0; nchar = ib->gllen[0]; } if (ns) { *ns = nseg; } if (nc) { *nc = nchar; } return ib->ics; } /* ARGSUSED */ static void Initialize(req, new, args, num_args) Widget req; Widget new; ArgList args; Cardinal *num_args; { CannaObject obj = (CannaObject)new; obj->canna.selectionending = False; obj->canna.textchanged = False; obj->canna.symbollist = SymbolList; obj->canna.numsymbols = NumSymbols; obj->canna.cursymbol = 0; obj->canna.candlist = NULL; obj->canna.candlistsize = 0; obj->canna.numcand = 0; obj->canna.lastTextLengthIsZero = False; ibufInitialize(obj); /* $BJQ49$N=i4|2=(B */ initializeCannaConnection(obj); addObject(obj); } static int bell() { if (displaybell) { XBell(displaybell, 0); } return 0; } static int nCannaContexts = 0; static void initializeCannaConnection(obj) CannaObject obj; { char **warn = 0; extern (*jrBeepFunc)(); if (nCannaContexts == 0) { #ifdef KC_SETSERVERNAME if (obj->canna.cannahost != NULL) { wcKanjiControl((int)obj, KC_SETSERVERNAME, obj->canna.cannahost); } #endif /* KC_SETSERVERNAME */ #ifdef KC_SETINITFILENAME if (obj->canna.cannafile != NULL) { wcKanjiControl((int)obj, KC_SETINITFILENAME, obj->canna.cannafile); } #endif /* KC_SETINITFILENAME */ wcKanjiControl((int)obj, KC_INITIALIZE, (char *)&warn); TRACE(("Canna initialized\n")); if (warn) { char **p; for (p = warn; *p ; p++) { XtAppWarning(XtWidgetToApplicationContext((Widget)obj), *p); } } } nCannaContexts++; #ifdef KC_SETAPPNAME wcKanjiControl((int)obj, KC_SETAPPNAME, "kinput2"); #endif #ifdef DONT_USE_HANKAKU_KATAKANA /* $BH>3Q%+%?%+%J$N6X;_(B */ wcKanjiControl((int)obj, KC_INHIBITHANKAKUKANA, (char *)1); #endif /* $B0lMw9T$r#7#8%3%i%`$K@_Dj(B */ wcKanjiControl((int)obj, KC_SETWIDTH, (char *)78); /* $B8uJd0lMw%3!<%k%P%C%/$r@_Dj(B */ #ifdef KC_SETLISTCALLBACK { jrListCallbackStruct lcs; lcs.client_data = (char *)obj; lcs.callback_func = listfunc; wcKanjiControl((int)obj, KC_SETLISTCALLBACK, (char *)&lcs); } #endif /* KC_SETLISTCALLBACK */ jrBeepFunc = bell; /* $B$5$i$KF|K\8lF~NO%b!<%I$K$7$F$*$/(B */ toJapaneseMode(obj); } static void Destroy(w) Widget w; { CannaObject obj = (CannaObject)w; wcKanjiStatusWithValue ksv; wcKanjiStatus ks; wchar buf[512]; int i; /* $B%P%C%U%!$N2rJ|(B */ freeIBuf(obj->canna.ibuf); if (obj->canna.candlist) { for (i = 0 ; i < obj->canna.candlistsize ; i++) { if ((obj->canna.candlist + i)->data) { XtFree((obj->canna.candlist + i)->data); } } XtFree((char *)obj->canna.candlist); } /* $B!X$+$s$J!Y$N=hM}(B */ ksv.buffer = buf; ksv.n_buffer = 512; ksv.ks = &ks; wcKanjiControl((int)obj, KC_CLOSEUICONTEXT, (char *)&ksv); if (--nCannaContexts == 0) { char **warn = 0; wcKanjiControl(0, KC_FINALIZE, (char *)&warn); if (warn) { char **p; for (p = warn; *p ; p++) { XtAppWarning(XtWidgetToApplicationContext((Widget)obj), *p); } } } deleteObject(obj); } static Boolean SetValues(cur, req, wid, args, num_args) Widget cur; Widget req; Widget wid; ArgList args; Cardinal *num_args; /* ARGSUSED */ { CannaObject old = (CannaObject)cur; CannaObject new = (CannaObject)wid; return False; } static void fix(obj) CannaObject obj; { /* $B3NDj$N=hM}(B */ XtCallCallbackList((Widget)obj, obj->inputConv.fixcallback, (XtPointer)NULL); /* $B!)!)!)(B */ } static void convend(obj) CannaObject obj; { XtCallCallbackList((Widget)obj, obj->inputConv.endcallback, (XtPointer)NULL); } /* * keeping list of objects */ typedef struct _oblist_ { CannaObject obj; struct _oblist_ *next; } ObjRec; static ObjRec *ObjList = NULL; static void addObject(obj) CannaObject obj; { ObjRec *objp = XtNew(ObjRec); objp->obj = obj; objp->next = ObjList; ObjList = objp; } static void deleteObject(obj) CannaObject obj; { ObjRec *objp, *objp0; for (objp0 = NULL, objp = ObjList; objp != NULL; objp0 = objp, objp = objp->next) { if (objp->obj == obj) { if (objp0 == NULL) { ObjList = objp->next; } else { objp0->next = objp->next; } XtFree((char *)objp); return; } } } /* * Operations to canna.ibuf */ /* cfuncdef changeTextForCanna -- ibuf $B$NFbMF$r(B kanji_status $B$rMQ$$$F=q$-49$($k!#(B $B4pK\E*$K$O8uJdJ8;zNs$H8uJd0lMw9TJ8;zNs$K4X$7$F0J2<$N=hM}$r9T$&!#(B (1) $B$$$:$l$NJ8;zNs$b%F%-%9%H$,H?E>$7$F$$$kItJ,$H$=$&$G$J$$ItJ,(B $B$,B8:_$7!"H?E>$7$F$$$kItJ,$O#1%+=j$7$+B8:_$7$J$$!#(B (2) $B$7$?$,$C$F$$$:$l$NJ8;zNs$bH?E>$7$F$$$k$H$3$m$H$=$NN>C<$KH?E>(B $B$7$F$$$J$$ItJ,$H$,B8:_$9$k>l9g$K#3ItJ,$KJ,$+$l$k$3$H$K$J$j!"(B $BH?E>$7$F$$$kItJ,$N0LCV$d!"H?E>$7$F$$$k2U=j$,$J$$>l9g$J$I$r(B $B9g$o$;$F9M$($F$b#3ItJ,0J>e$KJ,$+$l$k$3$H$O$J$$!#(B (3) $B$7$?$,$C$F!"$$$:$l$NJ8;zNs$b:GBg#3$D$N%;%0%a%s%H$KJ,$1$FI=<((B $B%&%#%8%'%C%H$KEO$9$h$&$K$9$k!#(B */ static void changeTextForCanna(cldata, ksp) caddr_t cldata; wcKanjiStatus *ksp; { CannaObject obj = (CannaObject)cldata; iBuf *ibuf = obj->canna.ibuf; int offset = ibuf->offset, i; if (ksp->length == 0) { ibuf->curseg = offset; ibuf->nseg = offset; ibuf->len[0 + offset] = ibuf->len[1 + offset] = ibuf->len[2 + offset] = 0; if (!obj->canna.lastTextLengthIsZero) { obj->canna.textchanged = True; obj->canna.lastTextLengthIsZero = True; } } else if (ksp->length > 0) { obj->canna.lastTextLengthIsZero = False; ibuf->len[1 + offset] = ibuf->len[2 + offset] = 0; if (ksp->revLen > 0) { if (ksp->revPos == 0) { int remain = ksp->length - ksp->revLen; copyInWchar(ksp->echoStr, ksp->revLen, &(ibuf->str[0 + offset]), &(ibuf->size[0 + offset]), &(ibuf->len[0 + offset])); ibuf->curseg = offset; ibuf->nseg = offset + 1; if (remain) { copyInWchar(ksp->echoStr + ksp->revLen, remain, &(ibuf->str[1 + offset]), &(ibuf->size[1 + offset]), &(ibuf->len[1 + offset])); ibuf->nseg = offset + 2; } } else { int remain = ksp->length - ksp->revPos - ksp->revLen; copyInWchar(ksp->echoStr, ksp->revPos, &(ibuf->str[0 + offset]), &(ibuf->size[0 + offset]), &(ibuf->len[0 + offset])); copyInWchar(ksp->echoStr + ksp->revPos, ksp->revLen, &(ibuf->str[1 + offset]), &(ibuf->size[1 + offset]), &(ibuf->len[1 + offset])); ibuf->curseg = offset + 1; ibuf->nseg = offset + 2; if (remain) { copyInWchar(ksp->echoStr + ksp->revPos + ksp->revLen, remain, &(ibuf->str[2 + offset]), &(ibuf->size[2 + offset]), &(ibuf->len[2 + offset])); ibuf->nseg = offset + 3; } } } else { copyInWchar(ksp->echoStr, ksp->length, &(ibuf->str[0 + offset]), &(ibuf->size[0 + offset]), &(ibuf->len[0 + offset])); ibuf->len[1 + offset] = ibuf->len[2 + offset] = 0; ibuf->nseg = offset + 1; ibuf->curseg = offset + 1; } obj->canna.textchanged = True; } /* $B%b!<%I(B */ if (ksp->info & KanjiModeInfo) { int modelen = 0; while (ksp->mode[modelen]) modelen++; copyInWchar(ksp->mode, modelen, &(ibuf->curmode), &(ibuf->modesize), &(ibuf->modelen)); } /* $B0lMw9T(B */ if (ksp->info & KanjiGLineInfo) { if (ksp->gline.length == 0) { switch (ibuf->candstat) { case CANNA_GLINE_Empty: case CANNA_GLINE_End: ibuf->candstat = CANNA_GLINE_Empty; break; case CANNA_GLINE_Start: case CANNA_GLINE_Change: ibuf->candstat = CANNA_GLINE_End; break; } ibuf->curgseg = 0; ibuf->ngseg = 0; ibuf->gllen[0] = ibuf->gllen[1] = ibuf->gllen[2] = 0; } else if (ksp->gline.length > 0) { switch (ibuf->candstat) { case CANNA_GLINE_Empty: case CANNA_GLINE_End: ibuf->candstat = CANNA_GLINE_Start; break; case CANNA_GLINE_Start: case CANNA_GLINE_Change: ibuf->candstat = CANNA_GLINE_Change; break; } ibuf->gllen[1] = ibuf->gllen[2] = 0; if (ksp->gline.revLen > 0) { if (ksp->gline.revPos == 0) { int remain = ksp->gline.length - ksp->gline.revLen; copyInWchar(ksp->gline.line, ksp->gline.revLen, &(ibuf->gline[0]), &(ibuf->glsize[0]), &(ibuf->gllen[0])); ibuf->curgseg = 0; ibuf->ngseg = 1; if (remain) { copyInWchar(ksp->gline.line + ksp->gline.revLen, remain, &(ibuf->gline[1]), &(ibuf->glsize[1]), &(ibuf->gllen[1])); ibuf->ngseg = 2; } } else { int remain = ksp->gline.length - ksp->gline.revPos - ksp->gline.revLen; copyInWchar(ksp->gline.line, ksp->gline.revPos, &(ibuf->gline[0]), &(ibuf->glsize[0]), &(ibuf->gllen[0])); copyInWchar(ksp->gline.line + ksp->gline.revPos, ksp->gline.revLen, &(ibuf->gline[1]), &(ibuf->glsize[1]), &(ibuf->gllen[1])); ibuf->curgseg = 1; ibuf->ngseg = 2; if (remain) { copyInWchar(ksp->gline.line + ksp->gline.revPos + ksp->gline.revLen, remain, &(ibuf->gline[2]), &(ibuf->glsize[2]), &(ibuf->gllen[2])); ibuf->ngseg = 3; } } } else { copyInWchar(ksp->gline.line, ksp->gline.length, &(ibuf->gline[0]), &(ibuf->glsize[0]), &(ibuf->gllen[0])); ibuf->gllen[1] = ibuf->gllen[2] = 0; ibuf->ngseg = 1; ibuf->curgseg = 1; } } for (i = 0 ; i < ibuf->ngseg ; i++) { ibuf->ics[i].data = (char *)ibuf->gline[i]; ibuf->ics[i].nchars = ibuf->gllen[i]; ibuf->ics[i].nbytes = ibuf->gllen[i] * sizeof(wchar); ibuf->ics[i].attr = ICAttrConverted; } if (ibuf->curgseg < ibuf->ngseg) { ibuf->ics[ibuf->curgseg].attr |= ICAttrCurrentSegment; } } } /* cfuncdef copyInWchar -- wchar $B$r%3%T!<$9$k!#(B ws, wlen $B$G<($5$l$?(B wchar $BJ8;zNs$r(B wsbuf $B$N%]%$%s%H@h$N%P%C%U%!$K3J(B $BG<$9$k!#(Bwsbuf $B$N%5%$%:$O(B wssize $B$N%]%$%s%H@h$K3JG<$5$l$F$$$kCM$G;X(B $BDj$5$l$k$,!"$=$l$G$O>.$5$$;~$O(B copyInWchar $BFb$G(B XtRealloc $B$5$l!"?7(B $B$?$K%"%m%1!<%H$5$l$?%P%C%U%!$,(B wsbuf $B$N%]%$%s%H@h$K3JG<$5$l$k!#$^$?!"(B $B%P%C%U%!$N?7$?$J%5%$%:$,(B wssize $B$N%]%$%s%H@h$K3JG<$5$l$k!#F@$i$l$?(B $BJ8;z?t$,(Bwslen $B$N%]%$%s%H@h$K3JG<$5$l$k!#(B */ static copyInWchar(ws, wlen, wsbuf, wssize, wslen) wchar *ws; int wlen; wchar **wsbuf; int *wssize, *wslen; { int i; if (*wssize == 0) { if ((*wsbuf = (wchar *)XtMalloc((wlen + 1) * sizeof(wchar))) == (wchar *)0) { /* $B%(%i!<$@(B */ } else { *wssize = wlen + 1; } } if (wlen + 1 > *wssize) { if ((*wsbuf = (wchar *)XtRealloc((char *)*wsbuf, (wlen + 1) * sizeof(wchar))) == (wchar *)0) { /* $B%(%i!<$@!#$I$&$9$l$PNI$$!)(B */ } else { *wssize = wlen + 1; } } *wslen = wlen; (void)bcopy(ws, *wsbuf, wlen * sizeof(wchar)); *(*wsbuf + wlen) = (wchar)0; return 0; /* $B#0$OFC$K0UL#$,L5$$(B */ } /* cfuncdef fixProcForCanna -- $B3NDj$7$?J8;z$N=hM}$r9T$&(B */ static void fixProcForCanna(cldata, fixedstr, fixedlen) caddr_t cldata; wchar *fixedstr; int fixedlen; { CannaObject obj = (CannaObject)cldata; iBuf *ib = obj->canna.ibuf; int offset = ib->offset; if (offset < NConvertedSegments) { shiftRight(ib); offset = ib->offset; } else { shiftLeft(ib); } copyInWchar(fixedstr, fixedlen, &(ib->str[offset - 1]), &(ib->size[offset - 1]), &(ib->len[offset - 1])); } /* cfuncdef shiftRight -- ibuf $B$NJ8;z%P%C%U%!$N(B offset $B0J9_$r1&$K%7%U%H$9$k(B */ static void shiftRight(ib) iBuf *ib; { int i; wchar *tmpbuf; int tmpsize, tmplen; int offset = ib->offset; tmpbuf = ib->str[ib->nseg]; tmpsize = ib->size[ib->nseg]; for (i = ib->nseg ; offset < i ; i--) { ib->str[i] = ib->str[i - 1]; ib->size[i] = ib->size[i - 1]; ib->len[i] = ib->len[i - 1]; } ib->str[offset] = tmpbuf; ib->size[offset] = tmpsize; ib->offset++; ib->nseg++; ib->curseg++; } /* cfuncdef shiftLeft -- ibuf $B$NJ8;z%P%C%U%!$N(B offset $B0JA0$r:8$K%7%U%H$9$k(B */ static void shiftLeft(ib) iBuf *ib; { int i; wchar *tmpbuf; int tmpsize, tmplen; int offset = ib->offset; tmpbuf = ib->str[0]; tmpsize = ib->size[0]; for (i = 0 ; i < offset - 1 ; i++) { ib->str[i] = ib->str[i + 1]; ib->size[i] = ib->size[i + 1]; ib->len[i] = ib->len[i + 1]; } ib->str[offset - 1] = tmpbuf; ib->size[offset - 1] = tmpsize; } /* cfuncdef shiftLeftAll -- ibuf $B$NJ8;z%P%C%U%!A4BN$r:8$K%7%U%H$9$k(B */ static void shiftLeftAll(ib) iBuf *ib; { int i; wchar *tmpbuf; int tmpsize, tmplen; int nseg = ib->nseg; tmpbuf = ib->str[0]; tmpsize = ib->size[0]; for (i = 0 ; i < nseg - 1 ; i++) { ib->str[i] = ib->str[i + 1]; ib->size[i] = ib->size[i + 1]; ib->len[i] = ib->len[i + 1]; } ib->str[nseg - 1] = tmpbuf; ib->size[nseg - 1] = tmpsize; ib->nseg--; ib->curseg--; ib->offset--; } /* cfuncdef ibufInitialize -- ibuf $B$N=i4|2==hM}(B */ static void ibufInitialize(obj) CannaObject obj; { int i; iBuf *ib; ib = obj->canna.ibuf = (iBuf *)XtMalloc(sizeof(iBuf)); if (ib == 0) { /* $B%(%i!<$@!#$I$&$9$Y(B */ } for (i = 0 ; i < NConvertedSegments + 3 ; i++) { ib->size[i] = 0; ib->len[i] = 0; } ib->offset = ib->curseg = ib->nseg = 0; ib->candstat = CANNA_GLINE_Empty; for (i = 0 ; i < 3 ; i++) { ib->gline[i] = 0; ib->glsize[i] = ib->gllen[i] = 0; } ib->modesize = 0; ib->modelen = 0; } /* cfuncdef freeIBuf -- ibuf $B$N(B free */ static int freeIBuf(ib) iBuf *ib; { int i; if (ib == 0) { return 0; } for (i = 0 ; i < NConvertedSegments + 3 ; i++) { if (ib->size[i] > 0) { XtFree((char *)ib->str[i]); } } for (i = 0 ; i < 3 ; i++) { if (ib->glsize[i] > 0) { XtFree((char *)ib->gline[i]); } } if (ib->modesize > 0) { XtFree((char *)ib->curmode); } free(ib); return 0; } static void toJapaneseMode(obj) CannaObject obj; { wcKanjiStatusWithValue ksv; wcKanjiStatus ks; wchar buf[1024]; buf[0] = '@'; ksv.ks = &ks; ksv.buffer = buf; ksv.n_buffer = 1024; #ifndef KC_DO ksv.val = CANNA_MODE_HenkanMode; wcKanjiControl((int)obj, KC_CHANGEMODE, (char *)&ksv); #else ksv.val = CANNA_FN_JapaneseMode; wcKanjiControl((int)obj, KC_DO, (char *)&ksv); #endif changeTextForCanna(obj, &ks); } /* checkIfFunctionalChar -- $B%7%U%H%-!<$N$h$&$KL50UL#$J%-!<$+$I$&$+$NH=JL(B $BCM(B: $B#1(B $B0UL#$,$"$k(B $B#0(B $BL50UL#(B($B%b%G%#%U%!%$%"%-!<$J$I(B) */ static int checkIfFunctionalChar(event_struct, keysym, buffer_return, n_buffer) XKeyEvent *event_struct; KeySym keysym; wchar *buffer_return; int n_buffer; { int functionalChar = 0; switch ((int)keysym) { case XK_KP_F1: case XK_KP_F2: case XK_KP_F3: case XK_KP_F4: *buffer_return = CANNA_KEY_PF1 + (int)keysym - (int)XK_KP_F1; functionalChar = 1; break; case XK_F1: case XK_F2: case XK_F3: case XK_F4: case XK_F5: case XK_F6: case XK_F7: case XK_F8: case XK_F9: case XK_F10: case XK_F11: case XK_F12: case XK_F13: case XK_F14: case XK_F15: case XK_F16: *buffer_return = CANNA_KEY_F1 + (int)keysym - (int)XK_F1; functionalChar = 1; break; case XK_Insert: *buffer_return = CANNA_KEY_Insert; functionalChar = 1; break; case XK_Prior: *buffer_return = CANNA_KEY_Rollup; functionalChar = 1; break; case XK_Next: *buffer_return = CANNA_KEY_Rolldown; functionalChar = 1; break; case XK_Muhenkan: if (event_struct->state & 4 /* control-shifted */) *buffer_return = CANNA_KEY_Cntrl_Nfer; else if (event_struct->state & 1 /* shifted */) *buffer_return = CANNA_KEY_Shift_Nfer; else *buffer_return = CANNA_KEY_Nfer; functionalChar = 1; break; case XK_Henkan_Mode: if (event_struct->state & 4 /* control-shifted */) *buffer_return = CANNA_KEY_Cntrl_Xfer; else if (event_struct->state & 1 /* shifted */) *buffer_return = CANNA_KEY_Shift_Xfer; else *buffer_return = CANNA_KEY_Xfer; functionalChar = 1; break; case XK_Kanji: if (event_struct->state & 4 /* control-shifted */) *buffer_return = CANNA_KEY_Cntrl_Xfer; else if (event_struct->state & 1 /* shifted */) *buffer_return = CANNA_KEY_Shift_Xfer; else *buffer_return = CANNA_KEY_Xfer; functionalChar = 1; break; case XK_Up: if (event_struct->state & 4 /* control-shifted */) *buffer_return = CANNA_KEY_Cntrl_Up; else if (event_struct->state & 1 /* shifted */) *buffer_return = CANNA_KEY_Shift_Up; else *buffer_return = CANNA_KEY_Up; functionalChar = 1; break; case XK_Down: if (event_struct->state & 4 /* control-shifted */) *buffer_return = CANNA_KEY_Cntrl_Down; else if (event_struct->state & 1 /* shifted */) *buffer_return = CANNA_KEY_Shift_Down; else *buffer_return = CANNA_KEY_Down; functionalChar = 1; break; case XK_Right: if (event_struct->state & 4 /* control-shifted */) *buffer_return = CANNA_KEY_Cntrl_Right; else if (event_struct->state & 1 /* shifted */) *buffer_return = CANNA_KEY_Shift_Right; else *buffer_return = CANNA_KEY_Right; functionalChar = 1; break; case XK_Left: if (event_struct->state & 4 /* control-shifted */) *buffer_return = CANNA_KEY_Cntrl_Left; else if (event_struct->state & 1 /* shifted */) *buffer_return = CANNA_KEY_Shift_Left; else *buffer_return = CANNA_KEY_Left; functionalChar = 1; break; case XK_Help: *buffer_return = CANNA_KEY_Help; functionalChar = 1; break; case XK_Home: *buffer_return = CANNA_KEY_Home; functionalChar = 1; break; } return functionalChar; } #ifdef KC_SETLISTCALLBACK static void moveSelection(obj, dir) CannaObject obj; int dir; { ICSelectionControlArg arg; arg.command = ICSelectionMove; arg.u.dir = dir; XtCallCallbackList((Widget)obj, obj->inputConv.selectioncallback, (XtPointer)&arg); } static int insertSelection(obj, selected) CannaObject obj; int selected; { obj->canna.curcand = selected; *(obj->canna.cur_addr) = selected; return 0; } static void endSelection(obj, abort) CannaObject obj; int abort; { ICSelectionControlArg arg; int selected; if (ignoreListfunc) return; /* SelectItem $B$G=hM}$5$l$k$N$G$3$3$OITMW(B */ arg.command = ICSelectionEnd; arg.u.current_item = -1; XtCallCallbackList((Widget)obj, obj->inputConv.selectioncallback, (XtPointer)&arg); if (!abort && (selected = arg.u.current_item) >= 0) { insertSelection(obj, selected); } } #ifdef CANNA_LIST_Query static void querySelection(obj) CannaObject obj; { ICSelectionControlArg arg; int selected; if (ignoreListfunc) return; /* SelectItem $B$G=hM}$5$l$k$N$G$3$3$OITMW(B */ arg.command = ICSelectionGet; arg.u.current_item = -1; XtCallCallbackList((Widget)obj, obj->inputConv.selectioncallback, (XtPointer)&arg); if ((selected = arg.u.current_item) >= 0) { insertSelection(obj, selected); } } #endif static void openSelection(obj, func, curitem) CannaObject obj; int func; /* $B0lHV>e$r8+$h(B */ int curitem; { ICSelectionControlArg arg; static int current = 0; static int doit = 0; if (func == SELECTION_SET) { current = curitem; doit = 1; } else if (func == SELECTION_DO && doit) { doit = 0; arg.command = ICSelectionStart; arg.u.selection_kind = ICSelectionCandidates; XtCallCallbackList((Widget)obj, obj->inputConv.selectioncallback, (XtPointer)&arg); /* set current item */ arg.command = ICSelectionSet; arg.u.current_item = current; XtCallCallbackList((Widget)obj, obj->inputConv.selectioncallback, (XtPointer)&arg); } } static void getAllCandidates(); /* listfunc -- $B8uJd0lMw%b!<%I$K$J$C$?;~$K8F$S=P$5$l$k4X?t(B * * obj : KC_SETLISTCALLBACK $B$G@_Dj$7$?%/%i%$%"%s%H%G!<%?(B * func : $B8uJd0lMw5!G=$N8GM-$N5!G=$rI=$9#I#D(B * items : Start $B$N;~$K$O8uJd0lMw$NA4%"%$%F%`$,F~$k(B * nitems : $B!7(B $BA4%"%$%F%`$N?t$,F~$k(B * cur_item : $B!7(B $B%+%l%s%H%"%$%F%`HV9f$r3JG<$9$k%"%I%l%9$,F~$k(B */ static CANNA_LISTFUNCTYPE listfunc(obj, func, items, nitems, cur_item) CannaObject obj; int func; wchar **items; int nitems, *cur_item; { ICSelectionControlArg arg; int i; wchar **p; switch (func) { case CANNA_LIST_Start: getAllCandidates(obj, nitems, items); obj->canna.numcand = nitems; obj->canna.curcand = *cur_item; obj->canna.cur_addr = cur_item; openSelection(obj, SELECTION_SET, *cur_item); break; case CANNA_LIST_Select: endSelection(obj, False); break; case CANNA_LIST_Quit: endSelection(obj, True); break; #ifdef CANNA_LIST_Query case CANNA_LIST_Query: querySelection(obj); break; #endif #ifdef CANNA_LIST_Convert case CANNA_LIST_Convert: #endif case CANNA_LIST_Forward: moveSelection(obj, ICMoveRight); break; case CANNA_LIST_Backward: moveSelection(obj, ICMoveLeft); break; case CANNA_LIST_Next: moveSelection(obj, ICMoveDown); break; case CANNA_LIST_Prev: moveSelection(obj, ICMoveUp); break; case CANNA_LIST_BeginningOfLine: moveSelection(obj, ICMoveLeftMost); break; case CANNA_LIST_EndOfLine: moveSelection(obj, ICMoveRightMost); break; #ifdef CANNA_LIST_Insert case CANNA_LIST_Insert: return 0; #endif } #ifdef CANNA_LIST_Convert return 1; #endif } static void allocCandlist(obj, n) CannaObject obj; int n; { ICString *p; int i; if (n <= obj->canna.candlistsize) return; if (obj->canna.candlistsize == 0) { p = (ICString *)XtMalloc(n * sizeof(ICString)); } else { p = (ICString *)XtRealloc((char *)obj->canna.candlist, n * sizeof(ICString)); } for (i = obj->canna.candlistsize ; i < n ; i++) { p[i].nbytes = p[i].nchars = (unsigned short)0; p[i].data = (char *)0; p[i].attr = 0; } obj->canna.candlist = p; obj->canna.candlistsize = n; } static void getAllCandidates(obj, ncand, items) CannaObject obj; int ncand; wchar **items; { ICString *strp; wchar **p; int i, bytes, chars; allocCandlist(obj, ncand); for (i = 0, strp = obj->canna.candlist, p = items ; i < ncand; i++, strp++, p++) { int len = 0; bytes = strp->nbytes; chars = strp->nchars; while ((*p)[len]) len++; copyInWchar(*p, len, (wchar **)&(strp->data), &bytes, &chars); strp->nbytes = bytes; strp->nchars = chars; strp->attr = ICAttrNormalString; } } #endif /* KC_SETLISTCALLBACK */ struct _keymap { unsigned char cannakey; KeySym keysym; long modifier; } cannakeymap[] = { {(unsigned char)'\b', XK_BackSpace, 0}, {(unsigned char)'\t', XK_Tab, 0}, {(unsigned char)'\n', XK_Linefeed, 0}, {(unsigned char)'\013', XK_Clear, 0}, {(unsigned char)'\r', XK_Return, 0}, {(unsigned char)'\023', XK_Pause, 0}, {(unsigned char)'\024', XK_Scroll_Lock, 0}, {(unsigned char)'\e', XK_Escape, 0}, {(unsigned char)CANNA_KEY_Nfer, XK_Muhenkan, 0}, {(unsigned char)CANNA_KEY_Xfer, XK_Henkan_Mode, 0}, {(unsigned char)CANNA_KEY_Up, XK_Up, 0}, {(unsigned char)CANNA_KEY_Left, XK_Left, 0}, {(unsigned char)CANNA_KEY_Right, XK_Right, 0}, {(unsigned char)CANNA_KEY_Down, XK_Down, 0}, {(unsigned char)CANNA_KEY_Insert, XK_Insert, 0}, {(unsigned char)CANNA_KEY_Rollup, XK_Prior, 0}, {(unsigned char)CANNA_KEY_Rolldown, XK_Next, 0}, {(unsigned char)CANNA_KEY_Home, XK_Home, 0}, {(unsigned char)CANNA_KEY_Help, XK_Help, 0}, {(unsigned char)CANNA_KEY_KP_Key, XK_KP_Space, 0}, /* ? */ {(unsigned char)CANNA_KEY_Shift_Nfer, XK_Muhenkan, ShiftMask}, {(unsigned char)CANNA_KEY_Shift_Xfer, XK_Henkan_Mode, ShiftMask}, {(unsigned char)CANNA_KEY_Shift_Up, XK_Up, ShiftMask}, {(unsigned char)CANNA_KEY_Shift_Left, XK_Left, ShiftMask}, {(unsigned char)CANNA_KEY_Shift_Right, XK_Right, ShiftMask}, {(unsigned char)CANNA_KEY_Shift_Down, XK_Down, ShiftMask}, {(unsigned char)CANNA_KEY_Cntrl_Nfer, XK_Muhenkan, ControlMask}, {(unsigned char)CANNA_KEY_Cntrl_Xfer, XK_Henkan_Mode, ControlMask}, {(unsigned char)CANNA_KEY_Cntrl_Up, XK_Up, ControlMask}, {(unsigned char)CANNA_KEY_Cntrl_Left, XK_Left, ControlMask}, {(unsigned char)CANNA_KEY_Cntrl_Right, XK_Right, ControlMask}, {(unsigned char)CANNA_KEY_Cntrl_Down, XK_Down, ControlMask}, {(unsigned char)CANNA_KEY_F1, XK_F1, 0}, {(unsigned char)CANNA_KEY_F2, XK_F2, 0}, {(unsigned char)CANNA_KEY_F3, XK_F3, 0}, {(unsigned char)CANNA_KEY_F4, XK_F4, 0}, {(unsigned char)CANNA_KEY_F5, XK_F5, 0}, {(unsigned char)CANNA_KEY_F6, XK_F6, 0}, {(unsigned char)CANNA_KEY_F7, XK_F7, 0}, {(unsigned char)CANNA_KEY_F8, XK_F8, 0}, {(unsigned char)CANNA_KEY_F9, XK_F9, 0}, {(unsigned char)CANNA_KEY_F10, XK_F10, 0}, {(unsigned char)CANNA_KEY_PF1, XK_KP_F1, 0}, {(unsigned char)CANNA_KEY_PF2, XK_KP_F2, 0}, {(unsigned char)CANNA_KEY_PF3, XK_KP_F3, 0}, {(unsigned char)CANNA_KEY_PF4, XK_KP_F4, 0}, {(unsigned char)CANNA_KEY_PF5, XK_F15, 0}, {(unsigned char)CANNA_KEY_PF6, XK_F16, 0}, {(unsigned char)CANNA_KEY_PF7, XK_F17, 0}, {(unsigned char)CANNA_KEY_PF8, XK_F18, 0}, {(unsigned char)CANNA_KEY_PF9, XK_F19, 0}, {(unsigned char)CANNA_KEY_PF10, XK_F20, 0}, }; #define NCANNAKEYMAP (sizeof(cannakeymap) / sizeof(struct _keymap)) /* ARGSUSED */ static int GetTriggerKeys(w, keys_return) Widget w; ICTriggerKey **keys_return; { CannaObject obj = (CannaObject)w; ICTriggerKey *keys; unsigned char c, mkeys[256], *p, *ekeys; /* enough */ int n; struct _keymap *pk, *ek; n = wcKanjiControl((int)obj, KC_MODEKEYS, (char *)mkeys); *keys_return = keys = (ICTriggerKey *)XtMalloc(2 * n * sizeof(ICTriggerKey)); /* $B!V(B2 *$B!W$N0UL#(B: $B0l$D$N%3!<%I$K(B2$B$D$N(B X $B$N%-!<$,B8:_$7$F$$$?$j$9$k;v$,$"$k!#(B ($BNc(B) C-h $B"*(B Ctl<Key>h, <Key>Backspace */ if (keys) { for (p = mkeys, ekeys = p + n ; p < ekeys ; p++, keys++) { c = *p; if (c == (unsigned char)0) { keys->keysym = XK_space; keys->modifiers = keys->modifiermask = ControlMask; keys++; keys->keysym = XK_at; keys->modifiers = keys->modifiermask = ControlMask; } else if (c < ' ') { keys->keysym = XK_quoteleft + c; keys->modifiers = keys->modifiermask = ControlMask; for (pk = cannakeymap, ek = cannakeymap + NCANNAKEYMAP ; pk < ek ; pk++) { if (c == pk->cannakey) { keys++; keys->keysym = pk->keysym; keys->modifiers = keys->modifiermask = pk->modifier; } } } else if (c <= '~') { keys->keysym = XK_space + (c - (unsigned char)' '); keys->modifiers = keys->modifiermask = 0; } else if (c == 0x7f) { keys->keysym = XK_Delete; keys->modifiers = keys->modifiermask = 0; } else if ((unsigned char)0xa1 <= c && c <= (unsigned char)0xdf) { keys->keysym = XK_kana_fullstop + (c - (unsigned char)0xa1); keys->modifiers = keys->modifiermask = pk->modifier; } else { keys--; for (pk = cannakeymap, ek = cannakeymap + NCANNAKEYMAP ; pk < ek ; pk++) { if (c == pk->cannakey) { keys++; keys->keysym = pk->keysym; keys->modifiers = keys->modifiermask = pk->modifier; } } } } return n; } return 0; } /* ARGSUSED */ static int PreeditString(w, segn, offset, encoding, format, length, string) Widget w; int segn; int offset; Atom *encoding; int *format; int *length; XtPointer *string; { CannaObject obj = (CannaObject)w; iBuf *ib = obj->canna.ibuf; int i; wchar *wbuf, *wp; int len, wlen; extern int convJWStoCT(); if (ib == NULL) return -1; if (segn < ib->nseg && offset >= ib->len[segn]) { /* $B%;%0%a%s%H$N:G8e(B */ ++segn; offset = 0; } if (segn >= ib->nseg || offset >= ib->len[segn]) { /* $B:o=|$5$l$?(B */ *encoding = XA_COMPOUND_TEXT(XtDisplayOfObject(w)); *format = 8; *length = 0; *string = (XtPointer)XtMalloc(1); return 0; } wlen = 0; for (i = segn; i < ib->nseg; i++) { wlen += ib->len[i]; } wlen -= offset; wp = wbuf = (wchar *)XtMalloc((wlen + 1) * sizeof(wchar)); len = ib->len[segn] - offset; (void)bcopy((char *)(ib->str[segn] + offset), (char *)wp, sizeof(wchar) * len); wp += len; for (i = segn + 1; i < ib->nseg; i++) { len = ib->len[i]; (void)bcopy((char *)ib->str[i], (char *)wp, sizeof(wchar) * len); wp += len; } wbuf[wlen] = 0; /* * Canna $B%*%V%8%'%/%H$O(B COMPOUND_TEXT $B%(%s%3!<%G%#%s%0$7$+%5%]!<%H$7$J$$(B * COMPOUND_TEXT $B$KJQ49$9$k(B */ *encoding = XA_COMPOUND_TEXT(XtDisplayOfObject(w)); *format = 8; /* COMPOUND_TEXT $B$O(B \r $B$,Aw$l$J$$$N$G(B \n $B$KJQ49$7$F$*$/(B */ for (wp = wbuf; *wp != 0; wp++) { if (*wp == '\r') *wp = '\n'; } *length = len = convJWStoCT(wbuf, (unsigned char *)NULL, 0); *string = (XtPointer)XtMalloc(len + 1); (void)convJWStoCT(wbuf, (unsigned char *)*string, 0); /* wbuf $B$r(B free $B$7$F$*$/(B */ XtFree((char *)wbuf); return 0; } /* ARGSUSED */ static int StatusString(w, encoding, format, length, string, nchars) Widget w; Atom *encoding; int *format; int *length; XtPointer *string; int *nchars; { ICString *seg; wchar *wbuf, *wp; int len, wlen; extern int convJWStoCT(); seg = GetMode(w); if (seg == NULL) { *length = *nchars = 0; return -1; } wlen = seg->nchars; if (wlen <= 0) { *length = *nchars = 0; return -1; } /* * data $B$KF~$C$F$$$kJQ49%F%-%9%H$O(B null $B%?!<%_%M!<%H$5$l$F$$$J$$$+$b(B * $B$7$l$J$$$N$G!"$^$:%3%T!<$7$F(B null $B%?!<%_%M!<%H$9$k(B */ wbuf = (wchar *)XtMalloc((wlen + 1) * sizeof(wchar)); (void)bcopy(seg->data, (char *)wbuf, sizeof(wchar) * wlen); wbuf[wlen] = 0; /* * Canna $B%*%V%8%'%/%H$O(B COMPOUND_TEXT $B%(%s%3!<%G%#%s%0$7$+%5%]!<%H$7$J$$(B * COMPOUND_TEXT $B$KJQ49$9$k(B */ *encoding = XA_COMPOUND_TEXT(XtDisplayOfObject(w)); *format = 8; /* COMPOUND_TEXT $B$O(B \r $B$,Aw$l$J$$$N$G(B \n $B$KJQ49$7$F$*$/(B */ for (wp = wbuf; *wp != 0; wp++) { if (*wp == '\r') *wp = '\n'; } *length = len = convJWStoCT(wbuf, (unsigned char *)NULL, 0); *string = XtMalloc(len + 1); (void)convJWStoCT(wbuf, (unsigned char *)*string, 0); *nchars = seg->nchars; /* wbuf $B$r(B free $B$7$F$*$/(B */ XtFree((char *)wbuf); return 0; }