Index: w3m/.cvsignore
diff -c w3m/.cvsignore:1.1.1.4 w3m/.cvsignore:1.1.1.1.2.4
*** w3m/.cvsignore:1.1.1.4	Sat Nov  1 21:02:44 2003
--- w3m/.cvsignore	Sat Nov  1 23:45:31 2003
***************
*** 22,25 ****
--- 22,27 ----
  w3mhelp-lynx_ja.html
  w3mhelp-w3m_en.html
  w3mhelp-w3m_ja.html
+ configure
+ aclocal.m4
  posubst
Index: w3m/Makefile.in
diff -c w3m/Makefile.in:1.1.1.2 w3m/Makefile.in:1.2.2.2
*** w3m/Makefile.in:1.1.1.2	Sat Nov  1 21:02:58 2003
--- w3m/Makefile.in	Sat Nov  1 23:45:31 2003
***************
*** 92,101 ****
  	func.o cookie.o history.o backend.o $(KEYBIND_OBJ)
  LSRCS=anchor.c parsetagx.c tagtable.c istream.c
  LOBJS=anchor.o parsetagx.o tagtable.o istream.o
  LLOBJS=version.o
  ALIBOBJS=Str.o indep.o regex.o textlist.o parsetag.o myctype.o hash.o
  ALIB=libindep.a
! ALLOBJS=$(OBJS) $(LOBJS) $(LLOBJS)
  
  EXT=@EXEEXT@
  
--- 92,104 ----
  	func.o cookie.o history.o backend.o $(KEYBIND_OBJ)
  LSRCS=anchor.c parsetagx.c tagtable.c istream.c
  LOBJS=anchor.o parsetagx.o tagtable.o istream.o
+ IMSRCS=im.c canna.c
+ IMOBJS=im.o canna.o
  LLOBJS=version.o
  ALIBOBJS=Str.o indep.o regex.o textlist.o parsetag.o myctype.o hash.o
  ALIB=libindep.a
! ALLOBJS=$(OBJS) $(LOBJS) $(IMOBJS) $(LLOBJS)
! IMGOBJS=@IMGOBJS@
  
  EXT=@EXEEXT@
  
Index: w3m/acinclude.m4
diff -c w3m/acinclude.m4:1.1.1.2 w3m/acinclude.m4:1.2.2.2
*** w3m/acinclude.m4:1.1.1.2	Sat Nov  1 21:02:45 2003
--- w3m/acinclude.m4	Sat Nov  1 23:45:31 2003
***************
*** 841,843 ****
--- 841,884 ----
   else
    AC_DEFINE(SIGNAL_RETURN,return 0)
   fi])
