diff options
| author | Albert | 2020-04-13 18:02:17 +0800 |
|---|---|---|
| committer | Eli Zaretskii | 2020-04-13 16:07:19 +0300 |
| commit | c6ecdab0ee5b633e184502e5440e3b893cb6a797 (patch) | |
| tree | 19fd7e21aa281f6217218a7bb4c09c1e3d4b4962 /src | |
| parent | 188bd80a903d34ef6a85b09e99890433e7adceb7 (diff) | |
| download | emacs-c6ecdab0ee5b633e184502e5440e3b893cb6a797.tar.gz emacs-c6ecdab0ee5b633e184502e5440e3b893cb6a797.zip | |
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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/w32fns.c | 75 | ||||
| -rw-r--r-- | src/w32term.h | 3 |
2 files changed, 77 insertions, 1 deletions
diff --git a/src/w32fns.c b/src/w32fns.c index 8d714f0b8d0..2d1a92be096 100644 --- a/src/w32fns.c +++ b/src/w32fns.c | |||
| @@ -166,6 +166,10 @@ typedef HIMC (WINAPI * ImmGetContext_Proc) (IN HWND window); | |||
| 166 | typedef BOOL (WINAPI * ImmReleaseContext_Proc) (IN HWND wnd, IN HIMC context); | 166 | typedef BOOL (WINAPI * ImmReleaseContext_Proc) (IN HWND wnd, IN HIMC context); |
| 167 | typedef BOOL (WINAPI * ImmSetCompositionWindow_Proc) (IN HIMC context, | 167 | typedef BOOL (WINAPI * ImmSetCompositionWindow_Proc) (IN HIMC context, |
| 168 | IN COMPOSITIONFORM *form); | 168 | IN COMPOSITIONFORM *form); |
| 169 | /* For toggling IME status. */ | ||
| 170 | typedef BOOL (WINAPI * ImmGetOpenStatus_Proc) (IN HIMC); | ||
| 171 | typedef BOOL (WINAPI * ImmSetOpenStatus_Proc) (IN HIMC, IN BOOL); | ||
| 172 | |||
| 169 | typedef HMONITOR (WINAPI * MonitorFromPoint_Proc) (IN POINT pt, IN DWORD flags); | 173 | typedef HMONITOR (WINAPI * MonitorFromPoint_Proc) (IN POINT pt, IN DWORD flags); |
| 170 | typedef BOOL (WINAPI * GetMonitorInfo_Proc) | 174 | typedef BOOL (WINAPI * GetMonitorInfo_Proc) |
| 171 | (IN HMONITOR monitor, OUT struct MONITOR_INFO* info); | 175 | (IN HMONITOR monitor, OUT struct MONITOR_INFO* info); |
| @@ -185,6 +189,8 @@ typedef HRESULT (WINAPI *SetThreadDescription_Proc) | |||
| 185 | TrackMouseEvent_Proc track_mouse_event_fn = NULL; | 189 | TrackMouseEvent_Proc track_mouse_event_fn = NULL; |
| 186 | ImmGetCompositionString_Proc get_composition_string_fn = NULL; | 190 | ImmGetCompositionString_Proc get_composition_string_fn = NULL; |
| 187 | ImmGetContext_Proc get_ime_context_fn = NULL; | 191 | ImmGetContext_Proc get_ime_context_fn = NULL; |
| 192 | ImmGetOpenStatus_Proc get_ime_open_status_fn = NULL; | ||
| 193 | ImmSetOpenStatus_Proc set_ime_open_status_fn = NULL; | ||
| 188 | ImmReleaseContext_Proc release_ime_context_fn = NULL; | 194 | ImmReleaseContext_Proc release_ime_context_fn = NULL; |
| 189 | ImmSetCompositionWindow_Proc set_ime_composition_window_fn = NULL; | 195 | ImmSetCompositionWindow_Proc set_ime_composition_window_fn = NULL; |
| 190 | MonitorFromPoint_Proc monitor_from_point_fn = NULL; | 196 | MonitorFromPoint_Proc monitor_from_point_fn = NULL; |
| @@ -3305,6 +3311,7 @@ w32_name_of_message (UINT msg) | |||
| 3305 | M (WM_EMACS_SETCURSOR), | 3311 | M (WM_EMACS_SETCURSOR), |
| 3306 | M (WM_EMACS_SHOWCURSOR), | 3312 | M (WM_EMACS_SHOWCURSOR), |
| 3307 | M (WM_EMACS_PAINT), | 3313 | M (WM_EMACS_PAINT), |
| 3314 | M (WM_EMACS_IME_STATUS), | ||
| 3308 | M (WM_CHAR), | 3315 | M (WM_CHAR), |
| 3309 | #undef M | 3316 | #undef M |
| 3310 | { 0, 0 } | 3317 | { 0, 0 } |
| @@ -3442,6 +3449,22 @@ w32_msg_pump (deferred_msg * msg_buf) | |||
| 3442 | emacs_abort (); | 3449 | emacs_abort (); |
| 3443 | } | 3450 | } |
| 3444 | break; | 3451 | break; |
| 3452 | case WM_EMACS_IME_STATUS: | ||
| 3453 | { | ||
| 3454 | focus_window = GetFocus (); | ||
| 3455 | if (!set_ime_open_status_fn || !focus_window) | ||
| 3456 | break; | ||
| 3457 | |||
| 3458 | HIMC context = get_ime_context_fn (focus_window); | ||
| 3459 | if (!context) | ||
| 3460 | break; | ||
| 3461 | |||
| 3462 | BOOL wParam = (BOOL) msg.wParam; | ||
| 3463 | set_ime_open_status_fn (context, wParam); | ||
| 3464 | release_ime_context_fn (focus_window, context); | ||
| 3465 | break; | ||
| 3466 | } | ||
| 3467 | |||
| 3445 | #ifdef MSG_DEBUG | 3468 | #ifdef MSG_DEBUG |
| 3446 | /* Broadcast messages make it here, so you need to be looking | 3469 | /* Broadcast messages make it here, so you need to be looking |
| 3447 | for something in particular for this to be useful. */ | 3470 | for something in particular for this to be useful. */ |
| @@ -10218,6 +10241,51 @@ DEFUN ("w32-notification-close", | |||
| 10218 | 10241 | ||
| 10219 | #endif /* WINDOWSNT && !HAVE_DBUS */ | 10242 | #endif /* WINDOWSNT && !HAVE_DBUS */ |
| 10220 | 10243 | ||
| 10244 | DEFUN ("w32-get-ime-open-status", | ||
| 10245 | Fw32_get_ime_open_status, Sw32_get_ime_open_status, | ||
| 10246 | 0, 0, 0, | ||
| 10247 | doc: /* Return non-nil if IME is active, otherwise return nil. | ||
| 10248 | |||
| 10249 | IME, the MS-Windows Input Method Editor, can be active or inactive. | ||
| 10250 | This function returns non-nil if the IME is active, otherwise nil. */) | ||
| 10251 | (void) | ||
| 10252 | { | ||
| 10253 | struct frame *sf = | ||
| 10254 | FRAMEP (selected_frame) && FRAME_LIVE_P (XFRAME (selected_frame)) | ||
| 10255 | ? XFRAME (selected_frame) | ||
| 10256 | : NULL; | ||
| 10257 | |||
| 10258 | if (sf) | ||
| 10259 | { | ||
| 10260 | HWND current_window = FRAME_W32_WINDOW (sf); | ||
| 10261 | HIMC context = get_ime_context_fn (current_window); | ||
| 10262 | if (!context) | ||
| 10263 | { | ||
| 10264 | BOOL retval = get_ime_open_status_fn (context); | ||
| 10265 | release_ime_context_fn (current_window, context); | ||
| 10266 | |||
| 10267 | return retval ? Qt : Qnil; | ||
| 10268 | } | ||
| 10269 | } | ||
| 10270 | |||
| 10271 | return Qnil; | ||
| 10272 | } | ||
| 10273 | |||
| 10274 | DEFUN ("w32-set-ime-open-status", | ||
| 10275 | Fw32_set_ime_open_status, Sw32_set_ime_open_status, | ||
| 10276 | 1, 1, 0, | ||
| 10277 | doc: /* Open or close the IME according to STATUS. | ||
| 10278 | |||
| 10279 | This function activates the IME, the MS-Windows Input Method Editor, | ||
| 10280 | if STATUS is non-nil, otherwise it deactivates the IME. */) | ||
| 10281 | (Lisp_Object status) | ||
| 10282 | { | ||
| 10283 | unsigned ime_status = NILP (status) ? 0 : 1; | ||
| 10284 | |||
| 10285 | PostThreadMessage (dwWindowsThreadId, WM_EMACS_IME_STATUS, ime_status, 0); | ||
| 10286 | return Qnil; | ||
| 10287 | } | ||
| 10288 | |||
| 10221 | 10289 | ||
| 10222 | #ifdef WINDOWSNT | 10290 | #ifdef WINDOWSNT |
| 10223 | /*********************************************************************** | 10291 | /*********************************************************************** |
| @@ -10744,6 +10812,8 @@ tip frame. */); | |||
| 10744 | defsubr (&Sw32_notification_notify); | 10812 | defsubr (&Sw32_notification_notify); |
| 10745 | defsubr (&Sw32_notification_close); | 10813 | defsubr (&Sw32_notification_close); |
| 10746 | #endif | 10814 | #endif |
| 10815 | defsubr (&Sw32_get_ime_open_status); | ||
| 10816 | defsubr (&Sw32_set_ime_open_status); | ||
| 10747 | 10817 | ||
| 10748 | #ifdef WINDOWSNT | 10818 | #ifdef WINDOWSNT |
| 10749 | defsubr (&Sw32_read_registry); | 10819 | defsubr (&Sw32_read_registry); |
| @@ -11032,6 +11102,11 @@ globals_of_w32fns (void) | |||
| 11032 | get_proc_addr (imm32_lib, "ImmReleaseContext"); | 11102 | get_proc_addr (imm32_lib, "ImmReleaseContext"); |
| 11033 | set_ime_composition_window_fn = (ImmSetCompositionWindow_Proc) | 11103 | set_ime_composition_window_fn = (ImmSetCompositionWindow_Proc) |
| 11034 | get_proc_addr (imm32_lib, "ImmSetCompositionWindow"); | 11104 | get_proc_addr (imm32_lib, "ImmSetCompositionWindow"); |
| 11105 | |||
| 11106 | get_ime_open_status_fn = (ImmGetOpenStatus_Proc) | ||
| 11107 | get_proc_addr (imm32_lib, "ImmGetOpenStatus"); | ||
| 11108 | set_ime_open_status_fn = (ImmSetOpenStatus_Proc) | ||
| 11109 | get_proc_addr (imm32_lib, "ImmSetOpenStatus"); | ||
| 11035 | } | 11110 | } |
| 11036 | 11111 | ||
| 11037 | HMODULE hm_kernel32 = GetModuleHandle ("kernel32.dll"); | 11112 | HMODULE hm_kernel32 = GetModuleHandle ("kernel32.dll"); |
diff --git a/src/w32term.h b/src/w32term.h index f8a8a727e8a..4e9234f239f 100644 --- a/src/w32term.h +++ b/src/w32term.h | |||
| @@ -670,7 +670,8 @@ do { \ | |||
| 670 | #define WM_EMACS_BRINGTOTOP (WM_EMACS_START + 23) | 670 | #define WM_EMACS_BRINGTOTOP (WM_EMACS_START + 23) |
| 671 | #define WM_EMACS_INPUT_READY (WM_EMACS_START + 24) | 671 | #define WM_EMACS_INPUT_READY (WM_EMACS_START + 24) |
| 672 | #define WM_EMACS_FILENOTIFY (WM_EMACS_START + 25) | 672 | #define WM_EMACS_FILENOTIFY (WM_EMACS_START + 25) |
| 673 | #define WM_EMACS_END (WM_EMACS_START + 26) | 673 | #define WM_EMACS_IME_STATUS (WM_EMACS_START + 26) |
| 674 | #define WM_EMACS_END (WM_EMACS_START + 27) | ||
| 674 | 675 | ||
| 675 | #define WND_FONTWIDTH_INDEX (0) | 676 | #define WND_FONTWIDTH_INDEX (0) |
| 676 | #define WND_LINEHEIGHT_INDEX (4) | 677 | #define WND_LINEHEIGHT_INDEX (4) |