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 |