// Copyright (c) 2012 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 <Cocoa/Cocoa.h> #include "ui/events/event_constants.h" #include "base/event_types.h" #include "base/logging.h" #include "base/time/time.h" #include "ui/events/event_utils.h" #import "ui/events/keycodes/keyboard_code_conversion_mac.h" #include "ui/gfx/point.h" namespace ui { EventType EventTypeFromNative(const base::NativeEvent& native_event) { NSEventType native_type = [native_event type]; switch (native_type) { case NSLeftMouseDown: case NSRightMouseDown: case NSOtherMouseDown: return ET_MOUSE_PRESSED; case NSLeftMouseUp: case NSRightMouseUp: case NSOtherMouseUp: return ET_MOUSE_RELEASED; case NSMouseMoved: return ET_MOUSE_MOVED; case NSLeftMouseDragged: case NSRightMouseDragged: case NSOtherMouseDragged: return ET_MOUSE_DRAGGED; case NSMouseEntered: return ET_MOUSE_ENTERED; case NSMouseExited: return ET_MOUSE_EXITED; case NSKeyDown: return ET_KEY_PRESSED; case NSKeyUp: return ET_KEY_RELEASED; case NSFlagsChanged: return ET_KEY_PRESSED; case NSScrollWheel: return ET_MOUSEWHEEL; case NSAppKitDefined: case NSSystemDefined: case NSApplicationDefined: case NSPeriodic: case NSCursorUpdate: case NSTabletPoint: case NSTabletProximity: default: return ET_UNKNOWN; } } int EventFlagsFromNative(const base::NativeEvent& native_event) { int event_flags = 0; NSUInteger modifiers = [native_event modifierFlags]; if (modifiers & NSAlphaShiftKeyMask) event_flags = event_flags | EF_CAPS_LOCK_DOWN; if (modifiers & NSShiftKeyMask) event_flags = event_flags | EF_SHIFT_DOWN; if (modifiers & NSControlKeyMask) event_flags = event_flags | EF_CONTROL_DOWN; if (modifiers & NSAlternateKeyMask) event_flags = event_flags | EF_ALT_DOWN; if (modifiers & NSCommandKeyMask) event_flags = event_flags | EF_COMMAND_DOWN; NSEventType type = [native_event type]; if (type == NSLeftMouseDown || type == NSLeftMouseUp || type == NSLeftMouseDragged) { event_flags = event_flags | EF_LEFT_MOUSE_BUTTON; } if (type == NSRightMouseDown || type == NSRightMouseUp || type == NSRightMouseDragged) { event_flags = event_flags | EF_RIGHT_MOUSE_BUTTON; } if (type == NSOtherMouseDown || type == NSOtherMouseUp || type == NSOtherMouseDragged) { event_flags = event_flags | EF_MIDDLE_MOUSE_BUTTON; } return event_flags; } base::TimeDelta EventTimeFromNative(const base::NativeEvent& native_event) { return base::TimeDelta::FromMicroseconds( [native_event timestamp] * 1000000.0f); } gfx::Point EventLocationFromNative(const base::NativeEvent& native_event) { NSWindow* window = [native_event window]; NSPoint location = [native_event locationInWindow]; // Convert |location| to be relative to coordinate system of |contentView|. // Note: this assumes that ui::Event coordinates are rooted in the top-level // view (with flipped coordinates). A more general (but costly) approach // would be to hit-test the view of the event and use the found view's // coordinate system. Currently there is no need for this generality, and // speed is preferred. Flipped views are not suppported. DCHECK([[window contentView] isFlipped] == NO); location = [[window contentView] convertPoint:location fromView:nil]; location.y = [[window contentView] bounds].size.height - location.y; return gfx::Point(NSPointToCGPoint(location)); } gfx::Point EventSystemLocationFromNative( const base::NativeEvent& native_event) { // TODO(port): Needs to always return screen position here. Returning normal // origin for now since that's obviously wrong. return gfx::Point(0, 0); } KeyboardCode KeyboardCodeFromNative(const base::NativeEvent& native_event) { return ui::KeyboardCodeFromNSEvent(native_event); } std::string CodeFromNative(const base::NativeEvent& native_event) { return ui::CodeFromNSEvent(native_event); } bool IsMouseEvent(const base::NativeEvent& native_event) { EventType type = EventTypeFromNative(native_event); return type == ET_MOUSE_PRESSED || type == ET_MOUSE_DRAGGED || type == ET_MOUSE_RELEASED || type == ET_MOUSE_MOVED || type == ET_MOUSE_ENTERED || type == ET_MOUSE_EXITED; } gfx::Vector2d GetMouseWheelOffset(const base::NativeEvent& native_event) { // TODO(dhollowa): Come back to this once comparisons can be made with other // platforms. return gfx::Vector2d([native_event deltaX], [native_event deltaY]); } void ClearTouchIdIfReleased(const base::NativeEvent& xev) { // Touch is currently unsupported. } int GetTouchId(const base::NativeEvent& native_event) { // Touch is currently unsupported. return 0; } float GetTouchRadiusX(const base::NativeEvent& native_event) { // Touch is currently unsupported. return 1.0; } float GetTouchRadiusY(const base::NativeEvent& native_event) { // Touch is currently unsupported. return 1.0; } float GetTouchAngle(const base::NativeEvent& native_event) { // Touch is currently unsupported. return 0.0; } float GetTouchForce(const base::NativeEvent& native_event) { // Touch is currently unsupported. return 0.0; } bool GetScrollOffsets(const base::NativeEvent& native_event, float* x_offset, float* y_offset, int* finger_count) { return false; } bool IsNoopEvent(const base::NativeEvent& event) { return ([event type] == NSApplicationDefined && [event subtype] == 0); } base::NativeEvent CreateNoopEvent() { return [NSEvent otherEventWithType:NSApplicationDefined location:NSZeroPoint modifierFlags:0 timestamp:[NSDate timeIntervalSinceReferenceDate] windowNumber:0 context:nil subtype:0 data1:0 data2:0]; } } // namespace ui