patch 9.1.1347: small problems with gui_w32.c
Problem: small problems with gui_w32.c
Solution: fix compile warnings and refactor code (John Marriott)
Compiler (clang v20.1.3) warnings on `_OnMenuSelect()` and
`_OnGetDpiScaledSize()`:
```
clang -c -I. -Iproto -DWIN32 -DWINVER=0x0601 -D_WIN32_WINNT=0x0601
-DHAVE_PATHDEF -DFEAT_HUGE -DHAVE_STDINT_H -D__USE_MINGW_ANSI_STDIO
-pipe -Wall -Wno-deprecated-declarations -D_REENTRANT -U_FORTIFY_SOURCE
-D_FORTIFY_SOURCE=1 -Wall -Wextra -Wshadow -Wstrict-prototypes
-Wmissing-prototypes -Wno-deprecated-declarations
-Wno-error=missing-field-initializers -Werror=uninitialized
-Wunused-but-set-variable -DEXITFREE -DFEAT_GUI_MSWIN -DFEAT_CLIPBOARD
gui_w32.c -o gobjx86-64/gui_w32.o
gui_w32.c:5038:55: warning: comparison of integers of different signs:
'UINT' (aka 'unsigned int') and 'int' [-Wsign-compare]
5038 | && GetMenuState(s_menuBar, pMenu->id, MF_BYCOMMAND) != -1)
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^ ~~
gui_w32.c:5054:26: warning: unused parameter 'hwnd' [-Wunused-parameter]
5054 | _OnGetDpiScaledSize(HWND hwnd, UINT dpi, SIZE *size)
| ^
2 warnings generated.
```
This commit contains the following changes:
- Fixes Warning 1:
The prototype of `GetMenuState()` says that it returns a UINT, but
returns -1 on failure. Huh?!?
Also, Microsoft says that this function has been superseded (see
https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getmenustate)
and replaced by `GetMenuItemInfo()`. Both of these functions have a
minimum support of Windows 2000.
Therefore in `_OnMenuSelect()`, replace the call to `GetMenuState()`
with `GetMenuItemInfo()`.
- Fixes Warning 2:
Add `UNUSED` to the definition of `_OnGetDpiScaledSize()`.
- Simplify `logfont2name()`.
- Add small optimisations in `_OnNotify()` and `gui_mch_do_spawn()`.
- Add out-of-memory check in `gui_mch_do_spawn()`.
- Code cosmetics (see definitions of `process_message_usual_key_classic()`
and `process_message()`).
closes: #17208
Signed-off-by: John Marriott <basilisk@internode.on.net>
Signed-off-by: Christian Brabandt <cb@256bit.org>
diff --git a/src/gui_w32.c b/src/gui_w32.c
index 0debae9..4e6eca8 100644
--- a/src/gui_w32.c
+++ b/src/gui_w32.c
@@ -2157,7 +2157,8 @@
* Experimental implementation, introduced in v8.2.4807
* "processing key event in Win32 GUI is not ideal"
*/
-static void process_message_usual_key_experimental(UINT vk, const MSG *pmsg)
+ static void
+process_message_usual_key_experimental(UINT vk, const MSG *pmsg)
{
WCHAR ch[8];
int len;
@@ -2237,7 +2238,8 @@
/*
* "Classic" implementation, existing prior to v8.2.4807
*/
-static void process_message_usual_key_classic(UINT vk, const MSG *pmsg)
+ static void
+process_message_usual_key_classic(UINT vk, const MSG *pmsg)
{
char_u string[40];
@@ -3673,12 +3675,11 @@
static char_u *
logfont2name(LOGFONTW lf)
{
- char *p;
- char *res;
char *charset_name;
char *quality_name;
char *font_name;
- int points;
+ size_t res_size;
+ char *res;
font_name = (char *)utf16_to_enc(lf.lfFaceName, NULL);
if (font_name == NULL)
@@ -3686,43 +3687,48 @@
charset_name = charset_id2name((int)lf.lfCharSet);
quality_name = quality_id2name((int)lf.lfQuality);
- res = alloc(strlen(font_name) + 30
- + (charset_name == NULL ? 0 : strlen(charset_name) + 2)
- + (quality_name == NULL ? 0 : strlen(quality_name) + 2));
+ res_size = STRLEN(font_name) + 30
+ + (charset_name == NULL ? 0 : STRLEN(charset_name) + 2)
+ + (quality_name == NULL ? 0 : STRLEN(quality_name) + 2);
+ res = alloc(res_size);
if (res != NULL)
{
- p = res;
+ char *p;
+ int points;
+ size_t res_len;
+
+ // replace spaces in font_name with underscores.
+ for (p = font_name; *p != NUL; ++p)
+ {
+ if (isspace(*p))
+ *p = '_';
+ }
+
// make a normal font string out of the lf thing:
points = pixels_to_points(
lf.lfHeight < 0 ? -lf.lfHeight : lf.lfHeight, TRUE);
if (lf.lfWeight == FW_NORMAL || lf.lfWeight == FW_BOLD)
- sprintf((char *)p, "%s:h%d", font_name, points);
+ res_len = vim_snprintf_safelen(
+ (char *)res, res_size, "%s:h%d", font_name, points);
else
- sprintf((char *)p, "%s:h%d:W%ld", font_name, points, lf.lfWeight);
- while (*p)
- {
- if (*p == ' ')
- *p = '_';
- ++p;
- }
- if (lf.lfItalic)
- STRCAT(p, ":i");
- if (lf.lfWeight == FW_BOLD)
- STRCAT(p, ":b");
- if (lf.lfUnderline)
- STRCAT(p, ":u");
- if (lf.lfStrikeOut)
- STRCAT(p, ":s");
+ res_len = vim_snprintf_safelen(
+ (char *)res, res_size, "%s:h%d:W%ld", font_name, points, lf.lfWeight);
+
+ res_len += vim_snprintf_safelen(
+ (char *)res + res_len,
+ res_size - res_len,
+ "%s%s%s%s",
+ lf.lfItalic ? ":i" : "",
+ lf.lfWeight ? ":b" : "",
+ lf.lfUnderline ? ":u" : "",
+ lf.lfStrikeOut ? ":s" : "");
+
if (charset_name != NULL)
- {
- STRCAT(p, ":c");
- STRCAT(p, charset_name);
- }
+ res_len += vim_snprintf_safelen((char *)res + res_len,
+ res_size - res_len, ":c%s", charset_name);
if (quality_name != NULL)
- {
- STRCAT(p, ":q");
- STRCAT(p, quality_name);
- }
+ vim_snprintf((char *)res + res_len,
+ res_size - res_len, ":q%s", quality_name);
}
vim_free(font_name);
@@ -4975,9 +4981,10 @@
else
{
LPNMTTDISPINFO lpdi = (LPNMTTDISPINFO)hdr;
+ size_t len = STRLEN(str);
- if (STRLEN(str) < sizeof(lpdi->szText)
- || ((tt_text = vim_strsave(str)) == NULL))
+ if (len < sizeof(lpdi->szText)
+ || ((tt_text = vim_strnsave(str, len)) == NULL))
vim_strncpy((char_u *)lpdi->szText, str,
sizeof(lpdi->szText) - 1);
else
@@ -5020,7 +5027,6 @@
== MF_HILITE
&& (State & MODE_CMDLINE) == 0)
{
- UINT idButton;
vimmenu_T *pMenu;
static int did_menu_tip = FALSE;
@@ -5032,17 +5038,23 @@
did_menu_tip = FALSE;
}
- idButton = (UINT)LOWORD(wParam);
- pMenu = gui_mswin_find_menu(root_menu, idButton);
- if (pMenu != NULL && pMenu->strings[MENU_INDEX_TIP] != 0
- && GetMenuState(s_menuBar, pMenu->id, MF_BYCOMMAND) != -1)
+ pMenu = gui_mswin_find_menu(root_menu, (UINT)LOWORD(wParam));
+ if (pMenu != NULL && pMenu->strings[MENU_INDEX_TIP] != NULL)
{
- ++msg_hist_off;
- msg((char *)pMenu->strings[MENU_INDEX_TIP]);
- --msg_hist_off;
- setcursor();
- out_flush();
- did_menu_tip = TRUE;
+ MENUITEMINFO menuinfo;
+
+ menuinfo.cbSize = sizeof(MENUITEMINFO);
+ menuinfo.fMask = MIIM_ID; // We only want to check if the menu item exists,
+ // so retrieve something simple.
+ if (GetMenuItemInfo(s_menuBar, pMenu->id, FALSE, &menuinfo))
+ {
+ ++msg_hist_off;
+ msg((char *)pMenu->strings[MENU_INDEX_TIP]);
+ --msg_hist_off;
+ setcursor();
+ out_flush();
+ did_menu_tip = TRUE;
+ }
}
return 0L;
}
@@ -5051,7 +5063,7 @@
#endif
static BOOL
-_OnGetDpiScaledSize(HWND hwnd, UINT dpi, SIZE *size)
+_OnGetDpiScaledSize(HWND hwnd UNUSED, UINT dpi, SIZE *size)
{
int old_width, old_height;
int new_width, new_height;
@@ -5394,7 +5406,12 @@
if (session == NULL)
goto error;
savebg = p_bg;
- p_bg = vim_strsave((char_u *)"light"); // Set 'bg' to "light".
+ p_bg = vim_strnsave((char_u *)"light", 5); // Set 'bg' to "light".
+ if (p_bg == NULL)
+ {
+ p_bg = savebg;
+ goto error;
+ }
ret = write_session_file(session);
vim_free(p_bg);
p_bg = savebg;