blob: e5018dfe51fd2f2a19b336ec3239d9ec1e59f6fd [file] [log] [blame]
// 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"
namespace views {
namespace {
ui::EventType EventTypeFromNative(NativeEvent native_event) {
// Add new event types as necessary.
switch (native_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 (native_event->motion.state & GDK_BUTTON1_MASK ||
native_event->motion.state & GDK_BUTTON2_MASK ||
native_event->motion.state & GDK_BUTTON3_MASK ||
native_event->motion.state & GDK_BUTTON4_MASK ||
native_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;
}
GdkEventKey* GetGdkEventKeyFromNative(NativeEvent native_event) {
DCHECK(native_event->type == GDK_KEY_PRESS ||
native_event->type == GDK_KEY_RELEASE);
return &native_event->key;
}
gfx::Point GetMouseEventLocation(NativeEvent native_event) {
double x = 0, y = 0;
if (gdk_event_get_coords(native_event, &x, &y))
return gfx::Point(static_cast<int>(x), static_cast<int>(y));
return gfx::Point();
}
int GetMouseWheelOffset(NativeEvent native_event) {
DCHECK(native_event->type == GDK_SCROLL);
int offset = (native_event->scroll.direction == GDK_SCROLL_UP ||
native_event->scroll.direction == GDK_SCROLL_LEFT) ? 1 : -1;
return MouseWheelEvent::kWheelDelta * offset;
}
unsigned int GetGdkStateFromNative(NativeEvent native_event) {
switch (native_event->type) {
case GDK_KEY_PRESS:
case GDK_KEY_RELEASE:
return native_event->key.state;
case GDK_BUTTON_PRESS:
case GDK_2BUTTON_PRESS:
case GDK_3BUTTON_PRESS:
case GDK_BUTTON_RELEASE:
return native_event->button.state;
case GDK_SCROLL:
return native_event->scroll.state;
case GDK_MOTION_NOTIFY:
return native_event->motion.state;
case GDK_ENTER_NOTIFY:
case GDK_LEAVE_NOTIFY:
return native_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;
}
} // namespace
////////////////////////////////////////////////////////////////////////////////
// Event, public:
// static
int Event::GetFlagsFromGdkEvent(NativeEvent native_event) {
int flags = GetFlagsFromGdkState(GetGdkStateFromNative(native_event));
if (native_event->type == GDK_2BUTTON_PRESS)
flags |= ui::EF_IS_DOUBLE_CLICK;
if (native_event->type == GDK_BUTTON_PRESS ||
native_event->type == GDK_2BUTTON_PRESS ||
native_event->type == GDK_3BUTTON_PRESS ||
native_event->type == GDK_BUTTON_RELEASE) {
switch (native_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;
}
////////////////////////////////////////////////////////////////////////////////
// Event, private:
void Event::Init() {
native_event_ = NULL;
native_event_2_ = NULL;
}
void Event::InitWithNativeEvent(NativeEvent native_event) {
native_event_ = native_event;
// TODO(beng): remove once we rid views of Gtk/Gdk.
native_event_2_ = NULL;
}
////////////////////////////////////////////////////////////////////////////////
// LocatedEvent, protected:
LocatedEvent::LocatedEvent(NativeEvent native_event)
: Event(native_event, EventTypeFromNative(native_event),
GetFlagsFromGdkEvent(native_event)),
location_(GetMouseEventLocation(native_event)) {
}
////////////////////////////////////////////////////////////////////////////////
// MouseEvent, public:
MouseEvent::MouseEvent(NativeEvent native_event)
: LocatedEvent(native_event) {
}
////////////////////////////////////////////////////////////////////////////////
// KeyEvent, public:
KeyEvent::KeyEvent(NativeEvent native_event)
: Event(native_event, EventTypeFromNative(native_event),
GetFlagsFromGdkEvent(native_event)),
key_code_(ui::KeyboardCodeFromGdkEventKey(
GetGdkEventKeyFromNative(native_event))) {
}
////////////////////////////////////////////////////////////////////////////////
// MouseWheelEvent, public:
MouseWheelEvent::MouseWheelEvent(NativeEvent native_event)
: MouseEvent(native_event),
offset_(GetMouseWheelOffset(native_event)) {
}
} // namespace views