+ #
+ # ----------------------------------------------------------------
+ # AC_W3M_CANNA
+ # ----------------------------------------------------------------
+ AC_DEFUN([AC_W3M_INPUT_METHOD],
+ [AC_SUBST(USE_INPUT_METHOD)
+ AC_SUBST(USE_CANNA)
+ AC_MSG_CHECKING(if input methods are enabled)
+ AC_ARG_ENABLE(input-method,
+  [  --enable-input-method		support input methods],,
+  [enable_input_method="yes"])
+ AC_MSG_RESULT($enable_input_method)
+ if test x"$enable_input_method" != xno; then
+   AC_DEFINE(USE_INPUT_METHOD)
+   AC_MSG_CHECKING(if canna is supported)
+   AC_ARG_WITH(canna,
+     [  --with-canna[=PREFIX]		support canna],,
+     [with_canna="yes"])
+   AC_MSG_RESULT($with_canna)
+   if test x"$with_canna" != xno; then
+     AC_DEFINE(USE_CANNA)
+     AC_MSG_CHECKING(for canna library/header)
+     test x"$with_canna" = xyes && with_canna="/usr/local/canna /usr/local /usr /opt/NSUG /usr/pkg"
+     AC_MSG_RESULT($with_canna)
+     for dir in $with_canna
+     do
+        if test -f "$dir/include/canna/jrkanji.h"; then
+ 	  if test "$dir" != "/usr"; then
+ 	     CANNA_CFLAGS="$CANNA_CFLAGS -I$dir/include"
+ 	  fi
+        fi
+        if test "$dir" != "/usr" -a -f "$dir/lib/libcanna.a"; then
+ 	  CANNA_LIBS="$CANNA_LIBS -L$dir/lib"
+        fi
+     done
+     AC_CHECK_LIB(canna, jrKanjiString,
+ 	  [w3m_canna="found"; CFLAGS="$CFLAGS $CANNA_CFLAGS" W3M_LIBS="$W3M_LIBS $CANNA_LIBS -lcanna"],
+ 	  [w3m_canna="not found"],
+ 	  [$CANNA_LIBS -lcrypto])
+   fi
+ fi])
Index: w3m/canna.c
diff -c /dev/null w3m/canna.c:1.1.2.8
*** /dev/null	Sun Nov  2 11:21:08 2003
--- w3m/canna.c	Sun Nov  2 11:18:48 2003
***************
*** 0 ****
--- 1,197 ----
+ #include "fm.h"
+ #include "local.h"
+ #include "im.h"
+ 
+ #ifdef USE_INPUT_METHOD
+ 
+ #ifdef USE_CANNA
+ #define CANNA_NEW_WCHAR_AWARE
+ #include "canna.h"
+ #include <canna/jrkanji.h>
+ 
+ static Str commitedstr;
+ static int need_echoback;
+ static int modelen;
+ 
+ struct im_preedit_info PreeditInfo;
+ static jrKanjiStatusWithValue *ksvnew(int bufsize);
+ static Str canna_conv_n(unsigned char *p, int len);
+ static void canna_warn(char **warnings);
+ static int isnullstr(char *str);
+ 
+ int
+ init_canna(void)
+ {
+     int result;
+     char **warnings;
+     if (!isnullstr(canna_initfile))
+ 	jrKanjiControl(0, KC_SETINITFILENAME, canna_initfile);
+     if (!isnullstr(canna_server))
+ 	jrKanjiControl(0, KC_SETSERVERNAME, canna_server);
+     result = jrKanjiControl(0, KC_INITIALIZE, (char *)&warnings);
+     if (result)
+ 	return FALSE;
+     if (!WcOption.use_jisx0201k)
+ 	jrKanjiControl(0, KC_INHIBITHANKAKUKANA, (char *)1);
+     modelen = jrKanjiControl(0, KC_QUERYMAXMODESTR, NULL);
+ 
+     commitedstr = Strnew();
+     need_echoback = FALSE;
+     PreeditInfo.has_echo = FALSE;
+     PreeditInfo.modestr = NULL;
+     PreeditInfo.has_gline = FALSE;
+     canna_warn(warnings);
+     return TRUE;
+ }
+ 
+ void
+ finalize_canna(void)
+ {
+     char **warnings;
+     jrKanjiControl(0, KC_FINALIZE, (char *)&warnings);
+     canna_warn(warnings);
+ }
+ 
+ void
+ cannaSetWidth(int width)
+ {
+     int realwidth = (width > modelen) ? (width - modelen) : 0;
+     jrKanjiControl(0, KC_SETWIDTH, (char *)realwidth);
+ }
+ 
+ int
+ cannaExtractChar(int remove)
+ {
+     int ch;
+     if (commitedstr->length == 0)
+ 	return EOF;
+     ch = (int)*(unsigned char *)commitedstr->ptr;
+     if (remove)
+ 	Strdelete(commitedstr, 0, 1);
+     return ch;
+ }
+ 
+ static int
+ canna_getmode(void)
+ {
+     char modech;
+     jrKanjiControl(0, KC_SETMODEINFOSTYLE, (char *)1);
+     jrKanjiControl(0, KC_QUERYMODE, &modech);
+     jrKanjiControl(0, KC_SETMODEINFOSTYLE, (char *)0);
+     return modech - '@';
+ }
+ 
+ #define CONVBUF_SIZE 1024
+ void
+ cannaInput(int ch)
+ {
+     jrKanjiStatusWithValue *ksv;
+     jrKanjiStatus *ks;
+     int ch2;
+     int len;
+     int off;
+ 
+     ksv = ksvnew(CONVBUF_SIZE);
+     ks = ksv->ks;
+ 
+     /*ch2 = (ch == CTRL_J) ? CTRL_M : ch;*/
+     ch2 = ch;
+     len = jrKanjiString(0, ch2, ksv->buffer, ksv->bytes_buffer, ks);
+     if (len == -1) {
+ 	jrKanjiControl(0, KC_KILL, (char *)ks);
+ 	len = 0;
+     }
+     if (ks->info & KanjiThroughInfo)
+ 	Strinsert_char(commitedstr, commitedstr->length, ch);
+     else if (len) {
+ 	Str tmp;
+ 	tmp = Strnew_charp_n(ksv->buffer, len);
+ 	Strcat(commitedstr, wc_Str_conv_strict(
+ 		    tmp, WC_CES_EUC_JP, DisplayCharset));
+     }
+     if (ks->length > 0) {
+ 	off = ks->revPos;
+ 	PreeditInfo.echostr[0] = canna_conv_n(ks->echoStr, off);
+ 	PreeditInfo.echostr[1] = canna_conv_n(ks->echoStr + off, ks->revLen);
+ 	off += ks->revLen;
+ 	PreeditInfo.echostr[2] =
+ 	    canna_conv_n(ks->echoStr + off, ks->length - off);
+ 	PreeditInfo.has_echo = TRUE;
+     }
+     else if (ks->length == 0)
+ 	PreeditInfo.has_echo = FALSE;
+     if (ks->info & KanjiModeInfo) {
+ 	if (canna_getmode() == CANNA_MODE_AlphaMode)
+ 	    PreeditInfo.modestr = NULL;
+ 	else
+ 	    PreeditInfo.modestr = canna_conv_n(ks->mode, strlen(ks->mode));
+     }
+     if (ks->info & KanjiGLineInfo) {
+ 	off = ks->gline.revPos;
+ 	PreeditInfo.glinestr[0] = canna_conv_n(ks->gline.line, off);
+ 	PreeditInfo.glinestr[1] =
+ 	    canna_conv_n(ks->gline.line + off, ks->gline.revLen);
+ 	off += ks->gline.revLen;
+ 	PreeditInfo.glinestr[2] =
+ 	    canna_conv_n(ks->gline.line + off, ks->gline.length - off);
+ 	PreeditInfo.has_gline = TRUE;
+     }
+     else
+ 	PreeditInfo.has_gline = FALSE;
+     if (PreeditInfo.has_echo || PreeditInfo.modestr || PreeditInfo.has_gline)
+ 	need_echoback = TRUE;
+ }
+ 
+ static Str
+ canna_conv_n(unsigned char *p, int len)
+ {
+     return wc_Str_conv_strict(
+ 	    Strnew_charp_n((char *)p, len), WC_CES_EUC_JP, InnerCharset);
+ }
+ 
+ static jrKanjiStatusWithValue *
+ ksvnew(int bufsize)
+ {
+     jrKanjiStatusWithValue *ksv;
+     jrKanjiStatus *ks;
+     unsigned char *buffer;
+ 
+     ksv = GC_malloc(sizeof(jrKanjiStatusWithValue));
+     ks = GC_malloc(sizeof(jrKanjiStatus));
+     buffer = GC_malloc(bufsize);
+     ksv->buffer = buffer;
+     ksv->bytes_buffer = bufsize;
+     ksv->ks = ks;
+     ksv->val = 0;
+     return ksv;
+ }
+ 
+ static void
+ canna_warn(char **warnings)
+ {
+     char **p;
+     if (warnings == NULL)
+ 	return;
+     for (p = warnings; *p; p++)
+ 	disp_message(canna_conv_n(*p, strlen(*p))->ptr, TRUE);
+ }
+ 
+ struct im_preedit_info *
+ cannaGetPreeditInfo(void)
+ {
+     if (need_echoback)
+ 	return &PreeditInfo;
+     return NULL;
+ }
+ 
+ static int
+ isnullstr(char *str)
+ {
+     if (str != NULL)
+ 	if (strlen(str) != 0)
+ 	    return FALSE;
+     return TRUE;
+ }
+ 
+ #endif				/* USE_CANNA */
+ #endif				/* USE_INPUT_METHOD */
Index: w3m/canna.h
diff -c /dev/null w3m/canna.h:1.1.2.3
*** /dev/null	Sun Nov  2 11:21:08 2003
--- w3m/canna.h	Sat Nov  1 23:45:31 2003
***************
*** 0 ****
--- 1,17 ----
+ #ifndef CANNA_H
+ #define CANNA_H
+ 
+ #ifdef USE_INPUT_METHOD
+ #ifdef USE_CANNA
+ #ifndef USE_M17N
+ # error "Canna IM requires M17N support"
+ #endif
+ extern int init_canna(void);
+ extern void finalize_canna(void);
+ extern void cannaInput(int ch);
+ extern int cannaExtractChar(int remove);
+ extern struct im_preedit_info *cannaGetPreeditInfo(void);
+ extern void cannaSetWidth(int width);
+ #endif				/* USE_CANNA */
+ #endif				/* USE_INPUT_METHOD */
+ #endif				/* CANNA_H */
Index: w3m/config.h.in
diff -c w3m/config.h.in:1.1.1.2 w3m/config.h.in:1.2.2.2
*** w3m/config.h.in:1.1.1.2	Sat Nov  1 21:02:49 2003
--- w3m/config.h.in	Sat Nov  1 23:45:31 2003
***************
*** 76,81 ****
--- 76,83 ----
  #undef USE_XFACE
  #undef USE_DICT
  #undef USE_HISTORY
