unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* [PATCH] Add IME status change support on windows natively
@ 2020-04-13  4:09 Albert
  2020-04-13  4:53 ` Eli Zaretskii
  0 siblings, 1 reply; 31+ messages in thread
From: Albert @ 2020-04-13  4:09 UTC (permalink / raw)
  To: emacs-devel


[-- Attachment #1.1: Type: text/plain, Size: 1449 bytes --]

Hi,
    I added some code on src/w32fns.c and src/w32term.h to add IME status change support on windows natively like gVim did. gVim can change IME status to chinese mode  in insert mode and switch back to english mode when in normal mode natively.



   IME status can be changed by dynamic call imm32.dll's function ImmSetOpenStatus_Proc, but we can't change IME status by elisp code only. Because calling imm32.dll's function ImmSetOpenStatus_Proc from lisp thread is not allowed by Windows, IME is attached to window thread and lisp code is executed in lisp thread. We have to set a flag in lisp thread and set a user-defined message to window thread, then processes that message in w32_msg_pump(). I added a function w32-set-ime-open-status which is called by lisp code.


Following is lisp to use w32-set-ime-open-status after evil mode changed



(if (fboundp 'w32-set-ime-open-status)
    (progn
      (defun emacs-ime-disable ()
        (w32-set-ime-open-status nil))

      (defun emacs-ime-enable ()
        (w32-set-ime-open-status t))

      (add-hook 'evil-insert-state-entry-hook 'emacs-ime-enable)
      (add-hook 'evil-insert-state-exit-hook 'emacs-ime-disable)
      ))

[-- Attachment #1.2: Type: text/html, Size: 1630 bytes --]

[-- Attachment #2: w32fns.c.patch --]
[-- Type: application/octet-stream, Size: 5516 bytes --]

diff --git a/src/w32fns.c b/src/w32fns.c
index 8d714f0b8d..341cbb4fcd 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -166,6 +166,10 @@ DECLARE_HANDLE(HMONITOR);
 typedef BOOL (WINAPI * ImmReleaseContext_Proc) (IN HWND wnd, IN HIMC context);
 typedef BOOL (WINAPI * ImmSetCompositionWindow_Proc) (IN HIMC context,
 						      IN COMPOSITIONFORM *form);
+/* for ime switch */
+typedef BOOL (WINAPI * ImmGetOpenStatus_Proc) (IN HIMC);
+typedef BOOL (WINAPI * ImmSetOpenStatus_Proc) (IN HIMC, IN BOOL);
+
 typedef HMONITOR (WINAPI * MonitorFromPoint_Proc) (IN POINT pt, IN DWORD flags);
 typedef BOOL (WINAPI * GetMonitorInfo_Proc)
   (IN HMONITOR monitor, OUT struct MONITOR_INFO* info);
@@ -185,6 +189,8 @@ DECLARE_HANDLE(HMONITOR);
 TrackMouseEvent_Proc track_mouse_event_fn = NULL;
 ImmGetCompositionString_Proc get_composition_string_fn = NULL;
 ImmGetContext_Proc get_ime_context_fn = NULL;
+ImmGetOpenStatus_Proc get_ime_open_status_fn = NULL;
+ImmSetOpenStatus_Proc set_ime_open_status_fn = NULL;
 ImmReleaseContext_Proc release_ime_context_fn = NULL;
 ImmSetCompositionWindow_Proc set_ime_composition_window_fn = NULL;
 MonitorFromPoint_Proc monitor_from_point_fn = NULL;
@@ -295,6 +301,10 @@ #define WS_EX_NOACTIVATE 0x08000000L
 
 static struct w32_display_info *w32_display_info_for_name (Lisp_Object);
 
+/* emacs ime status change flag, used in mainThread and windowsThread */
+static int w32_ime_status_changed = 0;
+static int w32_emacs_ime_status = 0;
+
 /* Let the user specify a display with a frame.
    nil stands for the selected frame--or, if that is not a w32 frame,
    the first display on the list.  */
@@ -2421,6 +2431,7 @@ w32_createhscrollbar (struct frame *f, struct scroll_bar * bar)
 		       FRAME_W32_WINDOW (f), NULL, hinst, NULL);
 }
 
+
 static void
 w32_createwindow (struct frame *f, int *coords)
 {
@@ -3305,6 +3316,7 @@ #define M(msg) { msg, # msg }
       M (WM_EMACS_SETCURSOR),
       M (WM_EMACS_SHOWCURSOR),
       M (WM_EMACS_PAINT),
+      M (WM_EMACS_IME_STATUS),
       M (WM_CHAR),
 #undef M
       { 0, 0 }
@@ -3442,6 +3454,25 @@ w32_msg_pump (deferred_msg * msg_buf)
 		  emacs_abort ();
 	      }
 	      break;
+            case WM_EMACS_IME_STATUS:
+              if (!set_ime_open_status_fn)
+                break;
+              else
+                {
+                  if (w32_ime_status_changed)
+                    {
+                      w32_ime_status_changed = 0;
+                      HIMC context;
+                      context = get_ime_context_fn (w32_system_caret_hwnd);
+                      if (!context)
+                          break;
+
+                      set_ime_open_status_fn (context, w32_emacs_ime_status);
+                      release_ime_context_fn (w32_system_caret_hwnd, context);
+                    }
+                }
+              break;
+
 #ifdef MSG_DEBUG
 	      /* Broadcast messages make it here, so you need to be looking
 		 for something in particular for this to be useful.  */
@@ -10218,6 +10249,43 @@ DEFUN ("w32-notification-close",
 
 #endif	/* WINDOWSNT && !HAVE_DBUS */
 
+DEFUN ("w32-get-ime-open-status",
+       Fw32_get_ime_open_status, Sw32_get_ime_open_status,
+       0, 0, 0,
+       doc: /* Return ime open status on Windows. */)
+  (void)
+{
+  int retval;
+
+  HIMC context = get_ime_context_fn (w32_system_caret_hwnd);
+  if (context != NULL)
+    {
+      retval = get_ime_open_status_fn (context);
+      release_ime_context_fn (w32_system_caret_hwnd, context);
+
+      return make_fixnum(retval);
+    }
+
+  return Qnil;
+}
+
+DEFUN ("w32-set-ime-open-status",
+       Fw32_set_ime_open_status, Sw32_set_ime_open_status,
+       1, 1, 0,
+       doc: /* Set emacs IME open status on Windows. */)
+  (Lisp_Object status)
+{
+    w32_ime_status_changed = 1;
+    if (NILP (status))
+      w32_emacs_ime_status = 0;
+    else
+      w32_emacs_ime_status = 1;
+
+    PostThreadMessage (dwWindowsThreadId, WM_EMACS_IME_STATUS, 0, 0);
+
+    return Qnil;
+}
+
 \f
 #ifdef WINDOWSNT
 /***********************************************************************
@@ -10744,6 +10812,8 @@ syms_of_w32fns (void)
   defsubr (&Sw32_notification_notify);
   defsubr (&Sw32_notification_close);
 #endif
+  defsubr (&Sw32_get_ime_open_status);
+  defsubr (&Sw32_set_ime_open_status);
 
 #ifdef WINDOWSNT
   defsubr (&Sw32_read_registry);
@@ -11032,6 +11102,11 @@ globals_of_w32fns (void)
       get_proc_addr (imm32_lib, "ImmReleaseContext");
     set_ime_composition_window_fn = (ImmSetCompositionWindow_Proc)
       get_proc_addr (imm32_lib, "ImmSetCompositionWindow");
+
+    get_ime_open_status_fn = (ImmGetOpenStatus_Proc)
+      get_proc_addr (imm32_lib, "ImmGetOpenStatus");
+    set_ime_open_status_fn = (ImmSetOpenStatus_Proc)
+      get_proc_addr (imm32_lib, "ImmSetOpenStatus");
   }
 
   HMODULE hm_kernel32 = GetModuleHandle ("kernel32.dll");
diff --git a/src/w32term.h b/src/w32term.h
index f8a8a727e8..4e9234f239 100644
--- a/src/w32term.h
+++ b/src/w32term.h
@@ -670,7 +670,8 @@ #define WM_EMACS_PAINT                 (WM_EMACS_START + 22)
 #define WM_EMACS_BRINGTOTOP            (WM_EMACS_START + 23)
 #define WM_EMACS_INPUT_READY           (WM_EMACS_START + 24)
 #define WM_EMACS_FILENOTIFY            (WM_EMACS_START + 25)
-#define WM_EMACS_END                   (WM_EMACS_START + 26)
+#define WM_EMACS_IME_STATUS            (WM_EMACS_START + 26)
+#define WM_EMACS_END                   (WM_EMACS_START + 27)
 
 #define WND_FONTWIDTH_INDEX    (0)
 #define WND_LINEHEIGHT_INDEX   (4)

^ permalink raw reply related	[flat|nested] 31+ messages in thread

end of thread, other threads:[~2020-04-15  2:56 UTC | newest]

Thread overview: 31+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-04-13  4:09 [PATCH] Add IME status change support on windows natively Albert
2020-04-13  4:53 ` Eli Zaretskii
2020-04-13  5:47   ` Eli Zaretskii
2020-04-13  6:06     ` =?gb18030?B?u9i4tKO6IFtQQVRDSF0gQWRkIElNRSBzdGF0dXMgY2hhbmdlIHN1cHBvcnQgb24gd2luZG93cyBuYXRpdmVseQ==?= =?gb18030?B?QWxiZXJ0?=
2020-04-13  6:13       ` =?gb18030?B?u9i4tKO6?= [PATCH] Add IME status change support on windows natively Eli Zaretskii
2020-04-13  8:50         ` 回复: " Valtteri Vuorikoski
2020-04-13  9:06           ` Eli Zaretskii
2020-04-13  9:18             ` Valtteri Vuorikoski
2020-04-13  6:12   ` =?gb18030?B?u9i4tKO6IFtQQVRDSF0gQWRkIElNRSBzdGF0dXMgY2hhbmdlIHN1cHBvcnQgb24gd2luZG93cyBuYXRpdmVseQ==?= =?gb18030?B?QWxiZXJ0?=
2020-04-13  6:24     ` =?gb18030?B?u9i4tKO6?= [PATCH] Add IME status change support on windows natively Eli Zaretskii
2020-04-13  6:27       ` =?gb18030?B?u9i4tKO6ILvYuLSjuiBbUEFUQ0hdIEFkZCBJTUUgc3RhdHVzIGNoYW5nZSBzdXBwb3J0IG9uIHdpbmRvd3MgbmF0aXZlbHk=?= =?gb18030?B?QWxiZXJ0?=
2020-04-13  6:32         ` =?gb18030?B?u9i4tKO6ILvYuLSjuiBbUEFUQ0hdIEFkZCBJTUUgc3RhdHVzIGNoYW5nZSBzdXBwb3J0IG9uIHdpbmRvd3MgbmF0aXZlbHk=?= =?gb18030?B?QWxiZXJ0?=
2020-04-13  6:43         ` =?gb18030?B?u9i4tKO6ILvYuLSjug==?= [PATCH] Add IME status change support on windows natively Eli Zaretskii
2020-04-13  6:47           ` =?gb18030?B?u9i4tKO6ILvYuLSjuiC72Li0o7ogW1BBVENIXSBBZGQgSU1FIHN0YXR1cyBjaGFuZ2Ugc3VwcG9ydCBvbiB3aW5kb3dzIG5hdGl2ZWx5?= =?gb18030?B?QWxiZXJ0?=
2020-04-13  7:05             ` 回复: 回复: 回复: [PATCH] Add IME status change support on windows natively Eli Zaretskii
2020-04-13  7:07               ` =?gb18030?B?u9i4tKO6ILvYuLSjuiC72Li0o7ogu9i4tKO6IFtQQVRDSF0gQWRkIElNRSBzdGF0dXMgY2hhbmdlIHN1cHBvcnQgb24gd2luZG93cyBuYXRpdmVseQ==?= =?gb18030?B?QWxiZXJ0?=
2020-04-13  7:21                 ` =?gb18030?B?u9i4tKO6ILvYuLSjuiC72Li0o7ogu9i4tKO6?= [PATCH] Add IME status change support on windows natively Eli Zaretskii
2020-04-13  7:25                   ` Eli Zaretskii
2020-04-13  7:26                   ` =?gb18030?B?u9i4tKO6ILvYuLSjuiC72Li0o7ogu9i4tKO6ILvYuLSjuiBbUEFUQ0hdIEFkZCBJTUUgc3RhdHVzIGNoYW5nZSBzdXBwb3J0IG9uIHdpbmRvd3MgbmF0aXZlbHk=?= =?gb18030?B?QWxiZXJ0?=
2020-04-13  9:22                     ` =?gb18030?B?u9i4tKO6ILvYuLSjuiC72Li0o7ogu9i4tKO6ILvYuLSjuiBbUEFUQ0hdIEFkZCBJTUUgc3RhdHVzIGNoYW5nZSBzdXBwb3J0IG9uIHdpbmRvd3MgbmF0aXZlbHk=?= =?gb18030?B?QWxiZXJ0?=
2020-04-13  9:33                       ` [PATCH] Add IME status change support on windows natively Eli Zaretskii
2020-04-13 10:02                         ` =?gb18030?B?u9i4tKO6IFtQQVRDSF0gQWRkIElNRSBzdGF0dXMgY2hhbmdlIHN1cHBvcnQgb24gd2luZG93cyBuYXRpdmVseQ==?= =?gb18030?B?QWxiZXJ0?=
2020-04-13 13:10                           ` [PATCH] Add IME status change support on windows natively Eli Zaretskii
2020-04-13 13:15                             ` =?gb18030?B?u9i4tKO6IFtQQVRDSF0gQWRkIElNRSBzdGF0dXMgY2hhbmdlIHN1cHBvcnQgb24gd2luZG93cyBuYXRpdmVseQ==?= =?gb18030?B?QWxiZXJ0?=
2020-04-13 13:44                               ` [PATCH] Add IME status change support on windows natively Eli Zaretskii
2020-04-13 14:52                                 ` =?gb18030?B?u9i4tKO6IFtQQVRDSF0gQWRkIElNRSBzdGF0dXMgY2hhbmdlIHN1cHBvcnQgb24gd2luZG93cyBuYXRpdmVseQ==?= =?gb18030?B?QWxiZXJ0?=
2020-04-13 15:32                                   ` =?gb18030?B?u9i4tKO6?= [PATCH] Add IME status change support on windows natively Eli Zaretskii
2020-04-13 15:01                                 ` =?gb18030?B?u9i4tKO6IFtQQVRDSF0gQWRkIElNRSBzdGF0dXMgY2hhbmdlIHN1cHBvcnQgb24gd2luZG93cyBuYXRpdmVseQ==?= =?gb18030?B?QWxiZXJ0?=
2020-04-14  2:13   ` [PATCH] Add IME status change support on windows natively Richard Stallman
2020-04-14  5:54     ` Eli Zaretskii
2020-04-15  2:56       ` Richard Stallman

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).