[Spice-devel] [PATCH win32/vd_agent] Handling keyboard description message
Pavel Grunt
pgrunt at redhat.com
Wed Nov 5 02:44:53 PST 2014
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
More information about the Spice-devel
mailing list