1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include <Cocoa/Cocoa.h> 6 7 #include "ui/events/event_constants.h" 8 9 #include "base/event_types.h" 10 #include "base/logging.h" 11 #include "base/time/time.h" 12 #include "ui/events/event_utils.h" 13 #import "ui/events/keycodes/keyboard_code_conversion_mac.h" 14 #include "ui/gfx/point.h" 15 16 namespace ui { 17 18 EventType EventTypeFromNative(const base::NativeEvent& native_event) { 19 NSEventType native_type = [native_event type]; 20 switch (native_type) { 21 case NSLeftMouseDown: 22 case NSRightMouseDown: 23 case NSOtherMouseDown: 24 return ET_MOUSE_PRESSED; 25 26 case NSLeftMouseUp: 27 case NSRightMouseUp: 28 case NSOtherMouseUp: 29 return ET_MOUSE_RELEASED; 30 31 case NSMouseMoved: 32 return ET_MOUSE_MOVED; 33 34 case NSLeftMouseDragged: 35 case NSRightMouseDragged: 36 case NSOtherMouseDragged: 37 return ET_MOUSE_DRAGGED; 38 39 case NSMouseEntered: 40 return ET_MOUSE_ENTERED; 41 42 case NSMouseExited: 43 return ET_MOUSE_EXITED; 44 45 case NSKeyDown: 46 return ET_KEY_PRESSED; 47 48 case NSKeyUp: 49 return ET_KEY_RELEASED; 50 51 case NSFlagsChanged: 52 return ET_KEY_PRESSED; 53 54 case NSScrollWheel: 55 return ET_MOUSEWHEEL; 56 57 case NSAppKitDefined: 58 case NSSystemDefined: 59 case NSApplicationDefined: 60 case NSPeriodic: 61 case NSCursorUpdate: 62 case NSTabletPoint: 63 case NSTabletProximity: 64 default: 65 return ET_UNKNOWN; 66 } 67 } 68 69 int EventFlagsFromNative(const base::NativeEvent& native_event) { 70 int event_flags = 0; 71 NSUInteger modifiers = [native_event modifierFlags]; 72 73 if (modifiers & NSAlphaShiftKeyMask) 74 event_flags = event_flags | EF_CAPS_LOCK_DOWN; 75 76 if (modifiers & NSShiftKeyMask) 77 event_flags = event_flags | EF_SHIFT_DOWN; 78 79 if (modifiers & NSControlKeyMask) 80 event_flags = event_flags | EF_CONTROL_DOWN; 81 82 if (modifiers & NSAlternateKeyMask) 83 event_flags = event_flags | EF_ALT_DOWN; 84 85 if (modifiers & NSCommandKeyMask) 86 event_flags = event_flags | EF_COMMAND_DOWN; 87 88 NSEventType type = [native_event type]; 89 90 if (type == NSLeftMouseDown || 91 type == NSLeftMouseUp || 92 type == NSLeftMouseDragged) { 93 event_flags = event_flags | EF_LEFT_MOUSE_BUTTON; 94 } 95 96 if (type == NSRightMouseDown || 97 type == NSRightMouseUp || 98 type == NSRightMouseDragged) { 99 event_flags = event_flags | EF_RIGHT_MOUSE_BUTTON; 100 } 101 102 if (type == NSOtherMouseDown || 103 type == NSOtherMouseUp || 104 type == NSOtherMouseDragged) { 105 event_flags = event_flags | EF_MIDDLE_MOUSE_BUTTON; 106 } 107 108 return event_flags; 109 } 110 111 base::TimeDelta EventTimeFromNative(const base::NativeEvent& native_event) { 112 return base::TimeDelta::FromMicroseconds( 113 [native_event timestamp] * 1000000.0f); 114 } 115 116 gfx::Point EventLocationFromNative(const base::NativeEvent& native_event) { 117 NSWindow* window = [native_event window]; 118 NSPoint location = [native_event locationInWindow]; 119 120 // Convert |location| to be relative to coordinate system of |contentView|. 121 // Note: this assumes that ui::Event coordinates are rooted in the top-level 122 // view (with flipped coordinates). A more general (but costly) approach 123 // would be to hit-test the view of the event and use the found view's 124 // coordinate system. Currently there is no need for this generality, and 125 // speed is preferred. Flipped views are not suppported. 126 DCHECK([[window contentView] isFlipped] == NO); 127 location = [[window contentView] convertPoint:location fromView:nil]; 128 location.y = [[window contentView] bounds].size.height - location.y; 129 130 return gfx::Point(NSPointToCGPoint(location)); 131 } 132 133 gfx::Point EventSystemLocationFromNative( 134 const base::NativeEvent& native_event) { 135 // TODO(port): Needs to always return screen position here. Returning normal 136 // origin for now since that's obviously wrong. 137 return gfx::Point(0, 0); 138 } 139 140 KeyboardCode KeyboardCodeFromNative(const base::NativeEvent& native_event) { 141 return ui::KeyboardCodeFromNSEvent(native_event); 142 } 143 144 std::string CodeFromNative(const base::NativeEvent& native_event) { 145 return ui::CodeFromNSEvent(native_event); 146 } 147 148 bool IsMouseEvent(const base::NativeEvent& native_event) { 149 EventType type = EventTypeFromNative(native_event); 150 return type == ET_MOUSE_PRESSED || 151 type == ET_MOUSE_DRAGGED || 152 type == ET_MOUSE_RELEASED || 153 type == ET_MOUSE_MOVED || 154 type == ET_MOUSE_ENTERED || 155 type == ET_MOUSE_EXITED; 156 } 157 158 gfx::Vector2d GetMouseWheelOffset(const base::NativeEvent& native_event) { 159 // TODO(dhollowa): Come back to this once comparisons can be made with other 160 // platforms. 161 return gfx::Vector2d([native_event deltaX], [native_event deltaY]); 162 } 163 164 void ClearTouchIdIfReleased(const base::NativeEvent& xev) { 165 // Touch is currently unsupported. 166 } 167 168 int GetTouchId(const base::NativeEvent& native_event) { 169 // Touch is currently unsupported. 170 return 0; 171 } 172 173 float GetTouchRadiusX(const base::NativeEvent& native_event) { 174 // Touch is currently unsupported. 175 return 1.0; 176 } 177 178 float GetTouchRadiusY(const base::NativeEvent& native_event) { 179 // Touch is currently unsupported. 180 return 1.0; 181 } 182 183 float GetTouchAngle(const base::NativeEvent& native_event) { 184 // Touch is currently unsupported. 185 return 0.0; 186 } 187 188 float GetTouchForce(const base::NativeEvent& native_event) { 189 // Touch is currently unsupported. 190 return 0.0; 191 } 192 193 bool GetScrollOffsets(const base::NativeEvent& native_event, 194 float* x_offset, 195 float* y_offset, 196 int* finger_count) { 197 return false; 198 } 199 200 bool IsNoopEvent(const base::NativeEvent& event) { 201 return ([event type] == NSApplicationDefined && [event subtype] == 0); 202 } 203 204 base::NativeEvent CreateNoopEvent() { 205 return [NSEvent otherEventWithType:NSApplicationDefined 206 location:NSZeroPoint 207 modifierFlags:0 208 timestamp:[NSDate timeIntervalSinceReferenceDate] 209 windowNumber:0 210 context:nil 211 subtype:0 212 data1:0 213 data2:0]; 214 } 215 216 } // namespace ui 217