+ #undef USE_INPUT_METHOD
+ #undef USE_CANNA
  #undef FORMAT_NICE
  #define ID_EXT
  #undef CLEAR_BUF
Index: w3m/configure.in
diff -c w3m/configure.in:1.1.1.2 w3m/configure.in:1.2.2.2
*** w3m/configure.in:1.1.1.2	Sat Nov  1 21:02:50 2003
--- w3m/configure.in	Sat Nov  1 23:45:31 2003
***************
*** 148,153 ****
--- 148,154 ----
  AC_W3M_SYS_ERRLIST
  AC_W3M_SIGSETJMP
  AC_W3M_SIGNAL
+ AC_W3M_INPUT_METHOD
  
  AC_SUBST(HELP_DIR)
  HELP_DIR="$datadir/$PACKAGE"
Index: w3m/fm.h
diff -c w3m/fm.h:1.1.1.13 w3m/fm.h:1.2.2.14
*** w3m/fm.h:1.1.1.13	Sat Nov  1 21:02:54 2003
--- w3m/fm.h	Sat Nov  1 23:45:32 2003
***************
*** 987,992 ****
--- 987,1001 ----
  global int migemo_active init(0);
  global char *migemo_command init(DEF_MIGEMO_COMMAND);
  #endif				/* USE_MIGEMO */
+ #ifdef USE_INPUT_METHOD
+ #define IM_NONE			0
+ #define IM_CANNA		1
+ global int im_type init(IM_NONE);
+ #ifdef USE_CANNA
+ global char *canna_server init(NULL);
+ global char *canna_initfile init(NULL);
+ #endif				/* USE_CANNA */
+ #endif				/* USE_INPUT_METHOD */
  
  global struct auth_cookie *Auth_cookie init(NULL);
  #ifdef USE_COOKIE
