Loading ...
Sorry, an error occurred while loading the content.

581Re: win2k IME, multibyte/width characters, etc. (patch)

Expand Messages
  • Muraoka Taro
    Oct 25, 2001
    • 0 Attachment
      Sorry, I forgot to attach that two files.

      > I had found two problems about Glenn's latest patch for IME.
      >
      > 1. In mbyte.c FEAT_WINDOWS is used for instead of WIN32.
      > It cause touble when compiling on non-windows platform.
      > Check attached ime_fix1.diff.
      > 2. I got report of strange behavior from an user of old IME (it is called SKK).
      > I had checked this problem.
      > SKK send WM_IME_COMPOSITION message when 'k' typed
      > without any composition string.
      > It cause unexpected two white space insertion.
      > I had fixed this.
      > Please check _OnImeComposition() and GetResultStr() in ime_fix2.diff.
      >
      > Regards.
      > ----
      > Muraoka Taro <koron@...>
      >

      ----ime_fix1.diff
      diff -cr src.orig/mbyte.c src/mbyte.c
      *** src.orig/mbyte.c Sun Oct 21 20:30:38 2001
      --- src/mbyte.c Sun Oct 21 20:30:33 2001
      ***************
      *** 572,577 ****
      --- 572,591 ----
      if (enc_utf8 && !option_was_set((char_u *)"fencs"))
      set_string_option_direct((char_u *)"fencs", -1,
      (char_u *)"ucs-bom,utf-8,latin1", OPT_FREE);
      + #ifdef FEAT_MBYTE_IME
      + # ifdef USE_ICONV
      + ime_conv.vc_fd = (iconv_t)-1;
      + # endif
      + convert_setup(&ime_conv, "ucs-2", p_enc);
      + #endif
      +
      + #ifdef FEAT_MBYTE_IME
      + # ifdef USE_ICONV
      + ime_conv_cp.vc_fd = (iconv_t)-1;
      + # endif
      + ime_conv_cp.vc_type = CONV_CODEPAGE;
      + ime_conv_cp.vc_factor = 2; /* we don't really know anything about the codepage */
      + #endif

      #ifdef HAVE_BIND_TEXTDOMAIN_CODESET
      /* GNU gettext 0.10.37 supports this feature: set the codeset used for
      ***************
      *** 3539,3566 ****
      add_to_input_buf(str, 3);
      }

      - /*
      - * Add "str[len]" to the input buffer while escaping CSI bytes.
      - */
      - static void
      - add_to_input_buf_csi(char_u *str, int len)
      - {
      - int i;
      - char_u buf[2];
      -
      - for (i = 0; i < len; ++i)
      - {
      - add_to_input_buf(str + i, 1);
      - if (str[i] == CSI)
      - {
      - /* Turn CSI into K_CSI. */
      - buf[0] = KS_EXTRA;
      - buf[1] = (int)KE_CSI;
      - add_to_input_buf(buf, 2);
      - }
      - }
      - }
      -
      static GSList *key_press_event_queue = NULL;
      static int preedit_buf_len = 0;
      static gboolean processing_queued_event = FALSE;
      --- 3553,3558 ----
      ***************
      *** 3897,3902 ****
      --- 3889,3908 ----
      /* Internal utf-8 -> latin1 conversion. */
      vcp->vc_type = CONV_TO_LATIN1;
      }
      + #ifdef WIN32
      + /* Win32-specific UTF-16 -> DBCS conversion, for the IME,
      + * so we don't need iconv ... */
      + else if((from_prop & ENC_UNICODE) && (from_prop & ENC_2BYTE) && (to_prop & ENC_DBCS))
      + {
      + vcp->vc_type = CONV_DBCS;
      + vcp->vc_factor = 2; /* up to twice as long */
      + vcp->dbcs = atoi(to + 2);
      + } else if((from_prop & ENC_UNICODE) && (from_prop & ENC_2BYTE) && (to_prop & ENC_UNICODE)) {
      + vcp->vc_type = CONV_DBCS;
      + vcp->vc_factor = 2; /* up to twice as long */
      + vcp->dbcs = CP_UTF8;
      + }
      + #endif
      # ifdef USE_ICONV
      else
      {
      ***************
      *** 4023,4029 ****
      --- 4029,4077 ----
      retval = iconv_string(vcp->vc_fd, ptr, len);
      if (retval != NULL && lenp != NULL)
      *lenp = (int)STRLEN(retval);
      + break;
      # endif
      + # ifdef WIN32
      + case CONV_DBCS: /* UTF-16 -> dbcs or UTF8 */
      + {
      + int retlen;
      + if (!lenp)
      + len /= sizeof(unsigned short);
      +
      + retlen = WideCharToMultiByte(vcp->dbcs, 0,
      + (const unsigned short *)ptr, len, 0, 0, 0, 0);
      +
      + retval = alloc(retlen + 1);
      + if (retval == NULL)
      + break;
      +
      + WideCharToMultiByte(vcp->dbcs, 0,
      + (const unsigned short *) ptr, len, retval, retlen, 0, 0);
      +
      + retval[retlen] = NUL;
      + if (lenp != NULL)
      + *lenp = retlen;
      + break;
      + }
      + case CONV_CODEPAGE: /* current codepage -> ucs-2 */
      + {
      + int retlen;
      + retlen = MultiByteToWideChar(GetACP(), 0, ptr, len,
      + 0, 0);
      +
      + retval = alloc(sizeof(unsigned short) * retlen);
      + if (retval == NULL)
      + break;
      +
      + MultiByteToWideChar(GetACP(), 0, ptr, len,
      + (unsigned short *) retval, retlen);
      +
      + if (lenp != NULL)
      + *lenp = retlen * sizeof(unsigned short); /* number of shorts -> buffer size */
      + }
      +
      + # endif
      +
      }

      return retval;


      ----ime_fix2.diff
      diff -cr src.orig/gui_w32.c src/gui_w32.c
      *** src.orig/gui_w32.c Wed Sep 19 21:43:49 2001
      --- src/gui_w32.c Tue Oct 2 17:31:11 2001
      ***************
      *** 210,215 ****
      --- 210,219 ----
      static int get_toolbar_bitmap(vimmenu_T *menu);
      #endif

      + #ifdef FEAT_MBYTE_IME
      + static LRESULT _OnImeComposition(HWND hwnd, WPARAM dbcs, LPARAM param);
      + static char_u *GetResultStr(HWND hwnd, int GCS);
      + #endif
      #if defined(FEAT_MBYTE_IME) && defined(DYNAMIC_IME)
      # ifdef NOIME
      typedef struct tagCOMPOSITIONFORM {
      ***************
      *** 221,227 ****
      # endif

      HINSTANCE hLibImm = NULL;
      ! LONG (WINAPI *pImmGetCompositionString)(HIMC, DWORD, LPVOID, DWORD);
      HIMC (WINAPI *pImmGetContext)(HWND);
      BOOL (WINAPI *pImmReleaseContext)(HWND, HIMC);
      BOOL (WINAPI *pImmGetOpenStatus)(HIMC);
      --- 225,232 ----
      # endif

      HINSTANCE hLibImm = NULL;
      ! LONG (WINAPI *pImmGetCompositionStringA)(HIMC, DWORD, LPVOID, DWORD);
      ! LONG (WINAPI *pImmGetCompositionStringW)(HIMC, DWORD, LPVOID, DWORD);
      HIMC (WINAPI *pImmGetContext)(HWND);
      BOOL (WINAPI *pImmReleaseContext)(HWND, HIMC);
      BOOL (WINAPI *pImmGetOpenStatus)(HIMC);
      ***************
      *** 232,238 ****
      BOOL (WINAPI *pImmGetConversionStatus)(HIMC, LPDWORD, LPDWORD);
      static void dyn_imm_load(void);
      #else
      ! # define pImmGetCompositionString ImmGetCompositionStringA
      # define pImmGetContext ImmGetContext
      # define pImmReleaseContext ImmReleaseContext
      # define pImmGetOpenStatus ImmGetOpenStatus
      --- 237,244 ----
      BOOL (WINAPI *pImmGetConversionStatus)(HIMC, LPDWORD, LPDWORD);
      static void dyn_imm_load(void);
      #else
      ! # define pImmGetCompositionStringA ImmGetCompositionStringA
      ! # define pImmGetCompositionStringW ImmGetCompositionStringW
      # define pImmGetContext ImmGetContext
      # define pImmReleaseContext ImmReleaseContext
      # define pImmGetOpenStatus ImmGetOpenStatus
      ***************
      *** 790,795 ****
      --- 841,852 ----
      case WM_IME_NOTIFY:
      if (!_OnImeNotify(hwnd, (DWORD)wParam, (DWORD)lParam))
      return DefWindowProc(hwnd, uMsg, wParam, lParam);
      + break;
      +
      + case WM_IME_COMPOSITION:
      + if (!_OnImeComposition(hwnd, wParam, lParam))
      + return DefWindowProc(hwnd, uMsg, wParam, lParam);
      + break;
      #endif

      default:
      ***************
      *** 1292,1298 ****
      #include <ime.h>
      #include <imm.h>

      - static char lpCompStr[100]; // Pointer to composition str.
      static BOOL bInComposition=FALSE;

      /*
      --- 1352,1357 ----
      ***************
      *** 1356,1453 ****
      }
      }
      gui_update_cursor(TRUE, FALSE);
      ! lResult = 1;
      break;
      }
      pImmReleaseContext(hWnd, hImc);
      return lResult;
      }

      ! /* get composition string from WIN_IME */
      ! static void
      ! GetCompositionStr(HWND hwnd, LPARAM CompFlag)
      {
      ! DWORD dwBufLen; // Stogare for len. of composition str
      ! HIMC hIMC; // Input context handle.
      !
      ! // If fail to get input context handle then do nothing.
      ! // Applications should call ImmGetContext API to get
      ! // input context handle.

      ! if (!pImmGetContext || !(hIMC = pImmGetContext(hwnd)))
      ! return;

      ! // Determines how much memory space to store the composition string.
      ! // Applications should call ImmGetCompositionString with
      ! // GCS_COMPSTR flag on, buffer length zero, to get the bullfer
      ! // length.

      ! if ((dwBufLen = pImmGetCompositionString(hIMC, GCS_COMPSTR,
      ! (void FAR*)NULL, 0l)) < 0)
      ! goto exit2;

      ! if (dwBufLen > 99)
      ! goto exit2;

      ! // Reads in the composition string.
      ! if ( dwBufLen != 0 )
      {
      ! pImmGetCompositionString(hIMC, GCS_COMPSTR, lpCompStr, dwBufLen);
      ! lpCompStr[dwBufLen] = 0;
      }
      else
      {
      ! strcpy(lpCompStr, " ");
      ! dwBufLen = 2;
      ! }
      !
      ! // Display new composition chars.
      ! DisplayCompStringOpaque(lpCompStr, dwBufLen);


      ! exit2:
      ! pImmReleaseContext(hwnd, hIMC);
      }

      !
      ! // void GetResultStr()
      ! //
      ! // This handles WM_IME_COMPOSITION with GCS_RESULTSTR flag on.
      ! //
      ! // get complete composition string
      !
      ! static void
      ! GetResultStr(HWND hwnd)
      {
      ! DWORD dwBufLen; // Storage for length of result str.
      ! HIMC hIMC; // Input context handle.

      - // If fail to get input context handle then do nothing.
      if (!pImmGetContext || !(hIMC = pImmGetContext(hwnd)))
      ! return;
      !
      ! // Determines how much memory space to store the result string.
      ! // Applications should call ImmGetCompositionString with
      ! // GCS_RESULTSTR flag on, buffer length zero, to get the bullfer
      ! // length.
      ! if ((dwBufLen = pImmGetCompositionString(hIMC, GCS_RESULTSTR,
      ! (void FAR *)NULL, (DWORD) 0)) <= 0)
      ! goto exit2;
      !
      ! if (dwBufLen > 99)
      ! goto exit2;
      !
      ! // Reads in the result string.
      ! pImmGetCompositionString(hIMC, GCS_RESULTSTR, lpCompStr, dwBufLen);

      ! // Displays the result string.
      ! DisplayCompStringOpaque(lpCompStr, dwBufLen);

      ! exit2:
      pImmReleaseContext(hwnd, hIMC);
      }

      ! static char *
      ImeGetTempComposition(void)
      {
      if (bInComposition == TRUE)
      --- 1415,1523 ----
      }
      }
      gui_update_cursor(TRUE, FALSE);
      ! lResult = 0;
      break;
      }
      pImmReleaseContext(hWnd, hImc);
      return lResult;
      }

      ! static LRESULT
      ! _OnImeComposition(HWND hwnd, WPARAM dbcs, LPARAM param)
      {
      ! char_u *ret;
      ! if ((param & GCS_RESULTSTR) == 0) /* Composition unfinished. */
      ! return 0;

      ! if (ret = GetResultStr(hwnd, GCS_RESULTSTR))
      ! {
      ! add_to_input_buf_csi(ret, strlen(ret));
      ! vim_free(ret);
      ! return 1;
      ! }
      ! else
      ! return 0;
      ! }

      ! /* get the currnet composition string, in UCS-2; len is the number of
      ! * Unicode characters */
      ! unsigned short *
      ! GetCompositionString_inUCS2(HIMC hIMC, DWORD GCS, int *len)
      ! {
      ! LONG ret;
      ! unsigned short *wbuf = NULL;

      ! if (!pImmGetContext)
      ! return NULL; /* no imm32.dll */

      ! /* Try Unicode; this'll always work on NT regardless of codepage. */
      ! ret = pImmGetCompositionStringW(hIMC, GCS, NULL, 0);
      ! if (ret == 0)
      ! return NULL; /* empty */

      ! if (ret > 0)
      {
      ! wbuf = (unsigned short *) alloc(ret * sizeof(unsigned short));
      ! if(!wbuf) return NULL;
      !
      ! pImmGetCompositionStringW(hIMC, GCS, wbuf, ret);
      ! *len = ret / sizeof(unsigned short); /* char -> wchar */
      ! return wbuf;
      }
      +
      + /* ret < 0; we got an error, so try the ANSI version. This'll work
      + * on 9x/ME, but only if the codepage happens to be set to whatever
      + * we're inputting. */
      +
      + ret = pImmGetCompositionStringA(hIMC, GCS, NULL, 0);
      + if (ret <= 0)
      + return NULL; /* empty or error */
      else
      {
      ! char_u *buf;

      + buf = (char_u *) alloc(ret);
      + if (!buf)
      + return NULL;
      + pImmGetCompositionStringA(hIMC, GCS, buf, ret);

      ! /* convert from codepage to UCS-2 */
      ! wbuf = (unsigned short *)string_convert(&ime_conv_cp, buf, &ret);
      ! vim_free(buf);
      ! *len = ret / sizeof(unsigned short); /* char_u -> wchar */
      ! }
      ! return wbuf;
      }

      ! /*
      ! * void GetResultStr()
      ! *
      ! * This handles WM_IME_COMPOSITION with GCS_RESULTSTR flag on.
      ! * get complete composition string
      ! */
      ! static char_u *
      ! GetResultStr(HWND hwnd, int GCS)
      {
      ! DWORD dwBufLen; /* Stogare for len. of composition str. */
      ! HIMC hIMC; /* Input context handle. */
      ! unsigned short *buf = NULL;
      ! char *convbuf = NULL;

      if (!pImmGetContext || !(hIMC = pImmGetContext(hwnd)))
      ! return NULL;

      ! /* Reads in the composition string. */
      ! buf = GetCompositionString_inUCS2(hIMC, GCS, &dwBufLen);
      ! if (!buf)
      ! return NULL;

      ! convbuf = string_convert(&ime_conv, (unsigned char *) buf, &dwBufLen);
      pImmReleaseContext(hwnd, hIMC);
      + vim_free(buf);
      + return convbuf;
      }

      ! static char_u *
      ImeGetTempComposition(void)
      {
      if (bInComposition == TRUE)
      ***************
      *** 1459,1466 ****
      {
      pImmGetConversionStatus(hImc, &dwConvMode, &dwSentMode);
      pImmReleaseContext(s_hwnd, hImc);
      ! if ((dwConvMode & IME_CMODE_NATIVE))
      ! return lpCompStr;
      }
      }
      return NULL;
      --- 1529,1537 ----
      {
      pImmGetConversionStatus(hImc, &dwConvMode, &dwSentMode);
      pImmReleaseContext(s_hwnd, hImc);
      ! if ((dwConvMode & IME_CMODE_NATIVE)) {
      ! return GetResultStr(s_hwnd, GCS_COMPSTR);
      ! }
      }
      }
      return NULL;
      ***************
      *** 1668,1674 ****
      HBRUSH hbr;
      RECT rc;
      #ifdef FEAT_MBYTE_IME
      ! char *szComp;
      #endif

      if (!(flags & DRAW_TRANSP))
      --- 1739,1745 ----
      HBRUSH hbr;
      RECT rc;
      #ifdef FEAT_MBYTE_IME
      ! char_u *szComp;
      #endif

      if (!(flags & DRAW_TRANSP))
      ***************
      *** 1763,1772 ****
      {
      /* draw an incomplete composition character (korean) */
      if (len == 1 && blink_state == BLINK_ON
      ! && (szComp = ImeGetTempComposition()) != NULL) // hangul
      HanExtTextOut(s_hdc, TEXT_X(col), TEXT_Y(row),
      foptions, pcliprect, szComp, 2, padding, TRUE);
      ! else
      HanExtTextOut(s_hdc, TEXT_X(col), TEXT_Y(row),
      foptions, pcliprect, (char *)text, len, padding, FALSE);
      }
      --- 1834,1844 ----
      {
      /* draw an incomplete composition character (korean) */
      if (len == 1 && blink_state == BLINK_ON
      ! && (szComp = ImeGetTempComposition()) != NULL) { // hangul
      HanExtTextOut(s_hdc, TEXT_X(col), TEXT_Y(row),
      foptions, pcliprect, szComp, 2, padding, TRUE);
      ! vim_free(szComp);
      ! } else
      HanExtTextOut(s_hdc, TEXT_X(col), TEXT_Y(row),
      foptions, pcliprect, (char *)text, len, padding, FALSE);
      }
      ***************
      *** 3334,3342 ****
      hLibImm = LoadLibrary("imm32.dll");
      if (hLibImm == NULL)
      return;
      ! if ((*((FARPROC*)&pImmGetCompositionString)
      = GetProcAddress(hLibImm, "ImmGetCompositionStringA")))
      nImmFunc++;
      if ((*((FARPROC*)&pImmGetContext)
      = GetProcAddress(hLibImm, "ImmGetContext")))
      nImmFunc++;
      --- 3406,3417 ----
      hLibImm = LoadLibrary("imm32.dll");
      if (hLibImm == NULL)
      return;
      ! if ((*((FARPROC*)&pImmGetCompositionStringA)
      = GetProcAddress(hLibImm, "ImmGetCompositionStringA")))
      nImmFunc++;
      + if ((*((FARPROC*)&pImmGetCompositionStringW)
      + = GetProcAddress(hLibImm, "ImmGetCompositionStringW")))
      + nImmFunc++;
      if ((*((FARPROC*)&pImmGetContext)
      = GetProcAddress(hLibImm, "ImmGetContext")))
      nImmFunc++;
      ***************
      *** 3362,3368 ****
      = GetProcAddress(hLibImm, "ImmGetConversionStatus")))
      nImmFunc++;

      ! if (nImmFunc != 9)
      {
      FreeLibrary(hLibImm);
      hLibImm = NULL;
      --- 3437,3443 ----
      = GetProcAddress(hLibImm, "ImmGetConversionStatus")))
      nImmFunc++;

      ! if (nImmFunc != 10)
      {
      FreeLibrary(hLibImm);
      hLibImm = NULL;
    • Show all 54 messages in this topic