From 71faffceb80469b316c86f24e7c6ab94bad8798c Mon Sep 17 00:00:00 2001 From: Shuanglei Tao Date: Wed, 13 Dec 2023 14:05:10 +0800 Subject: [PATCH] switch to unicode win32 api --- src/menu.c | 61 ++++++++++++++++++++++++++++------------------------ src/plugin.c | 8 +++---- 2 files changed, 37 insertions(+), 32 deletions(-) diff --git a/src/menu.c b/src/menu.c index 917e83c..5034238 100644 --- a/src/menu.c +++ b/src/menu.c @@ -12,38 +12,43 @@ struct item_data { char *cmd; }; -static HMENU find_submenu(HMENU hmenu, bstr name) { - MENUITEMINFO mii; - char buf[256]; +static wchar_t *mp_from_utf8(void *talloc_ctx, const char *s) { + int count = MultiByteToWideChar(CP_UTF8, 0, s, -1, NULL, 0); + if (count <= 0) abort(); + wchar_t *ret = talloc_array(talloc_ctx, wchar_t, count); + MultiByteToWideChar(CP_UTF8, 0, s, -1, ret, count); + return ret; +} + +static HMENU find_submenu(HMENU hmenu, wchar_t *name) { + MENUITEMINFOW mii; int count = GetMenuItemCount(hmenu); for (int i = 0; i < count; i++) { memset(&mii, 0, sizeof(mii)); - memset(buf, 0, sizeof(buf)); - mii.cbSize = sizeof(mii); - mii.fMask = MIIM_STRING | MIIM_SUBMENU; - mii.cch = 256; - mii.dwTypeData = buf; - GetMenuItemInfo(hmenu, i, TRUE, &mii); - if (mii.hSubMenu == NULL) continue; + mii.fMask = MIIM_STRING; + if (!GetMenuItemInfoW(hmenu, i, TRUE, &mii) || mii.cch == 0) continue; - if (bstr_equals0(name, mii.dwTypeData)) { - return mii.hSubMenu; - } + mii.cch++; + wchar_t buf[mii.cch]; + mii.dwTypeData = buf; + mii.fMask |= MIIM_SUBMENU; + if (!GetMenuItemInfoW(hmenu, i, TRUE, &mii) || !mii.hSubMenu) continue; + if (wcscmp(mii.dwTypeData, name) == 0) return mii.hSubMenu; } return NULL; } -static char *format_title(void *talloc_ctx, bstr name, bstr key) { - if (bstr_equals0(key, "_")) return bstrdup0(talloc_ctx, name); - +static wchar_t *format_title(void *talloc_ctx, bstr name, bstr key) { bstr title = bstrdup(NULL, name); - bstr_xappend(NULL, &title, bstr0("\t")); - bstr_xappend(NULL, &title, key); + if (key.len > 0 && !bstr_equals0(key, "_")) { + bstr_xappend(NULL, &title, bstr0("\t")); + bstr_xappend(NULL, &title, key); + } char *ret = bstrdup0(talloc_ctx, title); talloc_free(title.start); - return ret; + return mp_from_utf8(talloc_ctx, ret); } static void insert_menu(void *talloc_ctx, HMENU hmenu, bstr key, bstr cmd, @@ -53,7 +58,7 @@ static void insert_menu(void *talloc_ctx, HMENU hmenu, bstr key, bstr cmd, bstr name = bstr_split(comment, ">", &rest); name = bstr_strip(name); - MENUITEMINFO mii; + MENUITEMINFOW mii; memset(&mii, 0, sizeof(mii)); mii.cbSize = sizeof(mii); mii.fMask = MIIM_ID; @@ -69,20 +74,20 @@ static void insert_menu(void *talloc_ctx, HMENU hmenu, bstr key, bstr cmd, mii.fMask |= MIIM_STRING | MIIM_DATA; mii.dwTypeData = format_title(talloc_ctx, name, key); - mii.cch = strlen(mii.dwTypeData); + mii.cch = wcslen(mii.dwTypeData); mii.dwItemData = (ULONG_PTR)data; } - InsertMenuItem(hmenu, -1, TRUE, &mii); + InsertMenuItemW(hmenu, -1, TRUE, &mii); } else { mii.fMask |= MIIM_STRING | MIIM_SUBMENU; - mii.dwTypeData = bstrdup0(talloc_ctx, name); - mii.cch = strlen(mii.dwTypeData); - mii.hSubMenu = find_submenu(hmenu, name); + mii.dwTypeData = format_title(talloc_ctx, name, bstr0(NULL)); + mii.cch = wcslen(mii.dwTypeData); + mii.hSubMenu = find_submenu(hmenu, mii.dwTypeData); if (mii.hSubMenu == NULL) { mii.hSubMenu = CreatePopupMenu(); - InsertMenuItem(hmenu, -1, TRUE, &mii); + InsertMenuItemW(hmenu, -1, TRUE, &mii); } insert_menu(talloc_ctx, mii.hSubMenu, key, cmd, rest); @@ -136,11 +141,11 @@ void show_menu(struct plugin_ctx *ctx, POINT pt) { } void handle_menu(struct plugin_ctx *ctx, int id) { - MENUITEMINFO mii; + MENUITEMINFOW mii; memset(&mii, 0, sizeof(mii)); mii.cbSize = sizeof(mii); mii.fMask = MIIM_DATA; - GetMenuItemInfo(ctx->hmenu, id, FALSE, &mii); + if (!GetMenuItemInfoW(ctx->hmenu, id, FALSE, &mii)) return; struct item_data *data = (struct item_data *)mii.dwItemData; if (data == NULL) return; diff --git a/src/plugin.c b/src/plugin.c index 104848a..ef87575 100644 --- a/src/plugin.c +++ b/src/plugin.c @@ -26,7 +26,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { break; } - return CallWindowProc(ctx->wnd_proc, hWnd, uMsg, wParam, lParam); + return CallWindowProcW(ctx->wnd_proc, hWnd, uMsg, wParam, lParam); } static void plugin_init(mpv_handle *handle, int64_t wid) { @@ -37,13 +37,13 @@ static void plugin_init(mpv_handle *handle, int64_t wid) { ctx->hwnd = (HWND)wid; ctx->hmenu = load_menu(ctx, input_conf); ctx->wnd_proc = - (WNDPROC)SetWindowLongPtr(ctx->hwnd, GWLP_WNDPROC, (LONG_PTR)WndProc); + (WNDPROC)SetWindowLongPtrW(ctx->hwnd, GWLP_WNDPROC, (LONG_PTR)WndProc); } static void plugin_destroy() { if (ctx != NULL) { DestroyMenu(ctx->hmenu); - SetWindowLongPtr(ctx->hwnd, GWLP_WNDPROC, (LONG_PTR)ctx->wnd_proc); + SetWindowLongPtrW(ctx->hwnd, GWLP_WNDPROC, (LONG_PTR)ctx->wnd_proc); talloc_free(ctx); } if (input_conf != NULL) free(input_conf); @@ -73,7 +73,7 @@ MPV_EXPORT int mpv_open_cplugin(mpv_handle *handle) { return 0; } -void read_input_conf(HINSTANCE hinstDLL) { +static void read_input_conf(HINSTANCE hinstDLL) { wchar_t path[MAX_PATH]; GetModuleFileNameW(hinstDLL, path, MAX_PATH); PathCombineW(path, path, L"..\\..\\input.conf");