Index: w3m/im.c
diff -c /dev/null w3m/im.c:1.1.2.3
*** /dev/null	Sun Nov  2 11:21:09 2003
--- w3m/im.c	Sat Oct  5 09:22:48 2002
***************
*** 0 ****
--- 1,141 ----
+ #include "fm.h"
+ #include "local.h"
+ #include "im.h"
+ 
+ #ifdef USE_INPUT_METHOD
+ 
+ #ifdef USE_MOUSE
+ #ifdef USE_GPM
+ #include <gpm.h>
+ #endif
+ #if defined(USE_GPM) || defined(USE_SYSMOUSE)
+ extern int do_getch();
+ #define getch()	do_getch()
+ #endif				/* USE_GPM */
+ #endif				/* USE_MOUSE */
+ 
+ #ifdef USE_CANNA
+ #include "canna.h"
+ #endif
+ static int (*imExtractChar) (int remove);
+ static void (*imInput) (int ch);
+ static void (*imSetWidth) (int width);
+ static struct im_preedit_info *(*imGetPreeditInfo) (void);
+ static void (*imFinalize) (void);
+ 
+ static int need_init = TRUE;
+ static int im_active = FALSE;
+ 
+ void
+ init_input_method_later(void)
+ {
+     need_init = TRUE;
+ }
+ 
+ static void
+ init_input_method(void)
+ {
+     if (im_active)
+ 	finalize_input_method();
+     need_init = FALSE;
+     switch (im_type) {
+     case IM_NONE:
+ 	break;
+ #ifdef USE_CANNA
+     case IM_CANNA:
+ 	if (!init_canna())
+ 	    break;
+ 	imExtractChar = &cannaExtractChar;
+ 	imInput = &cannaInput;
+ 	imSetWidth = &cannaSetWidth;
+ 	imGetPreeditInfo = &cannaGetPreeditInfo;
+ 	imFinalize = &finalize_canna;
+ 	im_active = TRUE;
+ 	break;
+ #endif
+     }
+     im_set_width(COLS);
+ }
+ 
+ void
+ finalize_input_method(void)
+ {
+     if (!im_active)
+ 	return;
+     (*imFinalize) ();
+     im_active = FALSE;
+     need_init = TRUE;
+ }
+ 
+ int
+ im_check_active(void)
+ {
+     if (need_init)
+ 	init_input_method();
+     return im_active;
+ }
+ 
+ int
+ im_getch(imPreeditDrawProc * drawproc, void *arg)
+ {
+     int ch;
+     if (!im_check_active())
+ 	return getch();
+     (*drawproc) ((*imGetPreeditInfo) (), arg);
+     while (1) {
+ 	ch = (*imExtractChar) (TRUE);
+ 	if (ch != EOF)
+ 	    return ch;
+ 	(*imInput) (getch());
+ 	(*drawproc) ((*imGetPreeditInfo) (), arg);
+     }
+ }
+ 
+ void
+ im_set_width(int width)
+ {
+     if (im_check_active())
+ 	(*imSetWidth) (width);
+ }
+ 
+ int
+ im_normal_echoback(struct im_preedit_info *preedit)
+ {
+     if (!preedit || !preedit->has_echo)
+ 	return 0;
+     underline();
+     addstr(preedit->echostr[0]->ptr);
+     underlineend();
+     standout();
+     addstr(preedit->echostr[1]->ptr);
+     standend();
+     underline();
+     addstr(preedit->echostr[2]->ptr);
+     underlineend();
+     return preedit->echostr[0]->length
+ 	+ preedit->echostr[1]->length + preedit->echostr[2]->length;
+ }
+ 
+ int
+ im_normal_modeline(struct im_preedit_info *preedit)
+ {
+     int len = 0;
+     if (!preedit)
+ 	return 0;
+     if (preedit->modestr) {
+ 	addstr(preedit->modestr->ptr);
+ 	len += preedit->modestr->length;
+     }
+     if (preedit->has_gline) {
+ 	addstr(preedit->glinestr[0]->ptr);
+ 	standout();
+ 	addstr(preedit->glinestr[1]->ptr);
+ 	standend();
+ 	addstr(preedit->glinestr[2]->ptr);
+ 	len += preedit->glinestr[0]->length;
+ 	len += preedit->glinestr[1]->length;
+ 	len += preedit->glinestr[2]->length;
+     }
+     return len;
+ }
+ #endif				/* USE_INPUT_METHOD */
Index: w3m/im.h
diff -c /dev/null w3m/im.h:1.1.2.4
*** /dev/null	Sun Nov  2 11:21:09 2003
--- w3m/im.h	Sat Oct  5 11:06:29 2002
***************
*** 0 ****
--- 1,22 ----
+ #ifndef IM_H
+ #define IM_H
+ 
+ #ifdef USE_INPUT_METHOD
+ struct im_preedit_info {
+     Str echostr[3];
+     Str glinestr[3];
+     Str modestr;
+     int has_echo;
+     int has_gline;
+ };
+ typedef void imPreeditDrawProc(struct im_preedit_info *preedit, void *arg);
+ 
+ void init_input_method_later(void);
+ void finalize_input_method(void);
+ int im_getch(imPreeditDrawProc * drawproc, void *arg);
+ void im_set_width(int width);
+ int im_normal_echoback(struct im_preedit_info *preedit);
+ int im_normal_modeline(struct im_preedit_info *preedit);
+ 
+ #endif				/* USE_INPUT_METHOD */
+ #endif				/* IM_H */
Index: w3m/linein.c
diff -c w3m/linein.c:1.1.1.7 w3m/linein.c:1.2.2.11
*** w3m/linein.c:1.1.1.7	Sat Nov  1 21:02:56 2003
--- w3m/linein.c	Sat Nov  1 23:45:32 2003
***************
*** 2,7 ****
--- 2,8 ----
  #include "fm.h"
  #include "local.h"
  #include "myctype.h"
