diff --git a/dlls/user32/input.c b/dlls/user32/input.c index abd382f1308..050fb2b03b9 100644 --- a/dlls/user32/input.c +++ b/dlls/user32/input.c @@ -823,7 +823,7 @@ INT WINAPI GetKeyNameTextA(LONG lParam, LPSTR lpBuffer, INT nSize) WCHAR buf[256]; INT ret; - if (!GetKeyNameTextW(lParam, buf, 256)) + if (!nSize || !GetKeyNameTextW(lParam, buf, 256)) { lpBuffer[0] = 0; return 0; @@ -834,6 +834,8 @@ INT WINAPI GetKeyNameTextA(LONG lParam, LPSTR lpBuffer, INT nSize) ret = nSize - 1; lpBuffer[ret] = 0; } + else ret--; + return ret; } @@ -842,6 +844,7 @@ INT WINAPI GetKeyNameTextA(LONG lParam, LPSTR lpBuffer, INT nSize) */ INT WINAPI GetKeyNameTextW(LONG lParam, LPWSTR lpBuffer, INT nSize) { + if (!lpBuffer || !nSize) return 0; return USER_Driver->pGetKeyNameText( lParam, lpBuffer, nSize ); } diff --git a/dlls/user32/tests/input.c b/dlls/user32/tests/input.c index 748ed2613e3..cb090dd7309 100644 --- a/dlls/user32/tests/input.c +++ b/dlls/user32/tests/input.c @@ -1603,6 +1603,46 @@ static void test_keyboard_layout_name(void) ok(!strcmp(klid, "00000409"), "expected 00000409, got %s\n", klid); } +static void test_key_names(void) +{ + char buffer[40]; + WCHAR bufferW[40]; + int ret, prev; + LONG lparam = 0x1d << 16; + + memset( buffer, 0xcc, sizeof(buffer) ); + ret = GetKeyNameTextA( lparam, buffer, sizeof(buffer) ); + ok( ret > 0, "wrong len %u for '%s'\n", ret, buffer ); + ok( ret == strlen(buffer), "wrong len %u for '%s'\n", ret, buffer ); + + memset( buffer, 0xcc, sizeof(buffer) ); + prev = ret; + ret = GetKeyNameTextA( lparam, buffer, prev ); + ok( ret == prev - 1, "wrong len %u for '%s'\n", ret, buffer ); + ok( ret == strlen(buffer), "wrong len %u for '%s'\n", ret, buffer ); + + memset( buffer, 0xcc, sizeof(buffer) ); + ret = GetKeyNameTextA( lparam, buffer, 0 ); + ok( ret == 0, "wrong len %u for '%s'\n", ret, buffer ); + ok( buffer[0] == 0, "wrong string '%s'\n", buffer ); + + memset( bufferW, 0xcc, sizeof(bufferW) ); + ret = GetKeyNameTextW( lparam, bufferW, sizeof(bufferW)/sizeof(WCHAR) ); + ok( ret > 0, "wrong len %u for %s\n", ret, wine_dbgstr_w(bufferW) ); + ok( ret == lstrlenW(bufferW), "wrong len %u for %s\n", ret, wine_dbgstr_w(bufferW) ); + + memset( bufferW, 0xcc, sizeof(bufferW) ); + prev = ret; + ret = GetKeyNameTextW( lparam, bufferW, prev ); + ok( ret == prev - 1, "wrong len %u for %s\n", ret, wine_dbgstr_w(bufferW) ); + ok( ret == lstrlenW(bufferW), "wrong len %u for %s\n", ret, wine_dbgstr_w(bufferW) ); + + memset( bufferW, 0xcc, sizeof(bufferW) ); + ret = GetKeyNameTextW( lparam, bufferW, 0 ); + ok( ret == 0, "wrong len %u for %s\n", ret, wine_dbgstr_w(bufferW) ); + ok( bufferW[0] == 0xcccc, "wrong string %s\n", wine_dbgstr_w(bufferW) ); +} + START_TEST(input) { init_function_pointers(); @@ -1621,6 +1661,7 @@ START_TEST(input) test_ToUnicode(); test_get_async_key_state(); test_keyboard_layout_name(); + test_key_names(); if(pGetMouseMovePointsEx) test_GetMouseMovePointsEx(); diff --git a/dlls/winex11.drv/keyboard.c b/dlls/winex11.drv/keyboard.c index 57deb59b2cf..3b91d8faf46 100644 --- a/dlls/winex11.drv/keyboard.c +++ b/dlls/winex11.drv/keyboard.c @@ -2291,7 +2291,7 @@ INT CDECL X11DRV_GetKeyNameText(LONG lParam, LPWSTR lpBuffer, INT nSize) (scanCode != 0x4a ) && /* numpad - */ (scanCode != 0x4e ) ) /* numpad + */ { - if ((nSize >= 2) && lpBuffer) + if (nSize >= 2) { *lpBuffer = toupperW((WCHAR)ansi); *(lpBuffer+1) = 0; @@ -2318,6 +2318,8 @@ INT CDECL X11DRV_GetKeyNameText(LONG lParam, LPWSTR lpBuffer, INT nSize) break; if (keyi <= max_keycode) { + INT rc; + wine_tsx11_lock(); keyc = (KeyCode) keyi; keys = keycode_to_keysym(display, keyc, 0); @@ -2329,29 +2331,30 @@ INT CDECL X11DRV_GetKeyNameText(LONG lParam, LPWSTR lpBuffer, INT nSize) char* idx = strrchr(name, '_'); if (idx && (strcasecmp(idx, "_r") == 0 || strcasecmp(idx, "_l") == 0)) { - INT rc = 0; TRACE("found scan=%04x keyc=%u keysym=%lx modified_string=%s\n", scanCode, keyc, keys, debugstr_an(name,idx-name)); - if (lpBuffer && nSize) - { - rc = MultiByteToWideChar(CP_UNIXCP, 0, name, idx-name+1, lpBuffer, nSize); - if (rc > 0) lpBuffer[rc - 1] = 0; - } + rc = MultiByteToWideChar(CP_UNIXCP, 0, name, idx-name+1, lpBuffer, nSize); + if (!rc) rc = nSize; + lpBuffer[--rc] = 0; return rc; } } - TRACE("found scan=%04x keyc=%u keysym=%04x string=%s\n", - scanCode, keyc, (int)keys, debugstr_a(name)); - if (lpBuffer && nSize && name) - return MultiByteToWideChar(CP_UNIXCP, 0, name, -1, lpBuffer, nSize); + if (name) + { + TRACE("found scan=%04x keyc=%u keysym=%04x vkey=%04x string=%s\n", + scanCode, keyc, (int)keys, vkey, debugstr_a(name)); + rc = MultiByteToWideChar(CP_UNIXCP, 0, name, -1, lpBuffer, nSize); + if (!rc) rc = nSize; + lpBuffer[--rc] = 0; + return rc; + } } /* Finally issue WARN for unknown keys */ WARN("(%08x,%p,%d): unsupported key, vkey=%04X, ansi=%04x\n",lParam,lpBuffer,nSize,vkey,ansi); - if (lpBuffer && nSize) - *lpBuffer = 0; + *lpBuffer = 0; return 0; }