From: Albert <georgealbert@qq.com>
To: emacs-devel <emacs-devel@gnu.org>
Subject: [PATCH] Add IME status change support on windows natively
Date: Mon, 13 Apr 2020 12:09:00 +0800 [thread overview]
Message-ID: <tencent_759846479C7711E75290E7233935770D0108@qq.com> (raw)
[-- 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)
next reply other threads:[~2020-04-13 4:09 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-04-13 4:09 Albert [this message]
2020-04-13 4:53 ` [PATCH] Add IME status change support on windows natively 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
-- strict thread matches above, loose matches on Subject: below --
2020-04-13 10:56 Zhu Zihao
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=tencent_759846479C7711E75290E7233935770D0108@qq.com \
--to=georgealbert@qq.com \
--cc=emacs-devel@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.