+ #include "im.h"
  
  #ifdef USE_MOUSE
  #ifdef USE_GPM
***************
*** 64,76 ****
  
  static int setStrType(Str str, Lineprop *prop);
  static void addPasswd(char *p, Lineprop *pr, int len, int pos, int limit);
! static void addStr(char *p, Lineprop *pr, int len, int pos, int limit);
  
  static int CPos, CLen, offset;
  static int i_cont, i_broken, i_quote;
  static int cm_mode, cm_next, cm_clear, cm_disp_next, cm_disp_clear;
  static int need_redraw, is_passwd;
  static int move_word;
  
  static Hist *CurrentHist;
  static Str strCurrentBuf;
--- 65,79 ----
  
  static int setStrType(Str str, Lineprop *prop);
  static void addPasswd(char *p, Lineprop *pr, int len, int pos, int limit);
! static void addStr(char *p, Lineprop *pr, int len, int pos, int limit,
! 		   int flag);
  
  static int CPos, CLen, offset;
  static int i_cont, i_broken, i_quote;
  static int cm_mode, cm_next, cm_clear, cm_disp_next, cm_disp_clear;
  static int need_redraw, is_passwd;
  static int move_word;
+ static int moveR_flag;
  
  static Hist *CurrentHist;
  static Str strCurrentBuf;
