Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1464)

Unified Diff: ui/events/platform/platform_event_builder.cc

Issue 862093002: Split the event library into a cross-platform and native part. Part 1. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Rebase to ToT Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: ui/events/platform/platform_event_builder.cc
diff --git a/ui/events/platform/platform_event_builder.cc b/ui/events/platform/platform_event_builder.cc
new file mode 100644
index 0000000000000000000000000000000000000000..c5460114cbeb142cad7c815ace14dd9a8b79797d
--- /dev/null
+++ b/ui/events/platform/platform_event_builder.cc
@@ -0,0 +1,282 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/events/platform/platform_event_builder.h"
+
+#if defined(USE_X11)
+#include <X11/extensions/XInput2.h>
+#include <X11/Xlib.h>
+#include <X11/keysym.h>
+#endif
+
+#include "ui/events/event.h"
+#include "ui/events/event_utils.h"
+
+namespace ui {
+namespace {
+
+bool X11EventHasNonStandardState(const base::NativeEvent& event) {
+#if defined(USE_X11)
+ const unsigned int kAllStateMask =
+ Button1Mask | Button2Mask | Button3Mask | Button4Mask | Button5Mask |
+ Mod1Mask | Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask | ShiftMask |
+ LockMask | ControlMask | AnyModifier;
+ return event && (event->xkey.state & ~kAllStateMask) != 0;
+#else
+ return false;
+#endif
+}
+
+bool IsX11SendEventTrue(const base::NativeEvent& event) {
+#if defined(USE_X11)
+ return event && event->xany.send_event;
+#else
+ return false;
+#endif
+}
+
+KeyEvent* last_key_event_ = nullptr;
+MouseEvent* last_click_event_ = nullptr;
+
+// We can create a MouseEvent for a native event more than once. We set this
+// to true when the next event either has a different timestamp or we see a
+// release signalling that the press (click) event was completed.
+bool last_click_complete_ = false;
+
+bool IsRepeated(const base::NativeEvent& native_event, const KeyEvent& event) {
+ // A safe guard in case if there were continous key pressed events that are
+ // not auto repeat.
+ const int kMaxAutoRepeatTimeMs = 2000;
+ // Ignore key events that have non standard state masks as it may be
+ // reposted by an IME. IBUS-GTK uses this field to detect the
+ // re-posted event for example. crbug.com/385873.
+ if (X11EventHasNonStandardState(native_event))
+ return false;
+ if (event.is_char())
+ return false;
+ if (event.type() == ui::ET_KEY_RELEASED) {
+ delete last_key_event_;
+ last_key_event_ = NULL;
+ return false;
+ }
+ CHECK_EQ(ui::ET_KEY_PRESSED, event.type());
+ if (!last_key_event_) {
+ last_key_event_ = new KeyEvent(event);
+ return false;
+ }
+ if (event.key_code() == last_key_event_->key_code() &&
+ event.flags() == last_key_event_->flags() &&
+ (event.time_stamp() - last_key_event_->time_stamp()).InMilliseconds() <
+ kMaxAutoRepeatTimeMs) {
+ return true;
+ }
+ delete last_key_event_;
+ last_key_event_ = new KeyEvent(event);
+ return false;
+}
+
+} // namespace
+
+// static
+MouseEvent PlatformEventBuilder::BuildMouseEvent(
+ const base::NativeEvent& native_event) {
+ MouseEvent mouse_event;
+ FillEventFrom(native_event, &mouse_event);
+ FillLocatedEventFrom(native_event, &mouse_event);
+ FillMouseEventFrom(native_event, &mouse_event);
+ return mouse_event;
+}
+
+// static
+MouseWheelEvent PlatformEventBuilder::BuildMouseWheelEvent(
+ const base::NativeEvent& native_event) {
+ MouseWheelEvent mouse_wheel_event;
+ FillEventFrom(native_event, &mouse_wheel_event);
+ FillLocatedEventFrom(native_event, &mouse_wheel_event);
+ FillMouseEventFrom(native_event, &mouse_wheel_event);
+ FillMouseWheelEventFrom(native_event, &mouse_wheel_event);
+ return mouse_wheel_event;
+}
+
+// static
+TouchEvent PlatformEventBuilder::BuildTouchEvent(
+ const base::NativeEvent& native_event) {
+ TouchEvent touch_event;
+ FillEventFrom(native_event, &touch_event);
+ FillLocatedEventFrom(native_event, &touch_event);
+ FillTouchEventFrom(native_event, &touch_event);
+ return touch_event;
+}
+
+// static
+KeyEvent PlatformEventBuilder::BuildKeyEvent(
+ const base::NativeEvent& native_event) {
+ KeyEvent key_event;
+ FillEventFrom(native_event, &key_event);
+ FillKeyEventFrom(native_event, &key_event);
+ return key_event;
+}
+
+// static
+ScrollEvent PlatformEventBuilder::BuildScrollEvent(
+ const base::NativeEvent& native_event) {
+ ScrollEvent scroll_event;
+ FillEventFrom(native_event, &scroll_event);
+ FillLocatedEventFrom(native_event, &scroll_event);
+ FillMouseEventFrom(native_event, &scroll_event);
+ FillScrollEventFrom(native_event, &scroll_event);
+ return scroll_event;
+}
+
+// static
+int PlatformEventBuilder::GetRepeatCount(const base::NativeEvent& native_event,
+ const MouseEvent& event) {
+ int click_count = 1;
+ if (last_click_event_) {
+ if (event.type() == ui::ET_MOUSE_RELEASED) {
+ if (event.changed_button_flags() ==
+ last_click_event_->changed_button_flags()) {
+ last_click_complete_ = true;
+ return last_click_event_->GetClickCount();
+ } else {
+ // If last_click_event_ has changed since this button was pressed
+ // return a click count of 1.
+ return click_count;
+ }
+ }
+ if (event.time_stamp() != last_click_event_->time_stamp())
+ last_click_complete_ = true;
+ if (!last_click_complete_ || IsX11SendEventTrue(native_event)) {
+ click_count = last_click_event_->GetClickCount();
+ } else if (MouseEvent::IsRepeatedClickEvent(*last_click_event_, event)) {
+ click_count = last_click_event_->GetClickCount() + 1;
+ }
+ delete last_click_event_;
+ }
+ last_click_event_ = new MouseEvent(event);
+ last_click_complete_ = false;
+ if (click_count > 3)
+ click_count = 3;
+ last_click_event_->SetClickCount(click_count);
+ return click_count;
+}
+
+// static
+void PlatformEventBuilder::ResetLastClickForTest() {
+ if (last_click_event_) {
+ delete last_click_event_;
+ last_click_event_ = NULL;
+ last_click_complete_ = false;
+ }
+}
+
+// static
+void PlatformEventBuilder::FillEventFrom(const base::NativeEvent& native_event,
+ Event* event) {
+ event->set_type(EventTypeFromNative(native_event));
+ event->set_time_stamp(EventTimeFromNative(native_event));
+ event->set_flags(EventFlagsFromNative(native_event));
+
+#if defined(USE_X11)
+ if (native_event->type == GenericEvent) {
+ XIDeviceEvent* xiev =
+ static_cast<XIDeviceEvent*>(native_event->xcookie.data);
+ event->set_source_device_id(xiev->sourceid);
+ }
+#endif
+}
+
+// static
+void PlatformEventBuilder::FillLocatedEventFrom(
+ const base::NativeEvent& native_event,
+ LocatedEvent* located_event) {
+ gfx::PointF event_location = EventLocationFromNative(native_event);
+ located_event->set_location(event_location);
+ located_event->set_root_location(event_location);
+ located_event->set_screen_location(
+ EventSystemLocationFromNative(native_event));
+}
+
+// static
+void PlatformEventBuilder::FillMouseEventFrom(
+ const base::NativeEvent& native_event,
+ MouseEvent* mouse_event) {
+ mouse_event->set_changed_button_flags(
+ GetChangedMouseButtonFlagsFromNative(native_event));
+
+ if (mouse_event->type() == ET_MOUSE_PRESSED ||
+ mouse_event->type() == ET_MOUSE_RELEASED) {
+ mouse_event->SetClickCount(GetRepeatCount(native_event, *mouse_event));
+ }
+}
+
+// static
+void PlatformEventBuilder::FillMouseWheelEventFrom(
+ const base::NativeEvent& native_event,
+ MouseWheelEvent* mouse_wheel_event) {
+ mouse_wheel_event->set_offset(GetMouseWheelOffset(native_event));
+}
+
+// static
+void PlatformEventBuilder::FillTouchEventFrom(
+ const base::NativeEvent& native_event,
+ TouchEvent* touch_event) {
+ touch_event->set_touch_id(GetTouchId(native_event));
+ touch_event->set_radius_x(GetTouchRadiusX(native_event));
+ touch_event->set_radius_y(GetTouchRadiusY(native_event));
+ touch_event->set_rotation_angle(GetTouchAngle(native_event));
+ touch_event->set_force(GetTouchForce(native_event));
+}
+
+// static
+void PlatformEventBuilder::FillKeyEventFrom(
+ const base::NativeEvent& native_event,
+ KeyEvent* key_event) {
+ key_event->set_key_code(KeyboardCodeFromNative(native_event));
+ key_event->set_code(CodeFromNative(native_event));
+ key_event->set_is_char(IsCharFromNative(native_event));
+ key_event->set_platform_keycode(PlatformKeycodeFromNative(native_event));
+
+ if (IsRepeated(native_event, *key_event))
+ key_event->set_flags(key_event->flags() | ui::EF_IS_REPEAT);
+
+#if defined(USE_X11)
+ key_event->NormalizeFlags();
+#endif
+#if defined(OS_WIN)
+ // Only Windows has native character events.
+ if (key_event->is_char())
+ key_event->set_character(native_event.wParam);
+#endif
+}
+
+// static
+void PlatformEventBuilder::FillScrollEventFrom(
+ const base::NativeEvent& native_event,
+ ScrollEvent* scroll_event) {
+ float x_offset = 0;
+ float y_offset = 0;
+ float x_offset_ordinal = 0;
+ float y_offset_ordinal = 0;
+ int finger_count = 0;
+
+ if (scroll_event->type() == ET_SCROLL) {
+ GetScrollOffsets(native_event, &x_offset, &y_offset, &x_offset_ordinal,
+ &y_offset_ordinal, &finger_count);
+ scroll_event->set_offset(x_offset, y_offset);
+ scroll_event->set_offset_ordinal(x_offset_ordinal, y_offset_ordinal);
+ scroll_event->set_finger_count(finger_count);
+ } else if (scroll_event->type() == ET_SCROLL_FLING_START ||
+ scroll_event->type() == ET_SCROLL_FLING_CANCEL) {
+ GetFlingData(native_event, &x_offset, &y_offset, &x_offset_ordinal,
+ &y_offset_ordinal, NULL);
+ scroll_event->set_offset(x_offset, y_offset);
+ scroll_event->set_offset_ordinal(x_offset_ordinal, y_offset_ordinal);
+ } else {
+ NOTREACHED() << "Unexpected event type " << scroll_event->type()
+ << " when constructing a ScrollEvent.";
+ }
+}
+
+} // namespace ui
« no previous file with comments | « ui/events/platform/platform_event_builder.h ('k') | ui/events/platform/platform_event_builder_x_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698