[PATCH 2/6] winemac: Use unixlib interface for macdrv_ime_set_text calls.

Jacek Caban wine at gitlab.winehq.org
Wed Jun 1 19:27:54 CDT 2022


From: Jacek Caban <jacek at codeweavers.com>

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
---
 dlls/winemac.drv/dllmain.c     | 17 +++++++++++++-
 dlls/winemac.drv/event.c       | 28 +++++++++++++++++++++++
 dlls/winemac.drv/ime.c         | 42 ++++++++++++----------------------
 dlls/winemac.drv/macdrv.h      |  5 +++-
 dlls/winemac.drv/macdrv_main.c |  8 +++++++
 dlls/winemac.drv/unixlib.h     | 19 +++++++++++++++
 6 files changed, 89 insertions(+), 30 deletions(-)

diff --git a/dlls/winemac.drv/dllmain.c b/dlls/winemac.drv/dllmain.c
index 23a1e6e2218..27eda4d2ac8 100644
--- a/dlls/winemac.drv/dllmain.c
+++ b/dlls/winemac.drv/dllmain.c
@@ -26,9 +26,19 @@
 
 HMODULE macdrv_module = 0;
 
+typedef NTSTATUS (WINAPI *kernel_callback)(void *params, ULONG size);
+static const kernel_callback kernel_callbacks[] =
+{
+    macdrv_ime_set_text,
+};
+
+C_ASSERT(NtUserDriverCallbackFirst + ARRAYSIZE(kernel_callbacks) == client_func_last);
+
+
 static BOOL process_attach(void)
 {
     struct init_params params;
+    void **callback_table;
 
     struct localized_string *str;
     struct localized_string strings[] = {
@@ -53,7 +63,12 @@ static BOOL process_attach(void)
         str->len = LoadStringW(macdrv_module, str->id, (WCHAR *)&str->str, 0);
     params.strings = strings;
 
-    return !MACDRV_CALL(init, &params);
+    if (MACDRV_CALL(init, &params)) return FALSE;
+
+    callback_table = NtCurrentTeb()->Peb->KernelCallbackTable;
+    memcpy( callback_table + NtUserDriverCallbackFirst, kernel_callbacks, sizeof(kernel_callbacks) );
+
+    return TRUE;
 }
 
 BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, void *reserved)
diff --git a/dlls/winemac.drv/event.c b/dlls/winemac.drv/event.c
index 9e53bef981a..68b66d610fe 100644
--- a/dlls/winemac.drv/event.c
+++ b/dlls/winemac.drv/event.c
@@ -141,6 +141,34 @@ static macdrv_event_mask get_event_mask(DWORD mask)
 }
 
 
+/***********************************************************************
+ *              macdrv_im_set_text
+ */
+static void macdrv_im_set_text(const macdrv_event *event)
+{
+    HWND hwnd = macdrv_get_window_hwnd(event->window);
+    struct ime_set_text_params *params;
+    CFIndex length = 0, size;
+
+    TRACE_(imm)("win %p/%p himc %p text %s complete %u\n", hwnd, event->window, event->im_set_text.data,
+                debugstr_cf(event->im_set_text.text), event->im_set_text.complete);
+
+    if (event->im_set_text.text)
+        length = CFStringGetLength(event->im_set_text.text);
+
+    size = offsetof(struct ime_set_text_params, text[length]);
+    if (!(params = malloc(size))) return;
+    params->hwnd = hwnd;
+    params->data = event->im_set_text.data;
+    params->cursor_pos = event->im_set_text.cursor_pos;
+    params->complete = event->im_set_text.complete;
+
+    if (length)
+        CFStringGetCharacters(event->im_set_text.text, CFRangeMake(0, length), params->text);
+
+    macdrv_client_func(client_func_ime_set_text, params, size);
+}
+
 /***********************************************************************
  *              macdrv_sent_text_input
  */
