Mercurial > kinput2.yaz
view lib/Ruby.c @ 16:598fcbe482b5
imported patch 19_kinput2-v3.1-ruby.patch
author | Yoshiki Yazawa <yaz@honeyplanet.jp> |
---|---|
date | Mon, 08 Mar 2010 20:38:17 +0900 |
parents | |
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) */ /* Copyright 2003 Hiroyuki Komatsu <komatsu@taiyaki.org> (Ruby.c) */ /* 直さなければならないところ ・Destroy が呼ばれないので CloseUIContext できない。 ・モード領域の大きさ。(これは他のファイルだろうな) */ #ifndef lint static char *rcsid = "$Id: Ruby.c,v 1.2 2003/06/10 02:11:23 komatsu 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 "RubyP.h" #include "DebugPrint.h" #define wchar_t wchar #include "ruby-c.h" static XtResource resources[] = { #define offset(field) XtOffset(RubyObject, ruby.field) { XtNrubyhost, XtCRubyhost, XtRString, sizeof(String), offset(rubyhost), XtRString, NULL }, { XtNrubyfile, XtCRubyfile, XtRString, sizeof(String), offset(rubyfile), 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 int GetTriggerKeys(); static int PreeditString(); static int StatusString(); static void convend(); #if 1 /* KC_SETLISTCALLBACK */ static void openSelection(); #define SELECTION_SET 0 /* SelectionStart をしても良いと言う情報を設定する */ #define SELECTION_DO 1 /* 実際に SelectionStart を開始する */ #else /* !KC_SETLISTCALLBACK */ #define openSelection(x, y, z) #endif /* !KC_SETLISTCALLBACK */ static ICString *GetAuxSegments(); RubyClassRec rubyClassRec = { { /* object fields */ /* superclass */ (WidgetClass) &inputConvClassRec, /* class_name */ "Ruby", /* widget_size */ sizeof(RubyRec), /* 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, }, { /* ruby fields */ /* foo */ 0, } }; WidgetClass rubyObjectClass = (WidgetClass)&rubyClassRec; static void fix(); static ICString *SymbolList; static int NumSymbols; static void addObject(); static void deleteObject(); static Display *displaybell = (Display *)0; static void rubyEUCtoICString(); static void rubyEUCArraytoICStringArray(); static void rubySelectionEvent(); static void rubySelectionDisplay(); static void rubyDialogDisplay(); static void rubyDisplayPreEdit(); typedef struct { ICString *array; int length; } ICStringArray; static ICString *ruby_tmp_seg; static ICStringArray *ruby_cand_list; static void ClassInitialize() { ruby_init(); ruby_tmp_seg = XtMalloc(sizeof(ICString)); ruby_tmp_seg->nchars = 0; ruby_tmp_seg->nbytes = 0; ruby_cand_list = XtMalloc(sizeof(ICStringArray)); ruby_cand_list->length = 0; ruby_eval("$LOAD_PATH.concat(eval(`ruby -e 'p $LOAD_PATH'`))"); ruby_eval("$LOAD_PATH.uniq!"); if (ruby_eval("ENV['KINPUT2_RUBY']") != Qnil) { ruby_eval("require ENV['KINPUT2_RUBY']"); } else { ruby_eval("require 'kinput2_default'"); } if (ruby_eval("global_variables.member?('$kanjiConv')") == Qfalse) { fprintf(stderr, "Abort: KanjiConv was not initialized.\n"); exit (-1); } ruby_eval("kanjiConv = $kanjiConv"); TRACE(("RubyObjectClass initialized\n")); } static int InputEvent(w, event) Widget w; XEvent *event; { RubyObject obj = (RubyObject)w; char key_buf[200]; KeySym keysym; int len, nbytes, functionalChar; /* KeyPress以外は捨てる */ if (event->type != KeyPress /*&& event->type != KeyRelease*/) return 0; /* 取りあえず文字に直してしまう */ key_buf[0] = '\0'; key_buf[1] = '\0'; key_buf[2] = '\0'; nbytes = XLookupString(event, key_buf, 20, &keysym, NULL); if (keysym == XK_space && (event->xkey.state & ShiftMask)) { convend(obj); return 0; } /* ベルを鳴らすディスプレイの設定 */ displaybell = XtDisplayOfObject((Widget)obj); /* かな漢字変換する */ { VALUE pass; printf ("key_buf: `%d'\n", key_buf[0]); printf ("strlen(key_buf): `%d'\n", strlen(key_buf)); printf ("nbytes: `%d'\n", nbytes); pass = ruby_evalf ("kanjiConv.inputEvent(%d, %d, %d)", key_buf[0], (int)keysym, (int)(event->xkey.state)); printf ("Input: done\n"); rubyDisplayPreEdit(obj); return NUM2INT(pass); /* 1: pass the key / 0: trap the key */ } } static void rubyDialogDisplay(obj) RubyObject obj; { ICAuxControlArg arg; /* I'm not sure about Aux. */ if (ruby_eval("kanjiConv.dialog.visible") == Qfalse) { if (ruby_eval("kanjiConv.dialog.call_open") == Qtrue && ruby_eval ("kanjiConv.dialog.text.length > 0") == Qtrue) { printf ("Dialog: open\n"); arg.command = ICAuxStart; XtCallCallbackList((Widget)obj, obj->inputConv.auxcallback, (XtPointer)&arg); ruby_eval("kanjiConv.dialog.open_end"); } } else { /* value_dialog_visible == true */ if (ruby_eval("kanjiConv.dialog.call_close") == Qtrue) { printf ("Dialog: close\n"); arg.command = ICAuxEnd; XtCallCallbackList((Widget)obj, obj->inputConv.auxcallback, (XtPointer)&arg); ruby_eval("kanjiConv.dialog.close_end"); printf ("Dialog: close...done\n"); } else { arg.command = ICAuxChange; XtCallCallbackList((Widget)obj, obj->inputConv.auxcallback, (XtPointer)&arg); } } } static void rubySelectionEvent(obj) RubyObject obj; { /*** Right ***/ if (ruby_eval("kanjiConv.selection.call_right") == Qtrue) { moveSelection(obj, ICMoveRight); ruby_eval("kanjiConv.selection.right_end"); } /*** Left ***/ if (ruby_eval("kanjiConv.selection.call_left") == Qtrue) { moveSelection(obj, ICMoveLeft); ruby_eval("kanjiConv.selection.left_end"); } /*** Down ***/ if (ruby_eval("kanjiConv.selection.call_down") == Qtrue) { moveSelection(obj, ICMoveDown); ruby_eval("kanjiConv.selection.down_end"); } /*** Up ***/ if (ruby_eval("kanjiConv.selection.call_up") == Qtrue) { moveSelection(obj, ICMoveUp); ruby_eval("kanjiConv.selection.up_end"); } /*** Beginning Line ***/ if (ruby_eval("kanjiConv.selection.call_line_beginning") == Qtrue) { moveSelection(obj, ICMoveLeftMost); ruby_eval("kanjiConv.selection.line_beginning_end"); } /*** End Line ***/ if (ruby_eval("kanjiConv.selection.call_line_end") == Qtrue) { moveSelection(obj, ICMoveRightMost); ruby_eval("kanjiConv.selection.line_end_end"); } /*** Get Index ***/ { ICSelectionControlArg arg; arg.command = ICSelectionGet; arg.u.current_item = -1; XtCallCallbackList((Widget)obj, obj->inputConv.selectioncallback, (XtPointer)&arg); if (arg.u.current_item >= 0) { ruby_evalf ("kanjiConv.set_cand_index (%d)", arg.u.current_item); } } } static void moveSelection(obj, dir) RubyObject obj; int dir; { ICSelectionControlArg arg; arg.command = ICSelectionMove; arg.u.dir = dir; XtCallCallbackList((Widget)obj, obj->inputConv.selectioncallback, (XtPointer)&arg); } static void rubySelectionDisplay(obj) RubyObject obj; { ICSelectionControlArg arg; if (ruby_eval("kanjiConv.selection.call_open") == Qtrue) { printf ("Selection: open\n"); 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 = 0; /* INDEX of ITEM */ XtCallCallbackList((Widget)obj, obj->inputConv.selectioncallback, (XtPointer)&arg); ruby_eval("kanjiConv.selection.open_end"); } else if (ruby_eval("kanjiConv.selection.call_close") == Qtrue) { printf ("Selection: close\n"); arg.command = ICSelectionEnd; arg.u.current_item = -1; XtCallCallbackList((Widget)obj, obj->inputConv.selectioncallback, (XtPointer)&arg); ruby_eval("kanjiConv.selection.close_end"); } } static void rubyDisplayPreEdit(obj) RubyObject obj; { Widget w = (Widget)obj; if (ruby_eval("kanjiConv.call_fix") == Qtrue) { fix(obj); } /* 入力モードをチェックする */ /* #if 0 */ /* if (ks->info & KanjiModeInfo) { */ /* printf("modechangecallback\n"); */ XtCallCallbackList(w, obj->inputConv.modechangecallback, (XtPointer)NULL); /* } */ /* #endif */ rubyDialogDisplay(obj); rubySelectionEvent(obj); rubySelectionDisplay(obj); XtCallCallbackList(w, obj->inputConv.textchangecallback, (XtPointer)NULL); } static ICString * GetMode(w) Widget w; { rubyEUCtoICString (ruby_eval ("kanjiConv.modeline"), ruby_tmp_seg); ruby_tmp_seg->attr = ICAttrNormalString; return ruby_tmp_seg; } static int CursorPos(w, nsegp, ncharp) Widget w; Cardinal *nsegp; Cardinal *ncharp; { /* return value : =0 corsor ON / =1 OFF nseg: >0 segment index / =0 no segment nchar: number of chars; 'テs' == 2 */ *ncharp = NUM2INT(ruby_eval("kanjiConv.input.cursor")); *nsegp = 0; /* printf ("CursorPos: nseg=%d, nchar=%d\n", (int)*nsegp, (int)*ncharp); */ return (*ncharp == 0) ? 1: 0; } static int NumSegments(w) Widget w; { int num; printf ("NumSegments\n"); num = NUM2INT(ruby_eval("kanjiConv.segment_length")); /* printf ("NumSegments: num=%d\n", num); */ return num; } static ICString * GetSegment(w, n) Widget w; Cardinal n; { RubyObject obj = (RubyObject)w; static ICString seg; printf("GetSegment\n"); rubyEUCtoICString (ruby_evalf ("kanjiConv.segment_word(%d)", n), ruby_tmp_seg); if (ruby_evalf("kanjiConv.segment_status(%d) == :highlight", n) == Qtrue) { ruby_tmp_seg->attr = ICAttrConverted | ICAttrCurrentSegment; } else { ruby_tmp_seg->attr = ICAttrNotConverted; } /* ICAttrConverted | ICAttrCurrentSegment : Inversion. */ /* |= ICAttrChanged : Non-Underline. */ return ruby_tmp_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; printf("CompareSegment\n"); 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; { RubyObject obj = (RubyObject)w; printf("GetItemList\n"); rubyEUCArraytoICStringArray(ruby_eval("kanjiConv.cand_list"), ruby_cand_list); *n = ruby_cand_list->length; return ruby_cand_list->array; } static int SelectItem(w, n) Widget w; int n; { RubyObject obj = (RubyObject)w; printf ("selectItem\n"); ruby_evalf("kanjiConv.selection_fix (%d)", n); /* FIXME: Create new fix function in the feature. */ fix (obj); XtCallCallbackList(w, obj->inputConv.textchangecallback, (XtPointer)NULL); return 0; } static int ConvertedString(w, encoding, format, length, string) Widget w; Atom *encoding; int *format; int *length; XtPointer *string; { RubyObject obj = (RubyObject)w; wchar *wbuf, *wp; int len, wlen; extern int convJWStoCT(); /* メモリの解放は自動的に行われる. str を直接書き換えてはいけない. */ unsigned char *str = STR2CSTR(ruby_eval("kanjiConv.value_fixed")); printf("ConvertedString\n"); wbuf = XtMalloc((strlen(str) + 1) * sizeof(wchar)); euc2wcs(str, strlen(str), wbuf); wlen = wstrlen(wbuf); /* * Ruby オブジェクトは COMPOUND_TEXT エンコーディングしかサポートしない * COMPOUND_TEXT に変換する */ *encoding = XA_COMPOUND_TEXT(XtDisplayOfObject((Widget)obj)); *format = 8; /* COMPOUND_TEXT は \r が送れないので \n に変換しておく */ 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); XtFree(wbuf); return 0; } static int ClearConversion(w) Widget w; { ruby_eval ("kanjiConv.clear"); return 0; } static ICString * GetAuxSegments(w, n, ns, nc) Widget w; Cardinal *n, *ns, *nc; { /* I'm not sure about this function's purpose. */ /* n => ngseg ; number of segments (1 <= n <= 3). */ /* ns => nseg ; index of reversed segment (0 or 1). */ /* nc => nchar ; length of current segment??? */ printf ("GetAuxSegments\n"); if ((ruby_eval ("kanjiConv.dialog.visible") == Qtrue || ruby_eval ("kanjiConv.dialog.call_open") == Qtrue) && ruby_eval ("kanjiConv.dialog.text.length > 0") == Qtrue) { if (n) { *n = 1; } if (ns) { *ns = 0; } rubyEUCtoICString (ruby_eval ("kanjiConv.dialog.text"), ruby_tmp_seg); ruby_tmp_seg->attr = ICAttrConverted; if (nc) { *nc = ruby_tmp_seg->nchars; } return ruby_tmp_seg; } else { if (n) { *n = 0; } if (ns) { *ns = 0; } if (nc) { *nc = 0; } return NULL; } } /* ARGSUSED */ static void Initialize(req, new, args, num_args) Widget req; Widget new; ArgList args; Cardinal *num_args; { RubyObject obj = (RubyObject)new; obj->ruby.selectionending = False; obj->ruby.textchanged = False; obj->ruby.symbollist = SymbolList; obj->ruby.numsymbols = NumSymbols; obj->ruby.cursymbol = 0; obj->ruby.candlist = NULL; obj->ruby.candlistsize = 0; obj->ruby.numcand = 0; obj->ruby.lastTextLengthIsZero = False; addObject(obj); } static int bell() { if (displaybell) { XBell(displaybell, 0); } return 0; } static int nRubyContexts = 0; static void Destroy(w) Widget w; { RubyObject obj = (RubyObject)w; wchar buf[512]; int i; if (obj->ruby.candlist) { for (i = 0 ; i < obj->ruby.candlistsize ; i++) { if ((obj->ruby.candlist + i)->data) { XtFree((obj->ruby.candlist + i)->data); } } XtFree((char *)obj->ruby.candlist); } /* Ruby 用終了処理をここに書く */ deleteObject(obj); } static Boolean SetValues(cur, req, wid, args, num_args) Widget cur; Widget req; Widget wid; ArgList args; Cardinal *num_args; /* ARGSUSED */ { RubyObject old = (RubyObject)cur; RubyObject new = (RubyObject)wid; return False; } static void fix(obj) RubyObject obj; { /* 確定の処理 */ XtCallCallbackList((Widget)obj, obj->inputConv.fixcallback, (XtPointer)NULL); ruby_eval("kanjiConv.fix_end"); } static void convend(obj) RubyObject obj; { XtCallCallbackList((Widget)obj, obj->inputConv.endcallback, (XtPointer)NULL); ruby_eval("kanjiConv.reset"); } /* * keeping list of objects */ typedef struct _oblist_ { RubyObject obj; struct _oblist_ *next; } ObjRec; static ObjRec *ObjList = NULL; static void addObject(obj) RubyObject obj; { ObjRec *objp = XtNew(ObjRec); objp->obj = obj; objp->next = ObjList; ObjList = objp; } static void deleteObject(obj) RubyObject 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; } } } /* ARGSUSED */ static int GetTriggerKeys(w, keys_return) Widget w; ICTriggerKey **keys_return; { /* 何をする関数なのか不明 (komatsu) */ *keys_return = NULL; return 0; } /* ARGSUSED */ /* * int ICGetPreeditString(Widget object, int segn, int offset, * Atom *encoding, int *format, * int *length, XtPointer *string) * 変換途中の segn 番目の セグメントの offset 文字からのテキストを * string に返す * encoding には、テキストのエンコーディングを指定しておく * ただしこれは単なるリクエストであって、変換オブジェクトは * 別のエンコーディングで返してもよい * encoding には実際のエンコーディングが返される * 変換オブジェクトは少なくとも COMPOUND_TEXT エンコーディングは * サポートしなくてはならない * format には 8/16/32 のいずれか、length は string のエレメント数が * それぞれ返される * テキストの領域は malloc されているのでこの関数を呼んだ側で * free しなければならない * 変換テキストがない時やエラーの場合には -1、そうでなければ 0 が * 関数の値として返される */ /* まだ, 未検討 (komatsu) */ static int PreeditString(w, segn, offset, encoding, format, length, string) Widget w; int segn; int offset; Atom *encoding; int *format; int *length; XtPointer *string; { RubyObject obj = (RubyObject)w; return -1; } /* 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(); printf("StatusString\n"); seg = GetMode(w); if (seg == NULL) { *length = *nchars = 0; return -1; } wlen = seg->nchars; if (wlen <= 0) { *length = *nchars = 0; return -1; } /* * data に入っている変換テキストは null ターミネートされていないかも * しれないので、まずコピーして null ターミネートする */ wbuf = (wchar *)XtMalloc((wlen + 1) * sizeof(wchar)); (void)bcopy(seg->data, (char *)wbuf, sizeof(wchar) * wlen); wbuf[wlen] = 0; /* * Ruby オブジェクトは COMPOUND_TEXT エンコーディングしかサポートしない * COMPOUND_TEXT に変換する */ *encoding = XA_COMPOUND_TEXT(XtDisplayOfObject(w)); *format = 8; /* COMPOUND_TEXT は \r が送れないので \n に変換しておく */ 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 を free しておく */ XtFree((char *)wbuf); return 0; } /*** ic_str->nbytes が 0 の場合 ic_str->data は自動的に確保 (XtMalloc) される. 0 以外の場合 ic_str->data は (XtRealloc) される. */ static void rubyEUCtoICString(ruby_str, ic_str) VALUE ruby_str; ICString *ic_str; { unsigned char *euc_str; int euc_len; wchar *wc_str; /* printf("String_Len: %d\n", RSTRING(ruby_str)->len); */ euc_str = STR2CSTR(ruby_str); euc_len = strlen(euc_str); if (ic_str->nbytes == 0) { wc_str = (wchar *)XtMalloc((euc_len + 1) * sizeof(wchar)); } else { wc_str = (wchar *)XtRealloc(ic_str->data, (euc_len + 1) * sizeof(wchar)); } euc2wcs(euc_str, euc_len, wc_str); ic_str->data = (char *)wc_str; ic_str->nchars = wstrlen(wc_str); ic_str->nbytes = (euc_len + 1) * sizeof(wchar); ic_str->attr = ICAttrNotConverted; } static void rubyEUCArraytoICStringArray(ruby_str_ary, ic_str_ary) VALUE ruby_str_ary; ICStringArray *ic_str_ary; { VALUE ruby_str; int i, array_length; ICString ic_str; array_length = RARRAY(ruby_str_ary)->len; if ((ic_str_ary->length) < array_length) { ic_str_ary->array = (ICString *)XtRealloc((char *)ic_str_ary->array, array_length * sizeof(ICString)); for (i = ic_str_ary->length; i < array_length; i++) { /* ic_str_ary->array[i] = (ICString *)XtMalloc(1 * sizeof(ICString)); */ ic_str_ary->array[i].nbytes = 0; } } ic_str_ary->length = array_length; /* printf("array_length: %d\n", array_length); */ for (i = 0; i < array_length; i++) { rubyEUCtoICString(rb_ary_entry(ruby_str_ary, i), &(ic_str_ary->array[i])); } }