emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master c6ecdab: Support toggling native Input Methods on MS-Windows


From: Eli Zaretskii
Subject: master c6ecdab: Support toggling native Input Methods on MS-Windows
Date: Mon, 13 Apr 2020 09:08:05 -0400 (EDT)

branch: master
commit c6ecdab0ee5b633e184502e5440e3b893cb6a797
Author: Albert <address@hidden>
Commit: Eli Zaretskii <address@hidden>

    Support toggling native Input Methods on MS-Windows
    
    * src/w32term.h (WM_EMACS_IME_STATUS): New message code.
    
    * src/w32fns.c (ImmGetOpenStatus_Proc, ImmSetOpenStatus_Proc): New
    typedefs.
    (w32_msg_pump): Handle the WM_EMACS_IME_STATUS message.
    (Fw32_get_ime_open_status, Fw32_set_ime_open_status): New functions
    (syms_of_w32fns): Defsubr them.
    (globals_of_w32fns): Load ImmGetOpenStatus and ImmSetOpenStatus
    from IMM2.DLL.
---
 src/w32fns.c  | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/w32term.h |  3 ++-
 2 files changed, 77 insertions(+), 1 deletion(-)

diff --git a/src/w32fns.c b/src/w32fns.c
index 8d714f0..2d1a92b 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -166,6 +166,10 @@ typedef HIMC (WINAPI * ImmGetContext_Proc) (IN HWND 
window);
 typedef BOOL (WINAPI * ImmReleaseContext_Proc) (IN HWND wnd, IN HIMC context);
 typedef BOOL (WINAPI * ImmSetCompositionWindow_Proc) (IN HIMC context,
                                                      IN COMPOSITIONFORM *form);
+/* For toggling IME status.  */
+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 @@ typedef HRESULT (WINAPI *SetThreadDescription_Proc)
 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;
@@ -3305,6 +3311,7 @@ w32_name_of_message (UINT 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 +3449,22 @@ w32_msg_pump (deferred_msg * msg_buf)
                  emacs_abort ();
              }
              break;
+            case WM_EMACS_IME_STATUS:
+             {
+               focus_window = GetFocus ();
+               if (!set_ime_open_status_fn || !focus_window)
+                 break;
+
+               HIMC context = get_ime_context_fn (focus_window);
+               if (!context)
+                 break;
+
+               BOOL wParam = (BOOL) msg.wParam;
+               set_ime_open_status_fn (context, wParam);
+               release_ime_context_fn (focus_window, 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 +10241,51 @@ 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 non-nil if IME is active, otherwise return nil.
+
+IME, the MS-Windows Input Method Editor, can be active or inactive.
+This function returns non-nil if the IME is active, otherwise nil.  */)
+  (void)
+{
+  struct frame *sf =
+    FRAMEP (selected_frame) && FRAME_LIVE_P (XFRAME (selected_frame))
+    ? XFRAME  (selected_frame)
+    : NULL;
+
+  if (sf)
+    {
+      HWND current_window = FRAME_W32_WINDOW (sf);
+      HIMC context = get_ime_context_fn (current_window);
+      if (!context)
+       {
+         BOOL retval = get_ime_open_status_fn (context);
+         release_ime_context_fn (current_window, context);
+
+         return retval ? Qt : Qnil;
+       }
+    }
+
+  return Qnil;
+}
+
+DEFUN ("w32-set-ime-open-status",
+       Fw32_set_ime_open_status, Sw32_set_ime_open_status,
+       1, 1, 0,
+       doc: /* Open or close the IME according to STATUS.
+
+This function activates the IME, the MS-Windows Input Method Editor,
+if STATUS is non-nil, otherwise it deactivates the IME.  */)
+  (Lisp_Object status)
+{
+  unsigned ime_status = NILP (status) ? 0 : 1;
+
+  PostThreadMessage (dwWindowsThreadId, WM_EMACS_IME_STATUS, ime_status, 0);
+  return Qnil;
+}
+
 
 #ifdef WINDOWSNT
 /***********************************************************************
@@ -10744,6 +10812,8 @@ tip frame.  */);
   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 f8a8a72..4e9234f 100644
--- a/src/w32term.h
+++ b/src/w32term.h
@@ -670,7 +670,8 @@ do { \
 #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)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]