Upstream version 7.35.139.0
[platform/framework/web/crosswalk.git] / src / ui / events / x / events_x.cc
index 9fec9df..d62aeac 100644 (file)
@@ -9,6 +9,7 @@
 #include <X11/extensions/XInput.h>
 #include <X11/extensions/XInput2.h>
 #include <X11/Xlib.h>
+#include <X11/Xutil.h>
 
 #include "base/logging.h"
 #include "base/memory/singleton.h"
@@ -148,6 +149,31 @@ int GetEventFlagsFromXState(unsigned int state) {
   return flags;
 }
 
+int GetEventFlagsFromXKeyEvent(XEvent* xevent) {
+  DCHECK(xevent->type == KeyPress || xevent->type == KeyRelease);
+
+#if defined(OS_CHROMEOS)
+  const int ime_fabricated_flag = 0;
+#else
+  // XIM fabricates key events for the character compositions by XK_Multi_key.
+  // For example, when a user hits XK_Multi_key, XK_apostrophe, and XK_e in
+  // order to input "é", then XIM generates a key event with keycode=0 and
+  // state=0 for the composition, and the sequence of X11 key events will be
+  // XK_Multi_key, XK_apostrophe, **NoSymbol**, and XK_e.
+  //
+  // We have to send these fabricated key events to XIM so it can correctly
+  // handle the character compositions.
+  const bool fabricated_by_xim =
+      xevent->xkey.keycode == 0 && xevent->xkey.state == 0;
+  const int ime_fabricated_flag =
+      fabricated_by_xim ? ui::EF_IME_FABRICATED_KEY : 0;
+#endif
+
+  return GetEventFlagsFromXState(xevent->xkey.state) |
+      (IsKeypadKey(XLookupKeysym(&xevent->xkey, 0)) ? ui::EF_NUMPAD_KEY : 0) |
+      ime_fabricated_flag;
+}
+
 // Get the event flag for the button in XButtonEvent. During a ButtonPress
 // event, |state| in XButtonEvent does not include the button that has just been
 // pressed. Instead |state| contains flags for the buttons (if any) that had
@@ -328,7 +354,7 @@ int EventFlagsFromNative(const base::NativeEvent& native_event) {
     case KeyPress:
     case KeyRelease: {
       XModifierStateWatcher::GetInstance()->UpdateStateFromEvent(native_event);
-      return GetEventFlagsFromXState(native_event->xkey.state);
+      return GetEventFlagsFromXKeyEvent(native_event);
     }
     case ButtonPress:
     case ButtonRelease: {