// Copyright (c) 2011 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 "views/events/event.h" #include <gdk/gdk.h> #include "base/logging.h" #include "ui/base/keycodes/keyboard_code_conversion_gtk.h" #include "ui/gfx/point.h" namespace { unsigned int GetGdkStateFromNative(GdkEvent* gdk_event) { switch (gdk_event->type) { case GDK_KEY_PRESS: case GDK_KEY_RELEASE: return gdk_event->key.state; case GDK_BUTTON_PRESS: case GDK_2BUTTON_PRESS: case GDK_3BUTTON_PRESS: case GDK_BUTTON_RELEASE: return gdk_event->button.state; case GDK_SCROLL: return gdk_event->scroll.state; case GDK_MOTION_NOTIFY: return gdk_event->motion.state; case GDK_ENTER_NOTIFY: case GDK_LEAVE_NOTIFY: return gdk_event->crossing.state; default: NOTREACHED(); break; } return 0; } int GetFlagsFromGdkState(unsigned int state) { int flags = 0; flags |= (state & GDK_LOCK_MASK) ? ui::EF_CAPS_LOCK_DOWN : 0; flags |= (state & GDK_CONTROL_MASK) ? ui::EF_CONTROL_DOWN : 0; flags |= (state & GDK_SHIFT_MASK) ? ui::EF_SHIFT_DOWN : 0; flags |= (state & GDK_MOD1_MASK) ? ui::EF_ALT_DOWN : 0; flags |= (state & GDK_BUTTON1_MASK) ? ui::EF_LEFT_BUTTON_DOWN : 0; flags |= (state & GDK_BUTTON2_MASK) ? ui::EF_MIDDLE_BUTTON_DOWN : 0; flags |= (state & GDK_BUTTON3_MASK) ? ui::EF_RIGHT_BUTTON_DOWN : 0; return flags; } //////////////////////////////////////////////////////////////////////////////// // These functions mirror ui/base/events.h, but GTK is in the midst of removal. ui::EventType EventTypeFromNative(GdkEvent* gdk_event) { // Add new event types as necessary. switch (gdk_event->type) { case GDK_2BUTTON_PRESS: case GDK_3BUTTON_PRESS: case GDK_BUTTON_PRESS: return ui::ET_MOUSE_PRESSED; case GDK_BUTTON_RELEASE: return ui::ET_MOUSE_RELEASED; case GDK_DRAG_MOTION: return ui::ET_MOUSE_DRAGGED; case GDK_ENTER_NOTIFY: return ui::ET_MOUSE_ENTERED; case GDK_KEY_PRESS: return ui::ET_KEY_PRESSED; case GDK_KEY_RELEASE: return ui::ET_KEY_RELEASED; case GDK_LEAVE_NOTIFY: return ui::ET_MOUSE_EXITED; case GDK_MOTION_NOTIFY: if (gdk_event->motion.state & GDK_BUTTON1_MASK || gdk_event->motion.state & GDK_BUTTON2_MASK || gdk_event->motion.state & GDK_BUTTON3_MASK || gdk_event->motion.state & GDK_BUTTON4_MASK || gdk_event->motion.state & GDK_BUTTON5_MASK) { return ui::ET_MOUSE_DRAGGED; } return ui::ET_MOUSE_MOVED; case GDK_SCROLL: return ui::ET_MOUSEWHEEL; default: NOTREACHED(); break; } return ui::ET_UNKNOWN; } int EventFlagsFromNative(GdkEvent* gdk_event) { int flags = GetFlagsFromGdkState(GetGdkStateFromNative(gdk_event)); if (gdk_event->type == GDK_2BUTTON_PRESS) flags |= ui::EF_IS_DOUBLE_CLICK; if (gdk_event->type == GDK_BUTTON_PRESS || gdk_event->type == GDK_2BUTTON_PRESS || gdk_event->type == GDK_3BUTTON_PRESS || gdk_event->type == GDK_BUTTON_RELEASE) { switch (gdk_event->button.button) { case 1: return flags | ui::EF_LEFT_BUTTON_DOWN; case 2: return flags | ui::EF_MIDDLE_BUTTON_DOWN; case 3: return flags | ui::EF_RIGHT_BUTTON_DOWN; } } return flags; } gfx::Point EventLocationFromNative(GdkEvent* gdk_event) { double x = 0, y = 0; if (gdk_event_get_coords(gdk_event, &x, &y)) return gfx::Point(static_cast<int>(x), static_cast<int>(y)); return gfx::Point(); } ui::KeyboardCode KeyboardCodeFromNative(GdkEvent* gdk_event) { DCHECK(gdk_event->type == GDK_KEY_PRESS || gdk_event->type == GDK_KEY_RELEASE); return ui::KeyboardCodeFromGdkEventKey(&gdk_event->key); } bool IsMouseEvent(GdkEvent* gdk_event) { return gdk_event->type == GDK_MOTION_NOTIFY || gdk_event->type == GDK_BUTTON_PRESS || gdk_event->type == GDK_2BUTTON_PRESS || gdk_event->type == GDK_3BUTTON_PRESS || gdk_event->type == GDK_BUTTON_RELEASE; } int GetMouseWheelOffset(GdkEvent* gdk_event) { DCHECK(gdk_event->type == GDK_SCROLL); int offset = (gdk_event->scroll.direction == GDK_SCROLL_UP || gdk_event->scroll.direction == GDK_SCROLL_LEFT) ? 1 : -1; return offset; } } // namespace namespace views { //////////////////////////////////////////////////////////////////////////////// // Event, protected: Event::Event(GdkEvent* gdk_event, ui::EventType type, int flags) : native_event_(NULL), gdk_event_(gdk_event), type_(type), time_stamp_(base::Time::NowFromSystemTime()), flags_(flags) { } //////////////////////////////////////////////////////////////////////////////// // LocatedEvent, protected: LocatedEvent::LocatedEvent(GdkEvent* gdk_event) : Event(gdk_event, EventTypeFromNative(gdk_event), EventFlagsFromNative(gdk_event)), location_(EventLocationFromNative(gdk_event)) { } //////////////////////////////////////////////////////////////////////////////// // KeyEvent, public: KeyEvent::KeyEvent(GdkEvent* gdk_event) : Event(gdk_event, EventTypeFromNative(gdk_event), EventFlagsFromNative(gdk_event)), key_code_(KeyboardCodeFromNative(gdk_event)), character_(0), unmodified_character_(0) { } //////////////////////////////////////////////////////////////////////////////// // MouseEvent, public: MouseEvent::MouseEvent(GdkEvent* gdk_event) : LocatedEvent(gdk_event) { } //////////////////////////////////////////////////////////////////////////////// // MouseWheelEvent, public: MouseWheelEvent::MouseWheelEvent(GdkEvent* gdk_event) : MouseEvent(gdk_event), offset_(kWheelDelta * GetMouseWheelOffset(gdk_event)) { } } // namespace views