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/base/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/base/events/event_utils.h" 13 #import "ui/base/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 bool IsMouseEvent(const base::NativeEvent& native_event) { 145 EventType type = EventTypeFromNative(native_event); 146 return type == ET_MOUSE_PRESSED || 147 type == ET_MOUSE_DRAGGED || 148 type == ET_MOUSE_RELEASED || 149 type == ET_MOUSE_MOVED || 150 type == ET_MOUSE_ENTERED || 151 type == ET_MOUSE_EXITED; 152 } 153 154 gfx::Vector2d GetMouseWheelOffset(const base::NativeEvent& native_event) { 155 // TODO(dhollowa): Come back to this once comparisons can be made with other 156 // platforms. 157 return gfx::Vector2d([native_event deltaX], [native_event deltaY]); 158 } 159 160 void ClearTouchIdIfReleased(const base::NativeEvent& xev) { 161 // Touch is currently unsupported. 162 } 163 164 int GetTouchId(const base::NativeEvent& native_event) { 165 // Touch is currently unsupported. 166 return 0; 167 } 168 169 float GetTouchRadiusX(const base::NativeEvent& native_event) { 170 // Touch is currently unsupported. 171 return 1.0; 172 } 173 174 float GetTouchRadiusY(const base::NativeEvent& native_event) { 175 // Touch is currently unsupported. 176 return 1.0; 177 } 178 179 float GetTouchAngle(const base::NativeEvent& native_event) { 180 // Touch is currently unsupported. 181 return 0.0; 182 } 183 184 float GetTouchForce(const base::NativeEvent& native_event) { 185 // Touch is currently unsupported. 186 return 0.0; 187 } 188 189 bool GetScrollOffsets(const base::NativeEvent& native_event, 190 float* x_offset, 191 float* y_offset, 192 int* finger_count) { 193 return false; 194 } 195 196 bool IsNoopEvent(const base::NativeEvent& event) { 197 return ([event type] == NSApplicationDefined && [event subtype] == 0); 198 } 199 200 base::NativeEvent CreateNoopEvent() { 201 return [NSEvent otherEventWithType:NSApplicationDefined 202 location:NSZeroPoint 203 modifierFlags:0 204 timestamp:[NSDate timeIntervalSinceReferenceDate] 205 windowNumber:0 206 context:nil 207 subtype:0 208 data1:0 209 data2:0]; 210 } 211 212 } // namespace ui 213