From: Jacek Caban jacek@codeweavers.com
Signed-off-by: Jacek Caban jacek@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, ¶ms); + if (MACDRV_CALL(init, ¶ms)) 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);