diff options
author | Yaniv Kamay <ykamay@redhat.com> | 2009-11-21 19:28:59 +0200 |
---|---|---|
committer | Yaniv Kamay <ykamay@redhat.com> | 2009-11-30 18:22:13 +0200 |
commit | 6c5966d8ed8ff248ca21900aaf2350aac87f68e4 (patch) | |
tree | a210b657ee7f2815aeabad400b9bfa946cde50fb /client/x11/red_window.cpp | |
parent | 81241dd8251078fb049d35b7bc8a6c4dcfb6fa98 (diff) | |
download | spice-6c5966d8ed8ff248ca21900aaf2350aac87f68e4.tar.gz spice-6c5966d8ed8ff248ca21900aaf2350aac87f68e4.tar.xz spice-6c5966d8ed8ff248ca21900aaf2350aac87f68e4.zip |
client: KeyHandler now receive unicode char event in addition to RedKey events
Diffstat (limited to 'client/x11/red_window.cpp')
-rw-r--r-- | client/x11/red_window.cpp | 48 |
1 files changed, 47 insertions, 1 deletions
diff --git a/client/x11/red_window.cpp b/client/x11/red_window.cpp index 1d989b7c..2f17cb1d 100644 --- a/client/x11/red_window.cpp +++ b/client/x11/red_window.cpp @@ -54,6 +54,7 @@ static Display* x_display = NULL; static XContext user_data_context; static bool using_evdev = false; +static XIC x_input_context = NULL; static Atom wm_protocol_atom; static Atom wm_delete_window_atom; @@ -711,6 +712,49 @@ static inline RedButton to_red_button(unsigned int botton, unsigned int& state, return ret; } +void RedWindow_p::handle_key_press_event(RedWindow& window, XKeyEvent* event) +{ + static int buf_size = 0; + static char* utf8_buf = NULL; + static wchar_t* utf32_buf = NULL; + + KeySym key_sym; + Status status; + int len; + + window.get_listener().on_key_press(to_red_key_code(event->keycode)); + for (;;) { + len = XwcLookupString(x_input_context, event, utf32_buf, buf_size, &key_sym, &status); + if (status != XBufferOverflow) { + break; + } + + free(utf32_buf); + free(utf32_buf); + utf8_buf = new char[len]; + utf32_buf = new wchar_t[len]; + buf_size = len; + } + + switch (status) { + case XLookupChars: + case XLookupBoth: { + uint32_t* now = (uint32_t*)utf32_buf; + uint32_t* end = now + len; + + for (; now < end; now++) { + window.get_listener().on_char(*now); + } + break; + } + case XLookupNone: + case XLookupKeySym: + break; + default: + THROW("unexpected status %d", status); + } +} + void RedWindow_p::win_proc(XEvent& event) { XPointer window_pointer; @@ -733,7 +777,7 @@ void RedWindow_p::win_proc(XEvent& event) break; } case KeyPress: - red_window->get_listener().on_key_press(to_red_key_code(event.xkey.keycode)); + red_window->handle_key_press_event(*red_window, &event.xkey); break; case KeyRelease: { RedKey key = to_red_key_code(event.xkey.keycode); @@ -1925,6 +1969,7 @@ void RedWindow::on_focus_in() return; } _focused = true; + XwcResetIC(x_input_context); XPlatform::on_focus_in(); get_listener().on_activate(); if (_trace_key_interception && _pointer_in_window) { @@ -1976,6 +2021,7 @@ void RedWindow::set_menu(Menu* menu) void RedWindow::init() { x_display = XPlatform::get_display(); + x_input_context = XPlatform::get_input_context(); ASSERT(x_display); user_data_context = XUniqueContext(); |