The agent tries to find the appropriate keyboard layout and loads it into the language bar when the message is received. RFE: https://bugs.freedesktop.org/show_bug.cgi?id=85332 --- depends on: http://lists.freedesktop.org/archives/spice-devel/2014-November/017821.html --- vdagent/vdagent.cpp | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/vdagent/vdagent.cpp b/vdagent/vdagent.cpp index aa44383..e299d97 100644 --- a/vdagent/vdagent.cpp +++ b/vdagent/vdagent.cpp @@ -93,6 +93,7 @@ private: void handle_clipboard_release(); bool handle_display_config(VDAgentDisplayConfig* display_config, uint32_t port); bool handle_max_clipboard(VDAgentMaxClipboard *msg, uint32_t size); + void handle_keyboard_description(char *msg, uint32_t size); void handle_chunk(VDIChunk* chunk); void on_clipboard_grab(); void on_clipboard_request(UINT format); @@ -104,6 +105,7 @@ private: static DWORD WINAPI event_thread_proc(LPVOID param); static VOID CALLBACK read_completion(DWORD err, DWORD bytes, LPOVERLAPPED overlapped); static VOID CALLBACK write_completion(DWORD err, DWORD bytes, LPOVERLAPPED overlapped); + static BOOL CALLBACK setup_keyboard_layout(LPTSTR lpLocaleString); void dispatch_message(VDAgentMessage* msg, uint32_t port); uint32_t get_clipboard_format(uint32_t type); uint32_t get_clipboard_type(uint32_t format); @@ -161,6 +163,7 @@ private: mutex_t _message_mutex; std::queue<int> _control_queue; std::queue<VDIChunk*> _message_queue; + WCHAR* _keyboard_locale; bool _logon_desktop; bool _display_setting_initialized; @@ -898,6 +901,20 @@ bool VDAgent::handle_max_clipboard(VDAgentMaxClipboard *msg, uint32_t size) return true; } +void VDAgent::handle_keyboard_description(char *msg, uint32_t size) +{ + int req_size; + + if ((req_size = MultiByteToWideChar(CP_UTF8, 0, msg, size, NULL, 0)) == 0) + return; + + _keyboard_locale = new WCHAR[req_size]; + + if (MultiByteToWideChar(CP_UTF8, 0, msg, size, _keyboard_locale, req_size)) + EnumSystemLocales(setup_keyboard_layout, LCID_INSTALLED); + delete [] _keyboard_locale; +} + #define MIN(a, b) ((a) > (b) ? (b) : (a)) bool VDAgent::write_clipboard(VDAgentMessage* msg, uint32_t size) @@ -1294,6 +1311,9 @@ void VDAgent::dispatch_message(VDAgentMessage* msg, uint32_t port) case VD_AGENT_MAX_CLIPBOARD: res = handle_max_clipboard((VDAgentMaxClipboard*)msg->data, msg->size); break; + case VD_AGENT_KEYBOARD_DESCRIPTION: + handle_keyboard_description((char *) msg->data, msg->size); + break; default: vd_printf("Unsupported message type %u size %u", msg->type, msg->size); } @@ -1381,6 +1401,31 @@ void VDAgent::handle_chunk(VDIChunk* chunk) } } +BOOL VDAgent::setup_keyboard_layout(LPTSTR lpLocaleString) +{ + WCHAR country_name[KL_NAMELENGTH], *fnd; + LCID lcid; + int len; + VDAgent *a = _singleton; + + if (lpLocaleString == NULL) + return FALSE; + + lcid = _tcstol(lpLocaleString, NULL, 16); + GetLocaleInfoW(lcid, LOCALE_SISO3166CTRYNAME, country_name, KL_NAMELENGTH); + CharLowerW(country_name); + + len = wcslen(country_name); + fnd = wcsstr(a->_keyboard_locale, country_name); + if (fnd != NULL && + (fnd == a->_keyboard_locale || !IsCharAlphaW(*CharPrevW(a->_keyboard_locale, fnd))) && + !IsCharAlphaW(*(fnd+len))) { + LoadKeyboardLayout(lpLocaleString, 0); + } + + return TRUE; +} + void VDAgent::cleanup_in_msg() { _in_msg_pos = 0; -- 1.9.3 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/spice-devel