diff --git a/dlls/winemac.drv/ime.c b/dlls/winemac.drv/ime.c
index 00d4d9f1852..2cf3aefb79d 100644
--- a/dlls/winemac.drv/ime.c
+++ b/dlls/winemac.drv/ime.c
@@ -1395,38 +1395,25 @@ BOOL WINAPI ImeInquire(LPIMEINFO lpIMEInfo, LPWSTR lpszUIClass, LPCWSTR lpszOpti
 /* Interfaces to other parts of the Mac driver */
 
 /***********************************************************************
- *              macdrv_im_set_text
+ *              macdrv_ime_set_text
  */
-void macdrv_im_set_text(const macdrv_event *event)
+NTSTATUS WINAPI macdrv_ime_set_text(void *arg, ULONG size)
 {
-    HWND hwnd = macdrv_get_window_hwnd(event->window);
-    void *himc = event->im_set_text.data;
-
-    TRACE("win %p/%p himc %p text %s complete %u\n", hwnd, event->window, himc,
-          debugstr_cf(event->im_set_text.text), event->im_set_text.complete);
+    struct ime_set_text_params *params = arg;
+    ULONG length = (size - offsetof(struct ime_set_text_params, text)) / sizeof(WCHAR);
+    void *himc = params->data;
 
     if (!himc) himc = RealIMC(FROM_MACDRV);
 
-    if (event->im_set_text.text)
+    if (length)
     {
-        CFIndex length = CFStringGetLength(event->im_set_text.text);
-        const UniChar *chars = CFStringGetCharactersPtr(event->im_set_text.text);
-        UniChar *buffer = NULL;
-
-        if (!chars)
-        {
-            buffer = HeapAlloc(GetProcessHeap(), 0, length * sizeof(*buffer));
-            CFStringGetCharacters(event->im_set_text.text, CFRangeMake(0, length), buffer);
-            chars = buffer;
-        }
-
         if (himc)
-            IME_SetCompositionString(himc, SCS_SETSTR, chars, length * sizeof(*chars),
-                event->im_set_text.cursor_pos, !event->im_set_text.complete);
+            IME_SetCompositionString(himc, SCS_SETSTR, params->text, length * sizeof(WCHAR),
+                                     params->cursor_pos, !params->complete);
         else
         {
             INPUT input;
-            CFIndex i;
+            unsigned int i;
 
             input.type              = INPUT_KEYBOARD;
             input.ki.wVk            = 0;
@@ -1435,20 +1422,19 @@ void macdrv_im_set_text(const macdrv_event *event)
 
             for (i = 0; i < length; i++)
             {
-                input.ki.wScan      = chars[i];
+                input.ki.wScan      = params->text[i];
                 input.ki.dwFlags    = KEYEVENTF_UNICODE;
-                __wine_send_input(hwnd, &input, NULL);
+                __wine_send_input(params->hwnd, &input, NULL);
 
                 input.ki.dwFlags    = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP;
-                __wine_send_input(hwnd, &input, NULL);
+                __wine_send_input(params->hwnd, &input, NULL);
             }
         }
-
-        HeapFree(GetProcessHeap(), 0, buffer);
     }
 
-    if (event->im_set_text.complete)
+    if (params->complete)
         IME_NotifyComplete(himc);
+    return 0;
 }
 
 /**************************************************************************
diff --git a/dlls/winemac.drv/macdrv.h b/dlls/winemac.drv/macdrv.h
index 95ed36ff7e0..c9fcf1dbf4b 100644
--- a/dlls/winemac.drv/macdrv.h
+++ b/dlls/winemac.drv/macdrv.h
@@ -289,13 +289,16 @@ extern NTSTATUS macdrv_init(void *arg) DECLSPEC_HIDDEN;
 
 extern NTSTATUS macdrv_ime_process_text_input(void *arg) DECLSPEC_HIDDEN;
 
-extern void macdrv_im_set_text(const macdrv_event *event) DECLSPEC_HIDDEN;
+extern NTSTATUS WINAPI macdrv_ime_set_text(void *params, ULONG size) DECLSPEC_HIDDEN;
 extern BOOL query_ime_char_rect(macdrv_query* query) DECLSPEC_HIDDEN;
 
 /* unixlib interface */
 
 extern NTSTATUS macdrv_notify_icon(void *arg) DECLSPEC_HIDDEN;
 
+extern NTSTATUS macdrv_client_func(enum macdrv_client_funcs func, const void *params,
+                                   ULONG size) DECLSPEC_HIDDEN;
+
 /* user helpers */
 
 static inline LRESULT send_message(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
diff --git a/dlls/winemac.drv/macdrv_main.c b/dlls/winemac.drv/macdrv_main.c
index 4a183747796..bf06d96b407 100644
--- a/dlls/winemac.drv/macdrv_main.c
+++ b/dlls/winemac.drv/macdrv_main.c
@@ -607,6 +607,14 @@ BOOL macdrv_SystemParametersInfo( UINT action, UINT int_param, void *ptr_param,
 }
 
 
+NTSTATUS macdrv_client_func(enum macdrv_client_funcs id, const void *params, ULONG size)
+{
+    /* FIXME: use KeUserModeCallback instead */
+    NTSTATUS (WINAPI *func)(const void *, ULONG) = ((void **)NtCurrentTeb()->Peb->KernelCallbackTable)[id];
+    return func(params, size);
+}
+
+
 static NTSTATUS macdrv_ime_using_input_method(void *arg)
 {
     return macdrv_using_input_method();
diff --git a/dlls/winemac.drv/unixlib.h b/dlls/winemac.drv/unixlib.h
index dc1b314c8cb..20447f1f3b9 100644
--- a/dlls/winemac.drv/unixlib.h
+++ b/dlls/winemac.drv/unixlib.h
@@ -62,3 +62,22 @@ struct notify_icon_params
     DWORD msg;
     struct _NOTIFYICONDATAW *data;
 };
+
+/* driver client callbacks exposed with KernelCallbackTable interface */
+enum macdrv_client_funcs
+{
+    client_func_ime_set_text = NtUserDriverCallbackFirst,
+    client_func_last
+};
+
+/* macdrv_ime_set_text params */
+struct ime_set_text_params
+{
+    HWND hwnd;
+    void *data;
+    UINT32 cursor_pos;
+    UINT32 complete;
+    WCHAR text[1];
+};
+
+C_ASSERT(client_func_last <= NtUserDriverCallbackLast + 1);
-- 
GitLab


https://gitlab.winehq.org/wine/wine/-/merge_requests/170



More information about the wine-devel mailing list