***************
*** 80,93 ****
  #else
  static void ins_char(char c);
  #endif
  
  char *
  inputLineHistSearch(char *prompt, char *def_str, int flag, Hist *hist,
  		    int (*incrfunc) (int ch, Str str, Lineprop *prop))
  {
!     int opos, x, y, lpos, rpos, epos;
      unsigned char c;
      char *p;
  #ifdef USE_M17N
      Str tmp;
  #endif
--- 83,109 ----
  #else
  static void ins_char(char c);
  #endif
+ #ifdef USE_INPUT_METHOD
+ struct linein_info {
+     char *prompt;
+     int opos;
+     int pos;
+     int need_redraw;
+     int dirty;
+ };
+ static void linein_preedit_cb(struct im_preedit_info *preedit, void *arg);
+ #endif
  
  char *
  inputLineHistSearch(char *prompt, char *def_str, int flag, Hist *hist,
  		    int (*incrfunc) (int ch, Str str, Lineprop *prop))
  {
!     int opos, x, lpos, rpos, epos;
      unsigned char c;
      char *p;
+ #ifdef USE_INPUT_METHOD
+     struct linein_info info;
+ #endif
  #ifdef USE_M17N
      Str tmp;
  #endif
***************
*** 125,130 ****
--- 141,152 ----
      lpos = epos / 3;
      rpos = epos * 2 / 3;
      offset = 0;
+ #ifdef USE_INPUT_METHOD
+     info.prompt = prompt;
+     info.opos = opos;
+     info.need_redraw = FALSE;
+     info.dirty = 0;
+ #endif
  
      if (def_str) {
  	strBuf = Strnew_charp(def_str);
***************
*** 144,180 ****
      cm_next = FALSE;
      cm_disp_next = -1;
      need_redraw = FALSE;
  
  #ifdef USE_M17N
      wc_char_conv_init(wc_guess_8bit_charset(DisplayCharset), InnerCharset);
  #endif
      do {
  	x = calcPosition(strBuf->ptr, strProp, CLen, CPos, 0, CP_FORCE);
! 	if (x - rpos > offset) {
! 	    y = calcPosition(strBuf->ptr, strProp, CLen, CLen, 0, CP_AUTO);
! 	    if (y - epos > x - rpos)
  		offset = x - rpos;
! 	    else if (y - epos > 0)
! 		offset = y - epos;
  	}
! 	else if (x - lpos < offset) {
  	    if (x - lpos > 0)
  		offset = x - lpos;
  	    else
  		offset = 0;
  	}
  	move(LASTLINE, 0);
  	addstr(prompt);
  	if (is_passwd)
  	    addPasswd(strBuf->ptr, strProp, CLen, offset, COLS - opos);
  	else
! 	    addStr(strBuf->ptr, strProp, CLen, offset, COLS - opos);
  	clrtoeolx();
  	move(LASTLINE, opos + x - offset);
  	refresh();
  
        next_char:
! 	c = getch();
  #ifdef __EMX__
  	if (c == 0) {
  	    if (!(c = getcntrl()))
--- 166,220 ----
      cm_next = FALSE;
      cm_disp_next = -1;
      need_redraw = FALSE;
+     moveR_flag = 0;
  
  #ifdef USE_M17N
      wc_char_conv_init(wc_guess_8bit_charset(DisplayCharset), InnerCharset);
  #endif
      do {
  	x = calcPosition(strBuf->ptr, strProp, CLen, CPos, 0, CP_FORCE);
! 	if (moveR_flag == 2) {
! 	    if (x - rpos > offset)
  		offset = x - rpos;
! 	    else if (x - lpos > offset)
! 		offset = x - lpos;
! 	    else if (x - 2 > offset)
! 		offset = x - 2;
! 	}
! 	else if (x - epos > offset) {
! 	    if (moveR_flag == 1)
! 		offset = x - rpos;
! 	    else
! 		offset = x - epos;
  	}
! 	else if (x < offset + 1) {
  	    if (x - lpos > 0)
  		offset = x - lpos;
  	    else
  		offset = 0;
  	}
+ 	moveR_flag = 0;
  	move(LASTLINE, 0);
  	addstr(prompt);
  	if (is_passwd)
  	    addPasswd(strBuf->ptr, strProp, CLen, offset, COLS - opos);
  	else
! 	    addStr(strBuf->ptr, strProp, CLen, offset, COLS - opos, 1);
  	clrtoeolx();
  	move(LASTLINE, opos + x - offset);
  	refresh();
  
        next_char:
! #ifdef USE_INPUT_METHOD
! 	if (!is_passwd) {
! 	    info.pos = opos + x - offset;
! 	    c = im_getch(&linein_preedit_cb, &info);
! 	    if (info.need_redraw)
! 		need_redraw = TRUE;
! 	}
! 	else
! #endif
! 	    c = getch();
  #ifdef __EMX__
  	if (c == 0) {
  	    if (!(c = getcntrl()))
***************
*** 285,290 ****
--- 325,382 ----
  	return allocStr(p, -1);
  }
  
+ #ifdef USE_INPUT_METHOD
+ void
+ linein_preedit_cb(struct im_preedit_info *preedit, void *arg)
+ {
+     struct linein_info *info = arg;
+     int echolen;
+     if (LASTLINE >= 1) {
+ 	if (preedit && (preedit->modestr || preedit->has_gline)) {
+ 	    if (need_redraw) {
+ 		displayBuffer(Currentbuf, B_FORCE_REDRAW);
+ 		need_redraw = FALSE;
+ 		info->dirty = 2;
+ 	    }
+ 	    move(LASTLINE - 1, 0);
+ 	    im_normal_modeline(preedit);
+ 	    clrtoeol();
+ 	    info->need_redraw = TRUE;
+ 	}
+ 	else if (info->need_redraw) {
+ 	    displayBuffer(Currentbuf, B_FORCE_REDRAW);
+ 	    need_redraw = FALSE;
+ 	    info->need_redraw = FALSE;
+ 	    info->dirty = 2;
+ 	}
+     }
+ 
+     if (info->dirty == 2) {
+ 	move(LASTLINE, 0);
+ 	addstr(info->prompt);
+ 	addStr(strBuf->ptr, strProp, CLen, offset, COLS - info->opos, 1);
+ 	clrtoeol();
+ 	info->dirty = 0;
+     }
+ 
+     move(LASTLINE, info->pos);
+     echolen = im_normal_echoback(preedit);
+     if (info->dirty == 1) {
+ 	int col, dummy;
+ 	int newoff;
+ 	get_curpos(&dummy, &col);
+ 	newoff = offset + col - info->opos;
+ 	addStr(strBuf->ptr, strProp, CLen, newoff, COLS - col, 0);
+ 	clrtoeol();
+ 	move(LASTLINE, col);
+ 	info->dirty = 0;
+     }
+     if (echolen > 0)
+ 	info->dirty = 1;
+     refresh();
+ }
+ #endif				/* USE_INPUT_METHOD */
+ 
  #ifdef __EMX__
  static int
  getcntrl(void)
***************
*** 332,338 ****
  }
  
  static void
! addStr(char *p, Lineprop *pr, int len, int offset, int limit)
  {
      int i = 0, rcol = 0, ncol, delta = 1;
  
--- 424,430 ----
  }
  
  static void
! addStr(char *p, Lineprop *pr, int len, int offset, int limit, int flag)
  {
      int i = 0, rcol = 0, ncol, delta = 1;
  
***************
*** 347,354 ****
  	while (pr[i] & PC_WCHAR2)
  	    i++;
  #endif
! 	addChar('{', 0);
! 	rcol = offset + 1;
  	ncol = calcPosition(p, pr, len, i, 0, CP_AUTO);
  	for (; rcol < ncol; rcol++)
  	    addChar(' ', 0);
--- 439,450 ----
  	while (pr[i] & PC_WCHAR2)
  	    i++;
  #endif
! 	if (flag) {
! 	    addChar('{', 0);
! 	    rcol = offset + 1;
! 	}
! 	else
! 	    rcol = offset;
  	ncol = calcPosition(p, pr, len, i, 0, CP_AUTO);
  	for (; rcol < ncol; rcol++)
  	    addChar(' ', 0);
***************
*** 475,480 ****
--- 571,577 ----
  {
      int i;
  
+     moveR_flag = 1;
      Strinsert_char(strBuf, CPos, ' ');
      CLen = strBuf->length;
      for (i = CLen; i > CPos; i--) {
***************
*** 532,537 ****
--- 629,638 ----
  _mvRw(void)
  {
      int first = 1;
+     if (CPos == CLen)
+ 	moveR_flag = 2;
+     else
+ 	moveR_flag = 1;
      while (CPos < CLen && (first || !terminated(strBuf->ptr[CPos - 1]))) {
  	CPos++;
  	first = 0;
***************
*** 547,552 ****
--- 648,657 ----
  static void
  _mvR(void)
  {
+     if (CPos == CLen)
+ 	moveR_flag = 2;
+     else
+ 	moveR_flag = 1;
      if (CPos < CLen)
  	CPos++;
  #ifdef USE_M17N
Index: w3m/main.c
diff -c w3m/main.c:1.1.1.14 w3m/main.c:1.2.2.15
*** w3m/main.c:1.1.1.14	Sat Nov  1 21:02:58 2003
--- w3m/main.c	Sat Nov  1 23:45:32 2003
***************
*** 14,19 ****
--- 14,20 ----
  #include "terms.h"
  #include "myctype.h"
  #include "regex.h"
+ #include "im.h"
  #ifdef USE_MOUSE
  #ifdef USE_GPM
  #include <gpm.h>
***************
*** 170,175 ****
--- 171,182 ----
  #ifdef USE_MIGEMO
  	    ",migemo"
  #endif
+ #ifdef USE_INPUT_METHOD
+ 	    ",input_method"
+ #endif
+ #ifdef USE_CANNA
+ 	    ",canna"
+ #endif
  	);
  }
  
***************
*** 391,396 ****
--- 398,405 ----
      prepare_sys_errlist();
  #endif				/* not HAVE_SYS_ERRLIST */
  
+     srand48(time(0));
+ 
      NO_proxy_domains = newTextList();
      fileToDelete = newTextList();
  
***************
*** 800,805 ****
--- 809,817 ----
  #ifdef SIGPIPE
      mySignal(SIGPIPE, SigPipe);
  #endif
+ #ifdef USE_INPUT_METHOD
+     init_input_method_later();
+ #endif
  
      orig_GC_warn_proc = GC_set_warn_proc(wrap_GC_warn_proc);
      err_msg = Strnew();
***************
*** 1422,1427 ****
--- 1434,1442 ----
  resize_screen(void)
  {
      setlinescols();
+ #ifdef USE_INPUT_METHOD
+     im_set_width(COLS);
+ #endif
      setupscreen();
      if (CurrentTab)
  	displayBuffer(Currentbuf, B_FORCE_REDRAW);
***************
*** 5709,5714 ****
--- 5724,5732 ----
  {
  #ifdef USE_MIGEMO
      init_migemo();		/* close pipe to migemo */
+ #endif
+ #ifdef USE_INPUT_METHOD
+     finalize_input_method();
  #endif
      stopDownload();
      deleteFiles();
Index: w3m/proto.h
diff -c w3m/proto.h:1.1.1.12 w3m/proto.h:1.1.1.1.2.13
*** w3m/proto.h:1.1.1.12	Sat Nov  1 21:03:00 2003
--- w3m/proto.h	Sat Nov  1 23:45:32 2003
***************
*** 488,493 ****
--- 488,494 ----
  extern void toggle_stand(void);
  extern char getch(void);
  extern void bell(void);
+ extern void get_curpos(int *line, int *col);
  extern int sleep_till_anykey(int sec, int purge);
  #ifdef USE_IMAGE
  extern void touch_cursor();
Index: w3m/rc.c
diff -c w3m/rc.c:1.1.1.13 w3m/rc.c:1.2.2.14
*** w3m/rc.c:1.1.1.13	Sat Nov  1 21:03:00 2003
--- w3m/rc.c	Sat Nov  1 23:45:32 2003
***************
*** 9,14 ****
--- 9,15 ----
  #include <errno.h>
  #include "parsetag.h"
  #include "local.h"
+ #include "im.h"
  #include <stdlib.h>
  
  struct param_ptr {
***************
*** 205,210 ****
--- 206,219 ----
  #define CMT_MIGEMO_COMMAND N_("Migemo command")
  #endif				/* USE_MIGEMO */
  
+ #ifdef USE_INPUT_METHOD
+ #define CMT_IM_TYPE N_("input method")
+ #ifdef USE_CANNA
+ #define CMT_CANNA_SERVER N_("cannaserver name")
+ #define CMT_CANNA_INITFILE N_("canna initialization file")
+ #endif				/* USE_CANNA */
+ #endif				/* USE_INPUT_METHOD */
+ 
  #ifdef USE_M17N
  #define CMT_DISPLAY_CHARSET  N_("Display charset")
  #define CMT_DOCUMENT_CHARSET N_("Default document charset")
***************
*** 326,331 ****
--- 335,350 ----
  };
  #endif				/* INET6 */
  
+ #ifdef USE_INPUT_METHOD
+ static struct sel_c im_type_str[] = {
+     {N_S(IM_NONE), "(none)"},
+ #ifdef USE_CANNA
+     {N_S(IM_CANNA), "canna"},
+ #endif				/* USE_CANNA */
+     {0, NULL, NULL}
+ };
+ #endif				/* USE_INPUT_METHOD */
+ 
  #ifdef USE_COOKIE
  static struct sel_c badcookiestr[] = {
      {N_S(ACCEPT_BAD_COOKIE_DISCARD), "discard"},
***************
*** 479,484 ****
--- 498,513 ----
      {"migemo_command", P_STRING, PI_TEXT, (void *)&migemo_command,
       CMT_MIGEMO_COMMAND, NULL},
  #endif				/* USE_MIGEMO */
+ #ifdef USE_INPUT_METHOD
+     {"input_method_type", P_INT, PI_SEL_C, (void *)&im_type,
+      CMT_IM_TYPE, im_type_str},
+ #ifdef USE_CANNA
+     {"canna_server", P_STRING, PI_TEXT, (void *)&canna_server,
+      CMT_CANNA_SERVER, NULL},
+     {"canna_initfile", P_STRING, PI_TEXT, (void *)&canna_initfile,
+      CMT_CANNA_INITFILE, NULL},
+ #endif				/* USE_CANNA */
+ #endif				/* USE_INPUT_METHOD */
  #ifdef USE_MOUSE
      {"use_mouse", P_INT, PI_ONOFF, (void *)&use_mouse, CMT_MOUSE, NULL},
      {"reverse_mouse", P_INT, PI_ONOFF, (void *)&reverse_mouse,
***************
*** 1189,1194 ****
--- 1218,1226 ----
  	initImage();
  #else
      displayImage = FALSE;	/* XXX */
+ #endif
+ #ifdef USE_INPUT_METHOD
+     init_input_method_later();
  #endif
      loadPasswd();
      loadPreForm();
Index: w3m/terms.c
diff -c w3m/terms.c:1.1.1.8 w3m/terms.c:1.1.1.1.2.10
*** w3m/terms.c:1.1.1.8	Sat Nov  1 21:03:02 2003
--- w3m/terms.c	Sat Nov  1 23:45:32 2003
***************
*** 1735,1741 ****
  #define TTY_MODE ISIG|ICANON|ECHO
  #endif				/* not IEXTEN */
  {
!     ttymode_reset(TTY_MODE, IXON | IXOFF);
  #ifdef HAVE_TERMIOS_H
      set_cc(VMIN, 1);
  #else				/* not HAVE_TERMIOS_H */
--- 1735,1741 ----
  #define TTY_MODE ISIG|ICANON|ECHO
  #endif				/* not IEXTEN */
  {
!     ttymode_reset(TTY_MODE, IXON | IXOFF | ICRNL);
  #ifdef HAVE_TERMIOS_H
      set_cc(VMIN, 1);
  #else				/* not HAVE_TERMIOS_H */
***************
*** 2163,2165 ****
--- 2163,2172 ----
  #endif
  }
  #endif
+ 
+ void
+ get_curpos(int *line, int *col)
+ {
+     *line = CurLine;
+     *col = CurColumn;
+ }
Index: w3m/po/ja.po
diff -c w3m/po/ja.po:1.1.1.1 w3m/po/ja.po:1.1.1.1.2.2
*** w3m/po/ja.po:1.1.1.1	Sat Nov  1 21:04:11 2003
--- w3m/po/ja.po	Sun Nov  2 10:18:33 2003
***************
*** 573,578 ****
--- 573,590 ----
  msgid "Migemo command"
  msgstr "Migemo���ޥ��"
  
+ #: rc.c:210
+ msgid "input method"
+ msgstr "���Ѥ���input method"
+ 
+ #: rc.c:212
+ msgid "cannaserver name"
+ msgstr "cannaserver��̾��"
+ 
+ #: rc.c:213
+ msgid "canna initialization file"
+ msgstr "canna�ν�����ե������̾��"
+ 
  #: rc.c:209
  msgid "Display charset"
  msgstr "ɽ����ʸ��������"
Index: w3m/po/w3m.pot
diff -c w3m/po/w3m.pot:1.1.1.1 w3m/po/w3m.pot:1.1.1.1.2.2
*** w3m/po/w3m.pot:1.1.1.1	Sat Nov  1 21:04:11 2003
--- w3m/po/w3m.pot	Sun Nov  2 10:34:08 2003
***************
*** 572,577 ****
--- 572,589 ----
  msgid "Migemo command"
  msgstr ""
  
+ #: rc.c:210
+ msgid "input method"
+ msgstr ""
+ 
+ #: rc.c:212
+ msgid "cannaserver name"
+ msgstr ""
+ 
+ #: rc.c:213
+ msgid "canna initialization file"
+ msgstr ""
+ 
  #: rc.c:209
  msgid "Display charset"
  msgstr ""
