diff --git a/4J_Input/Windows64/4J_Input.cpp b/4J_Input/Windows64/4J_Input.cpp index 14708b2..063b444 100644 --- a/4J_Input/Windows64/4J_Input.cpp +++ b/4J_Input/Windows64/4J_Input.cpp @@ -254,11 +254,26 @@ bool C_4JInput::HasChar() const return InternalKeyboard.HasChar(); } +int C_4JInput::GetCharCount() const +{ + return InternalKeyboard.GetCharCount(); +} + wchar_t C_4JInput::GetChar(int index) const { return InternalKeyboard.GetChar(index); } +int C_4JInput::GetClipboardText(wchar_t *outText, int outCapacity) const +{ + return InternalKeyboard.GetClipboardText(outText, outCapacity); +} + +bool C_4JInput::SetClipboardText(const wchar_t *text) const +{ + return InternalKeyboard.SetClipboardText(text); +} + void C_4JInput::OnMouseMove(int x, int y) { InternalKeyboard.OnMouseMove(x, y); diff --git a/4J_Input/Windows64/INP_Keyboard.cpp b/4J_Input/Windows64/INP_Keyboard.cpp index ed4ee43..8a8967c 100644 --- a/4J_Input/Windows64/INP_Keyboard.cpp +++ b/4J_Input/Windows64/INP_Keyboard.cpp @@ -103,6 +103,55 @@ void CKeyboard::OnChar(wchar_t ch) } } +int CKeyboard::GetClipboardText(wchar_t *outText, int outCapacity) const +{ + if (!outText || outCapacity <= 0) + return 0; + outText[0] = 0; + if (!OpenClipboard(g_hWnd)) + return 0; + int copied = 0; + HANDLE h = GetClipboardData(CF_UNICODETEXT); + if (h) + { + const wchar_t *src = (const wchar_t *)GlobalLock(h); + if (src) + { + while (src[copied] && copied + 1 < outCapacity) + { + outText[copied] = src[copied]; + ++copied; + } + outText[copied] = 0; + GlobalUnlock(h); + } + } + CloseClipboard(); + return copied; +} + +bool CKeyboard::SetClipboardText(const wchar_t *text) const +{ + if (!text) + return false; + size_t len = wcslen(text); + if (!OpenClipboard(g_hWnd)) + return false; + EmptyClipboard(); + bool ok = false; + HGLOBAL h = GlobalAlloc(GMEM_MOVEABLE, (len + 1) * sizeof(wchar_t)); + if (h) + { + memcpy(GlobalLock(h), text, (len + 1) * sizeof(wchar_t)); + GlobalUnlock(h); + ok = (SetClipboardData(CF_UNICODETEXT, h) != NULL); + if (!ok) + GlobalFree(h); + } + CloseClipboard(); + return ok; +} + bool CKeyboard::IsKeyDown(int vkCode) const { if (vkCode >= 0 && vkCode < MAX_KEYS) @@ -215,6 +264,8 @@ void CKeyboard::SetMouseCaptured(bool grabbed) } else if (!grabbed && g_hWnd) { + // Show the system cursor whenever the mouse is free so it can be used as the UI pointer; + // the game's flash/custom cursors are hidden on Windows64 while the OS mouse is driving. while (ShowCursor(TRUE) < 0) {} ClipCursor(nullptr); } diff --git a/4J_Input/Windows64/INP_Keyboard.h b/4J_Input/Windows64/INP_Keyboard.h index 1e3a021..7ac480e 100644 --- a/4J_Input/Windows64/INP_Keyboard.h +++ b/4J_Input/Windows64/INP_Keyboard.h @@ -84,6 +84,12 @@ public: int GetCharCount() const { return m_charCount; } wchar_t GetChar(int index) const { return (index >= 0 && index < m_charCount) ? m_charBuffer[index] : 0; } + // System clipboard (UTF-16). Get returns chars copied excluding the + // terminator, 0 when unavailable. All input routing stays in the lib + // so future per-device (splitscreen KBM) plumbing has one place to land. + int GetClipboardText(wchar_t *outText, int outCapacity) const; + bool SetClipboardText(const wchar_t *text) const; + void SetMouseCaptured(bool captured); void SetWindowFocused(bool focused); bool IsMouseCaptured() const { return m_mouseCaptured; } diff --git a/Headers/Windows64/4J_Input.h b/Headers/Windows64/4J_Input.h index 38b10c3..5b15dbd 100644 --- a/Headers/Windows64/4J_Input.h +++ b/Headers/Windows64/4J_Input.h @@ -169,6 +169,11 @@ public: int GetCharCount() const; wchar_t GetChar(int index) const; + // System clipboard (UTF-16). GetClipboardText returns chars copied + // excluding the terminator, 0 when unavailable. + int GetClipboardText(wchar_t *outText, int outCapacity) const; + bool SetClipboardText(const wchar_t *text) const; + void SetMouseCaptured(bool captured); void SetWindowFocused(bool focused); bool IsMouseCaptured() const;