| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/ui/libgtkui/x11_input_method_context_impl_gtk.h" | 5 #include "chrome/browser/ui/libgtkui/x11_input_method_context_impl_gtk.h" |
| 6 | 6 |
| 7 #include <gdk/gdk.h> | 7 #include <gdk/gdk.h> |
| 8 #include <gdk/gdkkeysyms.h> | 8 #include <gdk/gdkkeysyms.h> |
| 9 #include <gdk/gdkx.h> | 9 #include <gdk/gdkx.h> |
| 10 #include <stddef.h> | 10 #include <stddef.h> |
| (...skipping 13 matching lines...) Expand all Loading... |
| 24 #include "ui/gfx/geometry/dip_util.h" | 24 #include "ui/gfx/geometry/dip_util.h" |
| 25 #include "ui/gfx/x/x11_types.h" | 25 #include "ui/gfx/x/x11_types.h" |
| 26 #include "ui/views/linux_ui/linux_ui.h" | 26 #include "ui/views/linux_ui/linux_ui.h" |
| 27 | 27 |
| 28 namespace libgtkui { | 28 namespace libgtkui { |
| 29 | 29 |
| 30 X11InputMethodContextImplGtk2::X11InputMethodContextImplGtk2( | 30 X11InputMethodContextImplGtk2::X11InputMethodContextImplGtk2( |
| 31 ui::LinuxInputMethodContextDelegate* delegate, | 31 ui::LinuxInputMethodContextDelegate* delegate, |
| 32 bool is_simple) | 32 bool is_simple) |
| 33 : delegate_(delegate), | 33 : delegate_(delegate), |
| 34 gtk_context_(NULL), | 34 gtk_context_(nullptr), |
| 35 gdk_last_set_client_window_(NULL) { | 35 gdk_last_set_client_window_(nullptr) { |
| 36 CHECK(delegate_); | 36 CHECK(delegate_); |
| 37 | 37 |
| 38 ResetXModifierKeycodesCache(); | 38 ResetXModifierKeycodesCache(); |
| 39 | 39 |
| 40 gtk_context_ = | 40 gtk_context_ = |
| 41 is_simple ? gtk_im_context_simple_new() : gtk_im_multicontext_new(); | 41 is_simple ? gtk_im_context_simple_new() : gtk_im_multicontext_new(); |
| 42 | 42 |
| 43 g_signal_connect(gtk_context_, "commit", G_CALLBACK(OnCommitThunk), this); | 43 g_signal_connect(gtk_context_, "commit", G_CALLBACK(OnCommitThunk), this); |
| 44 g_signal_connect(gtk_context_, "preedit-changed", | 44 g_signal_connect(gtk_context_, "preedit-changed", |
| 45 G_CALLBACK(OnPreeditChangedThunk), this); | 45 G_CALLBACK(OnPreeditChangedThunk), this); |
| 46 g_signal_connect(gtk_context_, "preedit-end", G_CALLBACK(OnPreeditEndThunk), | 46 g_signal_connect(gtk_context_, "preedit-end", G_CALLBACK(OnPreeditEndThunk), |
| 47 this); | 47 this); |
| 48 g_signal_connect(gtk_context_, "preedit-start", | 48 g_signal_connect(gtk_context_, "preedit-start", |
| 49 G_CALLBACK(OnPreeditStartThunk), this); | 49 G_CALLBACK(OnPreeditStartThunk), this); |
| 50 // TODO(shuchen): Handle operations on surrounding text. | 50 // TODO(shuchen): Handle operations on surrounding text. |
| 51 // "delete-surrounding" and "retrieve-surrounding" signals should be | 51 // "delete-surrounding" and "retrieve-surrounding" signals should be |
| 52 // handled. | 52 // handled. |
| 53 } | 53 } |
| 54 | 54 |
| 55 X11InputMethodContextImplGtk2::~X11InputMethodContextImplGtk2() { | 55 X11InputMethodContextImplGtk2::~X11InputMethodContextImplGtk2() { |
| 56 if (gtk_context_) { | 56 if (gtk_context_) { |
| 57 g_object_unref(gtk_context_); | 57 g_object_unref(gtk_context_); |
| 58 gtk_context_ = NULL; | 58 gtk_context_ = nullptr; |
| 59 } | 59 } |
| 60 } | 60 } |
| 61 | 61 |
| 62 // Overriden from ui::LinuxInputMethodContext | 62 // Overriden from ui::LinuxInputMethodContext |
| 63 | 63 |
| 64 bool X11InputMethodContextImplGtk2::DispatchKeyEvent( | 64 bool X11InputMethodContextImplGtk2::DispatchKeyEvent( |
| 65 const ui::KeyEvent& key_event) { | 65 const ui::KeyEvent& key_event) { |
| 66 if (!key_event.HasNativeEvent() || !gtk_context_) | 66 if (!key_event.HasNativeEvent() || !gtk_context_) |
| 67 return false; | 67 return false; |
| 68 | 68 |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 181 XKeyEvent& xkey = xkeyevent.xkey; | 181 XKeyEvent& xkey = xkeyevent.xkey; |
| 182 | 182 |
| 183 // Get a GdkDisplay. | 183 // Get a GdkDisplay. |
| 184 GdkDisplay* display = gdk_x11_lookup_xdisplay(xkey.display); | 184 GdkDisplay* display = gdk_x11_lookup_xdisplay(xkey.display); |
| 185 if (!display) { | 185 if (!display) { |
| 186 // Fall back to the default display. | 186 // Fall back to the default display. |
| 187 display = gdk_display_get_default(); | 187 display = gdk_display_get_default(); |
| 188 } | 188 } |
| 189 if (!display) { | 189 if (!display) { |
| 190 LOG(ERROR) << "Cannot get a GdkDisplay for a key event."; | 190 LOG(ERROR) << "Cannot get a GdkDisplay for a key event."; |
| 191 return NULL; | 191 return nullptr; |
| 192 } | 192 } |
| 193 // Get a keysym and group. | 193 // Get a keysym and group. |
| 194 KeySym keysym = NoSymbol; | 194 KeySym keysym = NoSymbol; |
| 195 guint8 keyboard_group = 0; | 195 guint8 keyboard_group = 0; |
| 196 XLookupString(&xkey, NULL, 0, &keysym, NULL); | 196 XLookupString(&xkey, nullptr, 0, &keysym, nullptr); |
| 197 GdkKeymap* keymap = gdk_keymap_get_for_display(display); | 197 GdkKeymap* keymap = gdk_keymap_get_for_display(display); |
| 198 GdkKeymapKey* keys = NULL; | 198 GdkKeymapKey* keys = nullptr; |
| 199 guint* keyvals = NULL; | 199 guint* keyvals = nullptr; |
| 200 gint n_entries = 0; | 200 gint n_entries = 0; |
| 201 if (keymap && gdk_keymap_get_entries_for_keycode(keymap, xkey.keycode, &keys, | 201 if (keymap && gdk_keymap_get_entries_for_keycode(keymap, xkey.keycode, &keys, |
| 202 &keyvals, &n_entries)) { | 202 &keyvals, &n_entries)) { |
| 203 for (gint i = 0; i < n_entries; ++i) { | 203 for (gint i = 0; i < n_entries; ++i) { |
| 204 if (keyvals[i] == keysym) { | 204 if (keyvals[i] == keysym) { |
| 205 keyboard_group = keys[i].group; | 205 keyboard_group = keys[i].group; |
| 206 break; | 206 break; |
| 207 } | 207 } |
| 208 } | 208 } |
| 209 } | 209 } |
| 210 g_free(keys); | 210 g_free(keys); |
| 211 keys = NULL; | 211 keys = nullptr; |
| 212 g_free(keyvals); | 212 g_free(keyvals); |
| 213 keyvals = NULL; | 213 keyvals = nullptr; |
| 214 // Get a GdkWindow. | 214 // Get a GdkWindow. |
| 215 #if GTK_CHECK_VERSION(2, 24, 0) | 215 #if GTK_CHECK_VERSION(2, 24, 0) |
| 216 GdkWindow* window = gdk_x11_window_lookup_for_display(display, xkey.window); | 216 GdkWindow* window = gdk_x11_window_lookup_for_display(display, xkey.window); |
| 217 #else | 217 #else |
| 218 GdkWindow* window = gdk_window_lookup_for_display(display, xkey.window); | 218 GdkWindow* window = gdk_window_lookup_for_display(display, xkey.window); |
| 219 #endif | 219 #endif |
| 220 if (window) | 220 if (window) |
| 221 g_object_ref(window); | 221 g_object_ref(window); |
| 222 else | 222 else |
| 223 #if GTK_CHECK_VERSION(2, 24, 0) | 223 #if GTK_CHECK_VERSION(2, 24, 0) |
| 224 window = gdk_x11_window_foreign_new_for_display(display, xkey.window); | 224 window = gdk_x11_window_foreign_new_for_display(display, xkey.window); |
| 225 #else | 225 #else |
| 226 window = gdk_window_foreign_new_for_display(display, xkey.window); | 226 window = gdk_window_foreign_new_for_display(display, xkey.window); |
| 227 #endif | 227 #endif |
| 228 if (!window) { | 228 if (!window) { |
| 229 LOG(ERROR) << "Cannot get a GdkWindow for a key event."; | 229 LOG(ERROR) << "Cannot get a GdkWindow for a key event."; |
| 230 return NULL; | 230 return nullptr; |
| 231 } | 231 } |
| 232 | 232 |
| 233 // Create a GdkEvent. | 233 // Create a GdkEvent. |
| 234 GdkEventType event_type = | 234 GdkEventType event_type = |
| 235 xkey.type == KeyPress ? GDK_KEY_PRESS : GDK_KEY_RELEASE; | 235 xkey.type == KeyPress ? GDK_KEY_PRESS : GDK_KEY_RELEASE; |
| 236 GdkEvent* event = gdk_event_new(event_type); | 236 GdkEvent* event = gdk_event_new(event_type); |
| 237 event->key.type = event_type; | 237 event->key.type = event_type; |
| 238 event->key.window = window; | 238 event->key.window = window; |
| 239 // GdkEventKey and XKeyEvent share the same definition for time and state. | 239 // GdkEventKey and XKeyEvent share the same definition for time and state. |
| 240 event->key.send_event = xkey.send_event; | 240 event->key.send_event = xkey.send_event; |
| 241 event->key.time = xkey.time; | 241 event->key.time = xkey.time; |
| 242 event->key.state = xkey.state; | 242 event->key.state = xkey.state; |
| 243 event->key.keyval = keysym; | 243 event->key.keyval = keysym; |
| 244 event->key.length = 0; | 244 event->key.length = 0; |
| 245 event->key.string = NULL; | 245 event->key.string = nullptr; |
| 246 event->key.hardware_keycode = xkey.keycode; | 246 event->key.hardware_keycode = xkey.keycode; |
| 247 event->key.group = keyboard_group; | 247 event->key.group = keyboard_group; |
| 248 event->key.is_modifier = IsKeycodeModifierKey(xkey.keycode); | 248 event->key.is_modifier = IsKeycodeModifierKey(xkey.keycode); |
| 249 | 249 |
| 250 char keybits[32] = {0}; | 250 char keybits[32] = {0}; |
| 251 XQueryKeymap(xkey.display, keybits); | 251 XQueryKeymap(xkey.display, keybits); |
| 252 if (IsAnyOfKeycodesPressed(meta_keycodes_, keybits, sizeof keybits * 8)) | 252 if (IsAnyOfKeycodesPressed(meta_keycodes_, keybits, sizeof keybits * 8)) |
| 253 event->key.state |= GDK_META_MASK; | 253 event->key.state |= GDK_META_MASK; |
| 254 if (IsAnyOfKeycodesPressed(super_keycodes_, keybits, sizeof keybits * 8)) | 254 if (IsAnyOfKeycodesPressed(super_keycodes_, keybits, sizeof keybits * 8)) |
| 255 event->key.state |= GDK_SUPER_MASK; | 255 event->key.state |= GDK_SUPER_MASK; |
| (...skipping 29 matching lines...) Expand all Loading... |
| 285 if (context != gtk_context_) | 285 if (context != gtk_context_) |
| 286 return; | 286 return; |
| 287 | 287 |
| 288 delegate_->OnCommit(base::UTF8ToUTF16(text)); | 288 delegate_->OnCommit(base::UTF8ToUTF16(text)); |
| 289 } | 289 } |
| 290 | 290 |
| 291 void X11InputMethodContextImplGtk2::OnPreeditChanged(GtkIMContext* context) { | 291 void X11InputMethodContextImplGtk2::OnPreeditChanged(GtkIMContext* context) { |
| 292 if (context != gtk_context_) | 292 if (context != gtk_context_) |
| 293 return; | 293 return; |
| 294 | 294 |
| 295 gchar* str = NULL; | 295 gchar* str = nullptr; |
| 296 PangoAttrList* attrs = NULL; | 296 PangoAttrList* attrs = nullptr; |
| 297 gint cursor_pos = 0; | 297 gint cursor_pos = 0; |
| 298 gtk_im_context_get_preedit_string(context, &str, &attrs, &cursor_pos); | 298 gtk_im_context_get_preedit_string(context, &str, &attrs, &cursor_pos); |
| 299 ui::CompositionText composition_text; | 299 ui::CompositionText composition_text; |
| 300 ui::ExtractCompositionTextFromGtkPreedit(str, attrs, cursor_pos, | 300 ui::ExtractCompositionTextFromGtkPreedit(str, attrs, cursor_pos, |
| 301 &composition_text); | 301 &composition_text); |
| 302 g_free(str); | 302 g_free(str); |
| 303 pango_attr_list_unref(attrs); | 303 pango_attr_list_unref(attrs); |
| 304 | 304 |
| 305 delegate_->OnPreeditChanged(composition_text); | 305 delegate_->OnPreeditChanged(composition_text); |
| 306 } | 306 } |
| 307 | 307 |
| 308 void X11InputMethodContextImplGtk2::OnPreeditEnd(GtkIMContext* context) { | 308 void X11InputMethodContextImplGtk2::OnPreeditEnd(GtkIMContext* context) { |
| 309 if (context != gtk_context_) | 309 if (context != gtk_context_) |
| 310 return; | 310 return; |
| 311 | 311 |
| 312 delegate_->OnPreeditEnd(); | 312 delegate_->OnPreeditEnd(); |
| 313 } | 313 } |
| 314 | 314 |
| 315 void X11InputMethodContextImplGtk2::OnPreeditStart(GtkIMContext* context) { | 315 void X11InputMethodContextImplGtk2::OnPreeditStart(GtkIMContext* context) { |
| 316 if (context != gtk_context_) | 316 if (context != gtk_context_) |
| 317 return; | 317 return; |
| 318 | 318 |
| 319 delegate_->OnPreeditStart(); | 319 delegate_->OnPreeditStart(); |
| 320 } | 320 } |
| 321 | 321 |
| 322 } // namespace libgtkui | 322 } // namespace libgtkui |
| OLD | NEW |